WebSettings.java revision 0d8b77c2453d0e597f94e39212e4bfeed8affffa
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.webkit; 18 19import android.content.Context; 20import android.os.Build; 21import android.os.Handler; 22import android.os.Message; 23import android.provider.Checkin; 24 25import java.lang.SecurityException; 26import android.content.pm.PackageManager; 27 28import java.util.Locale; 29 30/** 31 * Manages settings state for a WebView. When a WebView is first created, it 32 * obtains a set of default settings. These default settings will be returned 33 * from any getter call. A WebSettings object obtained from 34 * WebView.getSettings() is tied to the life of the WebView. If a WebView has 35 * been destroyed, any method call on WebSettings will throw an 36 * IllegalStateException. 37 */ 38public class WebSettings { 39 /** 40 * Enum for controlling the layout of html. 41 * NORMAL means no rendering changes. 42 * SINGLE_COLUMN moves all content into one column that is the width of the 43 * view. 44 * NARROW_COLUMNS makes all columns no wider than the screen if possible. 45 */ 46 // XXX: These must match LayoutAlgorithm in Settings.h in WebCore. 47 public enum LayoutAlgorithm { 48 NORMAL, 49 SINGLE_COLUMN, 50 NARROW_COLUMNS 51 } 52 53 /** 54 * Enum for specifying the text size. 55 * SMALLEST is 50% 56 * SMALLER is 75% 57 * NORMAL is 100% 58 * LARGER is 150% 59 * LARGEST is 200% 60 */ 61 public enum TextSize { 62 SMALLEST(50), 63 SMALLER(75), 64 NORMAL(100), 65 LARGER(150), 66 LARGEST(200); 67 TextSize(int size) { 68 value = size; 69 } 70 int value; 71 } 72 73 /** 74 * Enum for specifying the WebView's desired density. 75 * FAR makes 100% looking like in 240dpi 76 * MEDIUM makes 100% looking like in 160dpi 77 * CLOSE makes 100% looking like in 120dpi 78 * @hide Pending API council approval 79 */ 80 public enum ZoomDensity { 81 FAR(150), // 240dpi 82 MEDIUM(100), // 160dpi 83 CLOSE(75); // 120dpi 84 ZoomDensity(int size) { 85 value = size; 86 } 87 int value; 88 } 89 90 /** 91 * Default cache usage pattern Use with {@link #setCacheMode}. 92 */ 93 public static final int LOAD_DEFAULT = -1; 94 95 /** 96 * Normal cache usage pattern Use with {@link #setCacheMode}. 97 */ 98 public static final int LOAD_NORMAL = 0; 99 100 /** 101 * Use cache if content is there, even if expired (eg, history nav) 102 * If it is not in the cache, load from network. 103 * Use with {@link #setCacheMode}. 104 */ 105 public static final int LOAD_CACHE_ELSE_NETWORK = 1; 106 107 /** 108 * Don't use the cache, load from network 109 * Use with {@link #setCacheMode}. 110 */ 111 public static final int LOAD_NO_CACHE = 2; 112 113 /** 114 * Don't use the network, load from cache only. 115 * Use with {@link #setCacheMode}. 116 */ 117 public static final int LOAD_CACHE_ONLY = 3; 118 119 public enum RenderPriority { 120 NORMAL, 121 HIGH, 122 LOW 123 } 124 125 // WebView associated with this WebSettings. 126 private WebView mWebView; 127 // BrowserFrame used to access the native frame pointer. 128 private BrowserFrame mBrowserFrame; 129 // Flag to prevent multiple SYNC messages at one time. 130 private boolean mSyncPending = false; 131 // Custom handler that queues messages until the WebCore thread is active. 132 private final EventHandler mEventHandler; 133 // Private settings so we don't have to go into native code to 134 // retrieve the values. After setXXX, postSync() needs to be called. 135 // XXX: The default values need to match those in WebSettings.cpp 136 private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; 137 private Context mContext; 138 private TextSize mTextSize = TextSize.NORMAL; 139 private String mStandardFontFamily = "sans-serif"; 140 private String mFixedFontFamily = "monospace"; 141 private String mSansSerifFontFamily = "sans-serif"; 142 private String mSerifFontFamily = "serif"; 143 private String mCursiveFontFamily = "cursive"; 144 private String mFantasyFontFamily = "fantasy"; 145 private String mDefaultTextEncoding; 146 private String mUserAgent; 147 private boolean mUseDefaultUserAgent; 148 private String mAcceptLanguage; 149 private String mPluginsPath = ""; 150 private int mMinimumFontSize = 8; 151 private int mMinimumLogicalFontSize = 8; 152 private int mDefaultFontSize = 16; 153 private int mDefaultFixedFontSize = 13; 154 private boolean mLoadsImagesAutomatically = true; 155 private boolean mBlockNetworkImage = false; 156 private boolean mBlockNetworkLoads; 157 private boolean mJavaScriptEnabled = false; 158 private boolean mPluginsEnabled = false; 159 private boolean mJavaScriptCanOpenWindowsAutomatically = false; 160 private boolean mUseDoubleTree = false; 161 private boolean mUseWideViewport = false; 162 private boolean mSupportMultipleWindows = false; 163 private boolean mShrinksStandaloneImagesToFit = false; 164 // Don't need to synchronize the get/set methods as they 165 // are basic types, also none of these values are used in 166 // native WebCore code. 167 private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM; 168 private RenderPriority mRenderPriority = RenderPriority.NORMAL; 169 private int mOverrideCacheMode = LOAD_DEFAULT; 170 private boolean mSaveFormData = true; 171 private boolean mSavePassword = true; 172 private boolean mLightTouchEnabled = false; 173 private boolean mNeedInitialFocus = true; 174 private boolean mNavDump = false; 175 private boolean mSupportZoom = true; 176 private boolean mBuiltInZoomControls = false; 177 private boolean mAllowFileAccess = true; 178 179 // Class to handle messages before WebCore is ready. 180 private class EventHandler { 181 // Message id for syncing 182 static final int SYNC = 0; 183 // Message id for setting priority 184 static final int PRIORITY = 1; 185 // Actual WebCore thread handler 186 private Handler mHandler; 187 188 private synchronized void createHandler() { 189 // as mRenderPriority can be set before thread is running, sync up 190 setRenderPriority(); 191 192 // create a new handler 193 mHandler = new Handler() { 194 @Override 195 public void handleMessage(Message msg) { 196 switch (msg.what) { 197 case SYNC: 198 synchronized (WebSettings.this) { 199 if (mBrowserFrame.mNativeFrame != 0) { 200 nativeSync(mBrowserFrame.mNativeFrame); 201 } 202 mSyncPending = false; 203 } 204 break; 205 206 case PRIORITY: { 207 setRenderPriority(); 208 break; 209 } 210 } 211 } 212 }; 213 } 214 215 private void setRenderPriority() { 216 synchronized (WebSettings.this) { 217 if (mRenderPriority == RenderPriority.NORMAL) { 218 android.os.Process.setThreadPriority( 219 android.os.Process.THREAD_PRIORITY_DEFAULT); 220 } else if (mRenderPriority == RenderPriority.HIGH) { 221 android.os.Process.setThreadPriority( 222 android.os.Process.THREAD_PRIORITY_FOREGROUND + 223 android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE); 224 } else if (mRenderPriority == RenderPriority.LOW) { 225 android.os.Process.setThreadPriority( 226 android.os.Process.THREAD_PRIORITY_BACKGROUND); 227 } 228 } 229 } 230 231 /** 232 * Send a message to the private queue or handler. 233 */ 234 private synchronized boolean sendMessage(Message msg) { 235 if (mHandler != null) { 236 mHandler.sendMessage(msg); 237 return true; 238 } else { 239 return false; 240 } 241 } 242 } 243 244 // User agent strings. 245 private static final String DESKTOP_USERAGENT = 246 "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en)" 247 + " AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2" 248 + " Safari/525.20.1"; 249 private static final String IPHONE_USERAGENT = 250 "Mozilla/5.0 (iPhone; U; CPU iPhone 2_1 like Mac OS X; en)" 251 + " AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2" 252 + " Mobile/5F136 Safari/525.20.1"; 253 private static Locale sLocale; 254 private static Object sLockForLocaleSettings; 255 256 /** 257 * Package constructor to prevent clients from creating a new settings 258 * instance. 259 */ 260 WebSettings(Context context, WebView webview) { 261 mEventHandler = new EventHandler(); 262 mContext = context; 263 mWebView = webview; 264 mDefaultTextEncoding = context.getString(com.android.internal. 265 R.string.default_text_encoding); 266 267 if (sLockForLocaleSettings == null) { 268 sLockForLocaleSettings = new Object(); 269 sLocale = Locale.getDefault(); 270 } 271 mAcceptLanguage = getCurrentAcceptLanguage(); 272 mUserAgent = getCurrentUserAgent(); 273 mUseDefaultUserAgent = true; 274 275 mBlockNetworkLoads = mContext.checkPermission( 276 "android.permission.INTERNET", android.os.Process.myPid(), 277 android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED; 278 } 279 280 /** 281 * Looks at sLocale and returns current AcceptLanguage String. 282 * @return Current AcceptLanguage String. 283 */ 284 private String getCurrentAcceptLanguage() { 285 Locale locale; 286 synchronized(sLockForLocaleSettings) { 287 locale = sLocale; 288 } 289 StringBuffer buffer = new StringBuffer(); 290 final String language = locale.getLanguage(); 291 if (language != null) { 292 buffer.append(language); 293 final String country = locale.getCountry(); 294 if (country != null) { 295 buffer.append("-"); 296 buffer.append(country); 297 } 298 } 299 if (!locale.equals(Locale.US)) { 300 buffer.append(", "); 301 java.util.Locale us = Locale.US; 302 if (us.getLanguage() != null) { 303 buffer.append(us.getLanguage()); 304 final String country = us.getCountry(); 305 if (country != null) { 306 buffer.append("-"); 307 buffer.append(country); 308 } 309 } 310 } 311 312 return buffer.toString(); 313 } 314 315 /** 316 * Looks at sLocale and mContext and returns current UserAgent String. 317 * @return Current UserAgent String. 318 */ 319 private synchronized String getCurrentUserAgent() { 320 Locale locale; 321 synchronized(sLockForLocaleSettings) { 322 locale = sLocale; 323 } 324 StringBuffer buffer = new StringBuffer(); 325 // Add version 326 final String version = Build.VERSION.RELEASE; 327 if (version.length() > 0) { 328 buffer.append(version); 329 } else { 330 // default to "1.0" 331 buffer.append("1.0"); 332 } 333 buffer.append("; "); 334 final String language = locale.getLanguage(); 335 if (language != null) { 336 buffer.append(language.toLowerCase()); 337 final String country = locale.getCountry(); 338 if (country != null) { 339 buffer.append("-"); 340 buffer.append(country.toLowerCase()); 341 } 342 } else { 343 // default to "en" 344 buffer.append("en"); 345 } 346 347 final String model = Build.MODEL; 348 if (model.length() > 0) { 349 buffer.append("; "); 350 buffer.append(model); 351 } 352 final String id = Build.ID; 353 if (id.length() > 0) { 354 buffer.append(" Build/"); 355 buffer.append(id); 356 } 357 final String base = mContext.getResources().getText( 358 com.android.internal.R.string.web_user_agent).toString(); 359 return String.format(base, buffer); 360 } 361 362 /** 363 * Enables dumping the pages navigation cache to a text file. 364 */ 365 public void setNavDump(boolean enabled) { 366 mNavDump = enabled; 367 } 368 369 /** 370 * Returns true if dumping the navigation cache is enabled. 371 */ 372 public boolean getNavDump() { 373 return mNavDump; 374 } 375 376 /** 377 * Set whether the WebView supports zoom 378 */ 379 public void setSupportZoom(boolean support) { 380 mSupportZoom = support; 381 } 382 383 /** 384 * Returns whether the WebView supports zoom 385 */ 386 public boolean supportZoom() { 387 return mSupportZoom; 388 } 389 390 /** 391 * Sets whether the zoom mechanism built into WebView is used. 392 */ 393 public void setBuiltInZoomControls(boolean enabled) { 394 mBuiltInZoomControls = enabled; 395 } 396 397 /** 398 * Returns true if the zoom mechanism built into WebView is being used. 399 */ 400 public boolean getBuiltInZoomControls() { 401 return mBuiltInZoomControls; 402 } 403 404 /** 405 * Enable or disable file access within WebView. File access is enabled by 406 * default. 407 */ 408 public void setAllowFileAccess(boolean allow) { 409 mAllowFileAccess = allow; 410 } 411 412 /** 413 * Returns true if this WebView supports file access. 414 */ 415 public boolean getAllowFileAccess() { 416 return mAllowFileAccess; 417 } 418 419 /** 420 * Store whether the WebView is saving form data. 421 */ 422 public void setSaveFormData(boolean save) { 423 mSaveFormData = save; 424 } 425 426 /** 427 * Return whether the WebView is saving form data. 428 */ 429 public boolean getSaveFormData() { 430 return mSaveFormData; 431 } 432 433 /** 434 * Store whether the WebView is saving password. 435 */ 436 public void setSavePassword(boolean save) { 437 mSavePassword = save; 438 } 439 440 /** 441 * Return whether the WebView is saving password. 442 */ 443 public boolean getSavePassword() { 444 return mSavePassword; 445 } 446 447 /** 448 * Set the text size of the page. 449 * @param t A TextSize value for increasing or decreasing the text. 450 * @see WebSettings.TextSize 451 */ 452 public synchronized void setTextSize(TextSize t) { 453 if (WebView.mLogEvent && mTextSize != t ) { 454 Checkin.updateStats(mContext.getContentResolver(), 455 Checkin.Stats.Tag.BROWSER_TEXT_SIZE_CHANGE, 1, 0.0); 456 } 457 mTextSize = t; 458 postSync(); 459 } 460 461 /** 462 * Get the text size of the page. 463 * @return A TextSize enum value describing the text size. 464 * @see WebSettings.TextSize 465 */ 466 public synchronized TextSize getTextSize() { 467 return mTextSize; 468 } 469 470 /** 471 * Set the default zoom density of the page. This should be called from UI 472 * thread. 473 * @param zoom A ZoomDensity value 474 * @see WebSettings.ZoomDensity 475 * @hide Pending API council approval 476 */ 477 public void setDefaultZoom(ZoomDensity zoom) { 478 if (mDefaultZoom != zoom) { 479 mDefaultZoom = zoom; 480 mWebView.updateDefaultZoomDensity(zoom.value); 481 } 482 } 483 484 /** 485 * Get the default zoom density of the page. This should be called from UI 486 * thread. 487 * @return A ZoomDensity value 488 * @see WebSettings.ZoomDensity 489 * @hide Pending API council approval 490 */ 491 public ZoomDensity getDefaultZoom() { 492 return mDefaultZoom; 493 } 494 495 /** 496 * Enables using light touches to make a selection and activate mouseovers. 497 */ 498 public void setLightTouchEnabled(boolean enabled) { 499 mLightTouchEnabled = enabled; 500 } 501 502 /** 503 * Returns true if light touches are enabled. 504 */ 505 public boolean getLightTouchEnabled() { 506 return mLightTouchEnabled; 507 } 508 509 /** 510 * Tell the WebView to use the double tree rendering algorithm. 511 * @param use True if the WebView is to use double tree rendering, false 512 * otherwise. 513 */ 514 public synchronized void setUseDoubleTree(boolean use) { 515 if (mUseDoubleTree != use) { 516 mUseDoubleTree = use; 517 postSync(); 518 } 519 } 520 521 /** 522 * Return true if the WebView is using the double tree rendering algorithm. 523 * @return True if the WebView is using the double tree rendering 524 * algorithm. 525 */ 526 public synchronized boolean getUseDoubleTree() { 527 return mUseDoubleTree; 528 } 529 530 /** 531 * Tell the WebView about user-agent string. 532 * @param ua 0 if the WebView should use an Android user-agent string, 533 * 1 if the WebView should use a desktop user-agent string. 534 * 535 * @deprecated Please use setUserAgentString instead. 536 */ 537 @Deprecated 538 public synchronized void setUserAgent(int ua) { 539 String uaString = null; 540 if (ua == 1) { 541 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 542 return; // do nothing 543 } else { 544 uaString = DESKTOP_USERAGENT; 545 } 546 } else if (ua == 2) { 547 if (IPHONE_USERAGENT.equals(mUserAgent)) { 548 return; // do nothing 549 } else { 550 uaString = IPHONE_USERAGENT; 551 } 552 } else if (ua != 0) { 553 return; // do nothing 554 } 555 setUserAgentString(uaString); 556 } 557 558 /** 559 * Return user-agent as int 560 * @return int 0 if the WebView is using an Android user-agent string. 561 * 1 if the WebView is using a desktop user-agent string. 562 * -1 if the WebView is using user defined user-agent string. 563 * 564 * @deprecated Please use getUserAgentString instead. 565 */ 566 @Deprecated 567 public synchronized int getUserAgent() { 568 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 569 return 1; 570 } else if (IPHONE_USERAGENT.equals(mUserAgent)) { 571 return 2; 572 } else if (mUseDefaultUserAgent) { 573 return 0; 574 } 575 return -1; 576 } 577 578 /** 579 * Tell the WebView to use the wide viewport 580 */ 581 public synchronized void setUseWideViewPort(boolean use) { 582 if (mUseWideViewport != use) { 583 mUseWideViewport = use; 584 postSync(); 585 } 586 } 587 588 /** 589 * @return True if the WebView is using a wide viewport 590 */ 591 public synchronized boolean getUseWideViewPort() { 592 return mUseWideViewport; 593 } 594 595 /** 596 * Tell the WebView whether it supports multiple windows. TRUE means 597 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 598 * boolean, Message)} is implemented by the host application. 599 */ 600 public synchronized void setSupportMultipleWindows(boolean support) { 601 if (mSupportMultipleWindows != support) { 602 mSupportMultipleWindows = support; 603 postSync(); 604 } 605 } 606 607 /** 608 * @return True if the WebView is supporting multiple windows. This means 609 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 610 * boolean, Message)} is implemented by the host application. 611 */ 612 public synchronized boolean supportMultipleWindows() { 613 return mSupportMultipleWindows; 614 } 615 616 /** 617 * Set the underlying layout algorithm. This will cause a relayout of the 618 * WebView. 619 * @param l A LayoutAlgorithm enum specifying the algorithm to use. 620 * @see WebSettings.LayoutAlgorithm 621 */ 622 public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) { 623 // XXX: This will only be affective if libwebcore was built with 624 // ANDROID_LAYOUT defined. 625 if (mLayoutAlgorithm != l) { 626 mLayoutAlgorithm = l; 627 postSync(); 628 } 629 } 630 631 /** 632 * Return the current layout algorithm. 633 * @return LayoutAlgorithm enum value describing the layout algorithm 634 * being used. 635 * @see WebSettings.LayoutAlgorithm 636 */ 637 public synchronized LayoutAlgorithm getLayoutAlgorithm() { 638 return mLayoutAlgorithm; 639 } 640 641 /** 642 * Set the standard font family name. 643 * @param font A font family name. 644 */ 645 public synchronized void setStandardFontFamily(String font) { 646 if (font != null && !font.equals(mStandardFontFamily)) { 647 mStandardFontFamily = font; 648 postSync(); 649 } 650 } 651 652 /** 653 * Get the standard font family name. 654 * @return The standard font family name as a string. 655 */ 656 public synchronized String getStandardFontFamily() { 657 return mStandardFontFamily; 658 } 659 660 /** 661 * Set the fixed font family name. 662 * @param font A font family name. 663 */ 664 public synchronized void setFixedFontFamily(String font) { 665 if (font != null && !font.equals(mFixedFontFamily)) { 666 mFixedFontFamily = font; 667 postSync(); 668 } 669 } 670 671 /** 672 * Get the fixed font family name. 673 * @return The fixed font family name as a string. 674 */ 675 public synchronized String getFixedFontFamily() { 676 return mFixedFontFamily; 677 } 678 679 /** 680 * Set the sans-serif font family name. 681 * @param font A font family name. 682 */ 683 public synchronized void setSansSerifFontFamily(String font) { 684 if (font != null && !font.equals(mSansSerifFontFamily)) { 685 mSansSerifFontFamily = font; 686 postSync(); 687 } 688 } 689 690 /** 691 * Get the sans-serif font family name. 692 * @return The sans-serif font family name as a string. 693 */ 694 public synchronized String getSansSerifFontFamily() { 695 return mSansSerifFontFamily; 696 } 697 698 /** 699 * Set the serif font family name. 700 * @param font A font family name. 701 */ 702 public synchronized void setSerifFontFamily(String font) { 703 if (font != null && !font.equals(mSerifFontFamily)) { 704 mSerifFontFamily = font; 705 postSync(); 706 } 707 } 708 709 /** 710 * Get the serif font family name. 711 * @return The serif font family name as a string. 712 */ 713 public synchronized String getSerifFontFamily() { 714 return mSerifFontFamily; 715 } 716 717 /** 718 * Set the cursive font family name. 719 * @param font A font family name. 720 */ 721 public synchronized void setCursiveFontFamily(String font) { 722 if (font != null && !font.equals(mCursiveFontFamily)) { 723 mCursiveFontFamily = font; 724 postSync(); 725 } 726 } 727 728 /** 729 * Get the cursive font family name. 730 * @return The cursive font family name as a string. 731 */ 732 public synchronized String getCursiveFontFamily() { 733 return mCursiveFontFamily; 734 } 735 736 /** 737 * Set the fantasy font family name. 738 * @param font A font family name. 739 */ 740 public synchronized void setFantasyFontFamily(String font) { 741 if (font != null && !font.equals(mFantasyFontFamily)) { 742 mFantasyFontFamily = font; 743 postSync(); 744 } 745 } 746 747 /** 748 * Get the fantasy font family name. 749 * @return The fantasy font family name as a string. 750 */ 751 public synchronized String getFantasyFontFamily() { 752 return mFantasyFontFamily; 753 } 754 755 /** 756 * Set the minimum font size. 757 * @param size A non-negative integer between 1 and 72. 758 * Any number outside the specified range will be pinned. 759 */ 760 public synchronized void setMinimumFontSize(int size) { 761 size = pin(size); 762 if (mMinimumFontSize != size) { 763 mMinimumFontSize = size; 764 postSync(); 765 } 766 } 767 768 /** 769 * Get the minimum font size. 770 * @return A non-negative integer between 1 and 72. 771 */ 772 public synchronized int getMinimumFontSize() { 773 return mMinimumFontSize; 774 } 775 776 /** 777 * Set the minimum logical font size. 778 * @param size A non-negative integer between 1 and 72. 779 * Any number outside the specified range will be pinned. 780 */ 781 public synchronized void setMinimumLogicalFontSize(int size) { 782 size = pin(size); 783 if (mMinimumLogicalFontSize != size) { 784 mMinimumLogicalFontSize = size; 785 postSync(); 786 } 787 } 788 789 /** 790 * Get the minimum logical font size. 791 * @return A non-negative integer between 1 and 72. 792 */ 793 public synchronized int getMinimumLogicalFontSize() { 794 return mMinimumLogicalFontSize; 795 } 796 797 /** 798 * Set the default font size. 799 * @param size A non-negative integer between 1 and 72. 800 * Any number outside the specified range will be pinned. 801 */ 802 public synchronized void setDefaultFontSize(int size) { 803 size = pin(size); 804 if (mDefaultFontSize != size) { 805 mDefaultFontSize = size; 806 postSync(); 807 } 808 } 809 810 /** 811 * Get the default font size. 812 * @return A non-negative integer between 1 and 72. 813 */ 814 public synchronized int getDefaultFontSize() { 815 return mDefaultFontSize; 816 } 817 818 /** 819 * Set the default fixed font size. 820 * @param size A non-negative integer between 1 and 72. 821 * Any number outside the specified range will be pinned. 822 */ 823 public synchronized void setDefaultFixedFontSize(int size) { 824 size = pin(size); 825 if (mDefaultFixedFontSize != size) { 826 mDefaultFixedFontSize = size; 827 postSync(); 828 } 829 } 830 831 /** 832 * Get the default fixed font size. 833 * @return A non-negative integer between 1 and 72. 834 */ 835 public synchronized int getDefaultFixedFontSize() { 836 return mDefaultFixedFontSize; 837 } 838 839 /** 840 * Tell the WebView to load image resources automatically. 841 * @param flag True if the WebView should load images automatically. 842 */ 843 public synchronized void setLoadsImagesAutomatically(boolean flag) { 844 if (mLoadsImagesAutomatically != flag) { 845 mLoadsImagesAutomatically = flag; 846 postSync(); 847 } 848 } 849 850 /** 851 * Return true if the WebView will load image resources automatically. 852 * @return True if the WebView loads images automatically. 853 */ 854 public synchronized boolean getLoadsImagesAutomatically() { 855 return mLoadsImagesAutomatically; 856 } 857 858 /** 859 * Tell the WebView to block network image. This is only checked when 860 * getLoadsImagesAutomatically() is true. 861 * @param flag True if the WebView should block network image 862 */ 863 public synchronized void setBlockNetworkImage(boolean flag) { 864 if (mBlockNetworkImage != flag) { 865 mBlockNetworkImage = flag; 866 postSync(); 867 } 868 } 869 870 /** 871 * Return true if the WebView will block network image. 872 * @return True if the WebView blocks network image. 873 */ 874 public synchronized boolean getBlockNetworkImage() { 875 return mBlockNetworkImage; 876 } 877 878 /** 879 * @hide 880 * Tell the WebView to block all network load requests. 881 * @param flag True if the WebView should block all network loads 882 */ 883 public synchronized void setBlockNetworkLoads(boolean flag) { 884 if (mBlockNetworkLoads != flag) { 885 mBlockNetworkLoads = flag; 886 verifyNetworkAccess(); 887 } 888 } 889 890 /** 891 * @hide 892 * Return true if the WebView will block all network loads. 893 * @return True if the WebView blocks all network loads. 894 */ 895 public synchronized boolean getBlockNetworkLoads() { 896 return mBlockNetworkLoads; 897 } 898 899 900 private void verifyNetworkAccess() { 901 if (!mBlockNetworkLoads) { 902 if (mContext.checkPermission("android.permission.INTERNET", 903 android.os.Process.myPid(), android.os.Process.myUid()) != 904 PackageManager.PERMISSION_GRANTED) { 905 throw new SecurityException 906 ("Permission denied - " + 907 "application missing INTERNET permission"); 908 } 909 } 910 } 911 912 /** 913 * Tell the WebView to enable javascript execution. 914 * @param flag True if the WebView should execute javascript. 915 */ 916 public synchronized void setJavaScriptEnabled(boolean flag) { 917 if (mJavaScriptEnabled != flag) { 918 mJavaScriptEnabled = flag; 919 postSync(); 920 } 921 } 922 923 /** 924 * Tell the WebView to enable plugins. 925 * @param flag True if the WebView should load plugins. 926 */ 927 public synchronized void setPluginsEnabled(boolean flag) { 928 if (mPluginsEnabled != flag) { 929 mPluginsEnabled = flag; 930 postSync(); 931 } 932 } 933 934 /** 935 * Set a custom path to plugins used by the WebView. The client 936 * must ensure it exists before this call. 937 * @param pluginsPath String path to the directory containing plugins. 938 */ 939 public synchronized void setPluginsPath(String pluginsPath) { 940 if (pluginsPath != null && !pluginsPath.equals(mPluginsPath)) { 941 mPluginsPath = pluginsPath; 942 postSync(); 943 } 944 } 945 946 /** 947 * Return true if javascript is enabled. 948 * @return True if javascript is enabled. 949 */ 950 public synchronized boolean getJavaScriptEnabled() { 951 return mJavaScriptEnabled; 952 } 953 954 /** 955 * Return true if plugins are enabled. 956 * @return True if plugins are enabled. 957 */ 958 public synchronized boolean getPluginsEnabled() { 959 return mPluginsEnabled; 960 } 961 962 /** 963 * Return the current path used for plugins in the WebView. 964 * @return The string path to the WebView plugins. 965 */ 966 public synchronized String getPluginsPath() { 967 return mPluginsPath; 968 } 969 970 /** 971 * Tell javascript to open windows automatically. This applies to the 972 * javascript function window.open(). 973 * @param flag True if javascript can open windows automatically. 974 */ 975 public synchronized void setJavaScriptCanOpenWindowsAutomatically( 976 boolean flag) { 977 if (mJavaScriptCanOpenWindowsAutomatically != flag) { 978 mJavaScriptCanOpenWindowsAutomatically = flag; 979 postSync(); 980 } 981 } 982 983 /** 984 * Return true if javascript can open windows automatically. 985 * @return True if javascript can open windows automatically during 986 * window.open(). 987 */ 988 public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() { 989 return mJavaScriptCanOpenWindowsAutomatically; 990 } 991 992 /** 993 * Set the default text encoding name to use when decoding html pages. 994 * @param encoding The text encoding name. 995 */ 996 public synchronized void setDefaultTextEncodingName(String encoding) { 997 if (encoding != null && !encoding.equals(mDefaultTextEncoding)) { 998 mDefaultTextEncoding = encoding; 999 postSync(); 1000 } 1001 } 1002 1003 /** 1004 * Get the default text encoding name. 1005 * @return The default text encoding name as a string. 1006 */ 1007 public synchronized String getDefaultTextEncodingName() { 1008 return mDefaultTextEncoding; 1009 } 1010 1011 /** 1012 * Set the WebView's user-agent string. If the string "ua" is null or empty, 1013 * it will use the system default user-agent string. 1014 */ 1015 public synchronized void setUserAgentString(String ua) { 1016 if (ua == null || ua.length() == 0) { 1017 synchronized(sLockForLocaleSettings) { 1018 Locale currentLocale = Locale.getDefault(); 1019 if (!sLocale.equals(currentLocale)) { 1020 sLocale = currentLocale; 1021 mAcceptLanguage = getCurrentAcceptLanguage(); 1022 } 1023 } 1024 ua = getCurrentUserAgent(); 1025 mUseDefaultUserAgent = true; 1026 } else { 1027 mUseDefaultUserAgent = false; 1028 } 1029 1030 if (!ua.equals(mUserAgent)) { 1031 mUserAgent = ua; 1032 postSync(); 1033 } 1034 } 1035 1036 /** 1037 * Return the WebView's user-agent string. 1038 */ 1039 public synchronized String getUserAgentString() { 1040 if (DESKTOP_USERAGENT.equals(mUserAgent) || 1041 IPHONE_USERAGENT.equals(mUserAgent) || 1042 !mUseDefaultUserAgent) { 1043 return mUserAgent; 1044 } 1045 1046 boolean doPostSync = false; 1047 synchronized(sLockForLocaleSettings) { 1048 Locale currentLocale = Locale.getDefault(); 1049 if (!sLocale.equals(currentLocale)) { 1050 sLocale = currentLocale; 1051 mUserAgent = getCurrentUserAgent(); 1052 mAcceptLanguage = getCurrentAcceptLanguage(); 1053 doPostSync = true; 1054 } 1055 } 1056 if (doPostSync) { 1057 postSync(); 1058 } 1059 return mUserAgent; 1060 } 1061 1062 /* package api to grab the Accept Language string. */ 1063 /*package*/ synchronized String getAcceptLanguage() { 1064 synchronized(sLockForLocaleSettings) { 1065 Locale currentLocale = Locale.getDefault(); 1066 if (!sLocale.equals(currentLocale)) { 1067 sLocale = currentLocale; 1068 mAcceptLanguage = getCurrentAcceptLanguage(); 1069 } 1070 } 1071 return mAcceptLanguage; 1072 } 1073 1074 /** 1075 * Tell the WebView whether it needs to set a node to have focus when 1076 * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. 1077 * 1078 * @param flag 1079 */ 1080 public void setNeedInitialFocus(boolean flag) { 1081 if (mNeedInitialFocus != flag) { 1082 mNeedInitialFocus = flag; 1083 } 1084 } 1085 1086 /* Package api to get the choice whether it needs to set initial focus. */ 1087 /* package */ boolean getNeedInitialFocus() { 1088 return mNeedInitialFocus; 1089 } 1090 1091 /** 1092 * Set the priority of the Render thread. Unlike the other settings, this 1093 * one only needs to be called once per process. 1094 * 1095 * @param priority RenderPriority, can be normal, high or low. 1096 */ 1097 public synchronized void setRenderPriority(RenderPriority priority) { 1098 if (mRenderPriority != priority) { 1099 mRenderPriority = priority; 1100 mEventHandler.sendMessage(Message.obtain(null, 1101 EventHandler.PRIORITY)); 1102 } 1103 } 1104 1105 /** 1106 * Override the way the cache is used. The way the cache is used is based 1107 * on the navigation option. For a normal page load, the cache is checked 1108 * and content is re-validated as needed. When navigating back, content is 1109 * not revalidated, instead the content is just pulled from the cache. 1110 * This function allows the client to override this behavior. 1111 * @param mode One of the LOAD_ values. 1112 */ 1113 public void setCacheMode(int mode) { 1114 if (mode != mOverrideCacheMode) { 1115 mOverrideCacheMode = mode; 1116 } 1117 } 1118 1119 /** 1120 * Return the current setting for overriding the cache mode. For a full 1121 * description, see the {@link #setCacheMode(int)} function. 1122 */ 1123 public int getCacheMode() { 1124 return mOverrideCacheMode; 1125 } 1126 1127 /** 1128 * If set, webkit alternately shrinks and expands images viewed outside 1129 * of an HTML page to fit the screen. This conflicts with attempts by 1130 * the UI to zoom in and out of an image, so it is set false by default. 1131 * @param shrink Set true to let webkit shrink the standalone image to fit. 1132 * {@hide} 1133 */ 1134 public void setShrinksStandaloneImagesToFit(boolean shrink) { 1135 if (mShrinksStandaloneImagesToFit != shrink) { 1136 mShrinksStandaloneImagesToFit = shrink; 1137 postSync(); 1138 } 1139 } 1140 1141 /** 1142 * Transfer messages from the queue to the new WebCoreThread. Called from 1143 * WebCore thread. 1144 */ 1145 /*package*/ 1146 synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) { 1147 mBrowserFrame = frame; 1148 if (WebView.DEBUG) { 1149 junit.framework.Assert.assertTrue(frame.mNativeFrame != 0); 1150 } 1151 nativeSync(frame.mNativeFrame); 1152 mSyncPending = false; 1153 mEventHandler.createHandler(); 1154 } 1155 1156 private int pin(int size) { 1157 // FIXME: 72 is just an arbitrary max text size value. 1158 if (size < 1) { 1159 return 1; 1160 } else if (size > 72) { 1161 return 72; 1162 } 1163 return size; 1164 } 1165 1166 /* Post a SYNC message to handle syncing the native settings. */ 1167 private synchronized void postSync() { 1168 // Only post if a sync is not pending 1169 if (!mSyncPending) { 1170 mSyncPending = mEventHandler.sendMessage( 1171 Message.obtain(null, EventHandler.SYNC)); 1172 } 1173 } 1174 1175 // Synchronize the native and java settings. 1176 private native void nativeSync(int nativeFrame); 1177} 1178