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