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