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