1 /* 2 * Copyright (C) 2012 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.provider.Settings; 26 import android.provider.Settings.SettingNotFoundException; 27 import android.util.EventLog; 28 29 import java.util.Locale; 30 31 /** 32 * WebSettings implementation for the WebViewClassic implementation of WebView. 33 * @hide 34 */ 35 public class WebSettingsClassic extends WebSettings { 36 // TODO: Keep this up to date 37 private static final String PREVIOUS_VERSION = "4.0.4"; 38 39 // WebView associated with this WebSettings. 40 private WebViewClassic mWebView; 41 // BrowserFrame used to access the native frame pointer. 42 private BrowserFrame mBrowserFrame; 43 // Flag to prevent multiple SYNC messages at one time. 44 private boolean mSyncPending = false; 45 // Custom handler that queues messages until the WebCore thread is active. 46 private final EventHandler mEventHandler; 47 48 // Private settings so we don't have to go into native code to 49 // retrieve the values. After setXXX, postSync() needs to be called. 50 // 51 // The default values need to match those in WebSettings.cpp 52 // If the defaults change, please also update the JavaDocs so developers 53 // know what they are. 54 private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; 55 private Context mContext; 56 private int mTextSize = 100; 57 private String mStandardFontFamily = "sans-serif"; 58 private String mFixedFontFamily = "monospace"; 59 private String mSansSerifFontFamily = "sans-serif"; 60 private String mSerifFontFamily = "serif"; 61 private String mCursiveFontFamily = "cursive"; 62 private String mFantasyFontFamily = "fantasy"; 63 private String mDefaultTextEncoding; 64 private String mUserAgent; 65 private boolean mUseDefaultUserAgent; 66 private String mAcceptLanguage; 67 private int mMinimumFontSize = 8; 68 private int mMinimumLogicalFontSize = 8; 69 private int mDefaultFontSize = 16; 70 private int mDefaultFixedFontSize = 13; 71 private int mPageCacheCapacity = 0; 72 private boolean mLoadsImagesAutomatically = true; 73 private boolean mBlockNetworkImage = false; 74 private boolean mBlockNetworkLoads; 75 private boolean mJavaScriptEnabled = false; 76 private boolean mAllowUniversalAccessFromFileURLs = false; 77 private boolean mAllowFileAccessFromFileURLs = false; 78 private boolean mHardwareAccelSkia = false; 79 private boolean mShowVisualIndicator = false; 80 private PluginState mPluginState = PluginState.OFF; 81 private boolean mJavaScriptCanOpenWindowsAutomatically = false; 82 private boolean mUseDoubleTree = false; 83 private boolean mUseWideViewport = false; 84 private boolean mSupportMultipleWindows = false; 85 private boolean mShrinksStandaloneImagesToFit = false; 86 private long mMaximumDecodedImageSize = 0; // 0 means default 87 private boolean mPrivateBrowsingEnabled = false; 88 private boolean mSyntheticLinksEnabled = true; 89 // HTML5 API flags 90 private boolean mAppCacheEnabled = false; 91 private boolean mDatabaseEnabled = false; 92 private boolean mDomStorageEnabled = false; 93 private boolean mWorkersEnabled = false; // only affects V8. 94 private boolean mGeolocationEnabled = true; 95 private boolean mXSSAuditorEnabled = false; 96 private boolean mLinkPrefetchEnabled = false; 97 // HTML5 configuration parameters 98 private long mAppCacheMaxSize = Long.MAX_VALUE; 99 private String mAppCachePath = null; 100 private String mDatabasePath = ""; 101 // The WebCore DatabaseTracker only allows the database path to be set 102 // once. Keep track of when the path has been set. 103 private boolean mDatabasePathHasBeenSet = false; 104 private String mGeolocationDatabasePath = ""; 105 // Don't need to synchronize the get/set methods as they 106 // are basic types, also none of these values are used in 107 // native WebCore code. 108 private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM; 109 private RenderPriority mRenderPriority = RenderPriority.NORMAL; 110 private int mOverrideCacheMode = LOAD_DEFAULT; 111 private int mDoubleTapZoom = 100; 112 private boolean mSaveFormData = true; 113 private boolean mAutoFillEnabled = false; 114 private boolean mSavePassword = true; 115 private boolean mLightTouchEnabled = false; 116 private boolean mNeedInitialFocus = true; 117 private boolean mNavDump = false; 118 private boolean mSupportZoom = true; 119 private boolean mBuiltInZoomControls = false; 120 private boolean mDisplayZoomControls = true; 121 private boolean mAllowFileAccess = true; 122 private boolean mAllowContentAccess = true; 123 private boolean mLoadWithOverviewMode = false; 124 private boolean mEnableSmoothTransition = false; 125 private boolean mForceUserScalable = false; 126 private boolean mPasswordEchoEnabled = true; 127 128 // AutoFill Profile data 129 public static class AutoFillProfile { 130 private int mUniqueId; 131 private String mFullName; 132 private String mEmailAddress; 133 private String mCompanyName; 134 private String mAddressLine1; 135 private String mAddressLine2; 136 private String mCity; 137 private String mState; 138 private String mZipCode; 139 private String mCountry; 140 private String mPhoneNumber; 141 142 public AutoFillProfile(int uniqueId, String fullName, String email, 143 String companyName, String addressLine1, String addressLine2, 144 String city, String state, String zipCode, String country, 145 String phoneNumber) { 146 mUniqueId = uniqueId; 147 mFullName = fullName; 148 mEmailAddress = email; 149 mCompanyName = companyName; 150 mAddressLine1 = addressLine1; 151 mAddressLine2 = addressLine2; 152 mCity = city; 153 mState = state; 154 mZipCode = zipCode; 155 mCountry = country; 156 mPhoneNumber = phoneNumber; 157 } 158 159 public int getUniqueId() { return mUniqueId; } 160 public String getFullName() { return mFullName; } 161 public String getEmailAddress() { return mEmailAddress; } 162 public String getCompanyName() { return mCompanyName; } 163 public String getAddressLine1() { return mAddressLine1; } 164 public String getAddressLine2() { return mAddressLine2; } 165 public String getCity() { return mCity; } 166 public String getState() { return mState; } 167 public String getZipCode() { return mZipCode; } 168 public String getCountry() { return mCountry; } 169 public String getPhoneNumber() { return mPhoneNumber; } 170 } 171 172 173 private AutoFillProfile mAutoFillProfile; 174 175 private boolean mUseWebViewBackgroundForOverscroll = true; 176 177 // private WebSettings, not accessible by the host activity 178 static private int mDoubleTapToastCount = 3; 179 180 private static final String PREF_FILE = "WebViewSettings"; 181 private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count"; 182 183 // Class to handle messages before WebCore is ready. 184 private class EventHandler { 185 // Message id for syncing 186 static final int SYNC = 0; 187 // Message id for setting priority 188 static final int PRIORITY = 1; 189 // Message id for writing double-tap toast count 190 static final int SET_DOUBLE_TAP_TOAST_COUNT = 2; 191 // Actual WebCore thread handler 192 private Handler mHandler; 193 194 private synchronized void createHandler() { 195 // as mRenderPriority can be set before thread is running, sync up 196 setRenderPriority(); 197 198 // create a new handler 199 mHandler = new Handler() { 200 @Override 201 public void handleMessage(Message msg) { 202 switch (msg.what) { 203 case SYNC: 204 synchronized (WebSettingsClassic.this) { 205 if (mBrowserFrame.mNativeFrame != 0) { 206 nativeSync(mBrowserFrame.mNativeFrame); 207 } 208 mSyncPending = false; 209 } 210 break; 211 212 case PRIORITY: { 213 setRenderPriority(); 214 break; 215 } 216 217 case SET_DOUBLE_TAP_TOAST_COUNT: { 218 SharedPreferences.Editor editor = mContext 219 .getSharedPreferences(PREF_FILE, 220 Context.MODE_PRIVATE).edit(); 221 editor.putInt(DOUBLE_TAP_TOAST_COUNT, 222 mDoubleTapToastCount); 223 editor.commit(); 224 break; 225 } 226 } 227 } 228 }; 229 } 230 231 private void setRenderPriority() { 232 synchronized (WebSettingsClassic.this) { 233 if (mRenderPriority == RenderPriority.NORMAL) { 234 android.os.Process.setThreadPriority( 235 android.os.Process.THREAD_PRIORITY_DEFAULT); 236 } else if (mRenderPriority == RenderPriority.HIGH) { 237 android.os.Process.setThreadPriority( 238 android.os.Process.THREAD_PRIORITY_FOREGROUND + 239 android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE); 240 } else if (mRenderPriority == RenderPriority.LOW) { 241 android.os.Process.setThreadPriority( 242 android.os.Process.THREAD_PRIORITY_BACKGROUND); 243 } 244 } 245 } 246 247 /** 248 * Send a message to the private queue or handler. 249 */ 250 private synchronized boolean sendMessage(Message msg) { 251 if (mHandler != null) { 252 mHandler.sendMessage(msg); 253 return true; 254 } else { 255 return false; 256 } 257 } 258 } 259 260 // User agent strings. 261 private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " + 262 "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " + 263 "Chrome/11.0.696.34 Safari/534.24"; 264 private static final String IPHONE_USERAGENT = 265 "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)" 266 + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0" 267 + " Mobile/7A341 Safari/528.16"; 268 private static Locale sLocale; 269 private static Object sLockForLocaleSettings; 270 271 /** 272 * Package constructor to prevent clients from creating a new settings 273 * instance. 274 */ 275 WebSettingsClassic(Context context, WebViewClassic webview) { 276 mEventHandler = new EventHandler(); 277 mContext = context; 278 mWebView = webview; 279 mDefaultTextEncoding = context.getString(com.android.internal. 280 R.string.default_text_encoding); 281 282 if (sLockForLocaleSettings == null) { 283 sLockForLocaleSettings = new Object(); 284 sLocale = Locale.getDefault(); 285 } 286 mAcceptLanguage = getCurrentAcceptLanguage(); 287 mUserAgent = getCurrentUserAgent(); 288 mUseDefaultUserAgent = true; 289 290 mBlockNetworkLoads = mContext.checkPermission( 291 "android.permission.INTERNET", android.os.Process.myPid(), 292 android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED; 293 294 // SDK specific settings. See issue 6212665 295 if (mContext.getApplicationInfo().targetSdkVersion < 296 Build.VERSION_CODES.JELLY_BEAN) { 297 mAllowUniversalAccessFromFileURLs = true; 298 mAllowFileAccessFromFileURLs = true; 299 } 300 try { 301 mPasswordEchoEnabled = 302 Settings.System.getInt(context.getContentResolver(), 303 Settings.System.TEXT_SHOW_PASSWORD) != 0; 304 } catch (SettingNotFoundException e) { 305 mPasswordEchoEnabled = true; 306 } 307 } 308 309 private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US"; 310 311 /** 312 * Looks at sLocale and returns current AcceptLanguage String. 313 * @return Current AcceptLanguage String. 314 */ 315 private String getCurrentAcceptLanguage() { 316 Locale locale; 317 synchronized(sLockForLocaleSettings) { 318 locale = sLocale; 319 } 320 StringBuilder buffer = new StringBuilder(); 321 addLocaleToHttpAcceptLanguage(buffer, locale); 322 323 if (!Locale.US.equals(locale)) { 324 if (buffer.length() > 0) { 325 buffer.append(", "); 326 } 327 buffer.append(ACCEPT_LANG_FOR_US_LOCALE); 328 } 329 330 return buffer.toString(); 331 } 332 333 /** 334 * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish, 335 * to new standard. 336 */ 337 private static String convertObsoleteLanguageCodeToNew(String langCode) { 338 if (langCode == null) { 339 return null; 340 } 341 if ("iw".equals(langCode)) { 342 // Hebrew 343 return "he"; 344 } else if ("in".equals(langCode)) { 345 // Indonesian 346 return "id"; 347 } else if ("ji".equals(langCode)) { 348 // Yiddish 349 return "yi"; 350 } 351 return langCode; 352 } 353 354 private static void addLocaleToHttpAcceptLanguage(StringBuilder builder, 355 Locale locale) { 356 String language = convertObsoleteLanguageCodeToNew(locale.getLanguage()); 357 if (language != null) { 358 builder.append(language); 359 String country = locale.getCountry(); 360 if (country != null) { 361 builder.append("-"); 362 builder.append(country); 363 } 364 } 365 } 366 367 /** 368 * Looks at sLocale and mContext and returns current UserAgent String. 369 * @return Current UserAgent String. 370 */ 371 private synchronized String getCurrentUserAgent() { 372 Locale locale; 373 synchronized(sLockForLocaleSettings) { 374 locale = sLocale; 375 } 376 StringBuffer buffer = new StringBuffer(); 377 // Add version 378 final String version = Build.VERSION.RELEASE; 379 if (version.length() > 0) { 380 if (Character.isDigit(version.charAt(0))) { 381 // Release is a version, eg "3.1" 382 buffer.append(version); 383 } else { 384 // Release is a codename, eg "Honeycomb" 385 // In this case, use the previous release's version 386 buffer.append(PREVIOUS_VERSION); 387 } 388 } else { 389 // default to "1.0" 390 buffer.append("1.0"); 391 } 392 buffer.append("; "); 393 final String language = locale.getLanguage(); 394 if (language != null) { 395 buffer.append(convertObsoleteLanguageCodeToNew(language)); 396 final String country = locale.getCountry(); 397 if (country != null) { 398 buffer.append("-"); 399 buffer.append(country.toLowerCase()); 400 } 401 } else { 402 // default to "en" 403 buffer.append("en"); 404 } 405 buffer.append(";"); 406 // add the model for the release build 407 if ("REL".equals(Build.VERSION.CODENAME)) { 408 final String model = Build.MODEL; 409 if (model.length() > 0) { 410 buffer.append(" "); 411 buffer.append(model); 412 } 413 } 414 final String id = Build.ID; 415 if (id.length() > 0) { 416 buffer.append(" Build/"); 417 buffer.append(id); 418 } 419 String mobile = mContext.getResources().getText( 420 com.android.internal.R.string.web_user_agent_target_content).toString(); 421 final String base = mContext.getResources().getText( 422 com.android.internal.R.string.web_user_agent).toString(); 423 return String.format(base, buffer, mobile); 424 } 425 426 /** 427 * @see android.webkit.WebSettings#setNavDump(boolean) 428 */ 429 @Override 430 @Deprecated 431 public void setNavDump(boolean enabled) { 432 mNavDump = enabled; 433 } 434 435 /** 436 * @see android.webkit.WebSettings#getNavDump() 437 */ 438 @Override 439 @Deprecated 440 public boolean getNavDump() { 441 return mNavDump; 442 } 443 444 /** 445 * @see android.webkit.WebSettings#setSupportZoom(boolean) 446 */ 447 @Override 448 public void setSupportZoom(boolean support) { 449 mSupportZoom = support; 450 mWebView.updateMultiTouchSupport(mContext); 451 } 452 453 /** 454 * @see android.webkit.WebSettings#supportZoom() 455 */ 456 @Override 457 public boolean supportZoom() { 458 return mSupportZoom; 459 } 460 461 /** 462 * @see android.webkit.WebSettings#setBuiltInZoomControls(boolean) 463 */ 464 @Override 465 public void setBuiltInZoomControls(boolean enabled) { 466 mBuiltInZoomControls = enabled; 467 mWebView.updateMultiTouchSupport(mContext); 468 } 469 470 /** 471 * @see android.webkit.WebSettings#getBuiltInZoomControls() 472 */ 473 @Override 474 public boolean getBuiltInZoomControls() { 475 return mBuiltInZoomControls; 476 } 477 478 /** 479 * @see android.webkit.WebSettings#setDisplayZoomControls(boolean) 480 */ 481 @Override 482 public void setDisplayZoomControls(boolean enabled) { 483 mDisplayZoomControls = enabled; 484 mWebView.updateMultiTouchSupport(mContext); 485 } 486 487 /** 488 * @see android.webkit.WebSettings#getDisplayZoomControls() 489 */ 490 @Override 491 public boolean getDisplayZoomControls() { 492 return mDisplayZoomControls; 493 } 494 495 /** 496 * @see android.webkit.WebSettings#setAllowFileAccess(boolean) 497 */ 498 @Override 499 public void setAllowFileAccess(boolean allow) { 500 mAllowFileAccess = allow; 501 } 502 503 /** 504 * @see android.webkit.WebSettings#getAllowFileAccess() 505 */ 506 @Override 507 public boolean getAllowFileAccess() { 508 return mAllowFileAccess; 509 } 510 511 /** 512 * @see android.webkit.WebSettings#setAllowContentAccess(boolean) 513 */ 514 @Override 515 public void setAllowContentAccess(boolean allow) { 516 mAllowContentAccess = allow; 517 } 518 519 /** 520 * @see android.webkit.WebSettings#getAllowContentAccess() 521 */ 522 @Override 523 public boolean getAllowContentAccess() { 524 return mAllowContentAccess; 525 } 526 527 /** 528 * @see android.webkit.WebSettings#setLoadWithOverviewMode(boolean) 529 */ 530 @Override 531 public void setLoadWithOverviewMode(boolean overview) { 532 mLoadWithOverviewMode = overview; 533 } 534 535 /** 536 * @see android.webkit.WebSettings#getLoadWithOverviewMode() 537 */ 538 @Override 539 public boolean getLoadWithOverviewMode() { 540 return mLoadWithOverviewMode; 541 } 542 543 /** 544 * @see android.webkit.WebSettings#setEnableSmoothTransition(boolean) 545 */ 546 @Override 547 public void setEnableSmoothTransition(boolean enable) { 548 mEnableSmoothTransition = enable; 549 } 550 551 /** 552 * @see android.webkit.WebSettings#enableSmoothTransition() 553 */ 554 @Override 555 public boolean enableSmoothTransition() { 556 return mEnableSmoothTransition; 557 } 558 559 /** 560 * @see android.webkit.WebSettings#setUseWebViewBackgroundForOverscrollBackground(boolean) 561 */ 562 @Override 563 @Deprecated 564 public void setUseWebViewBackgroundForOverscrollBackground(boolean view) { 565 mUseWebViewBackgroundForOverscroll = view; 566 } 567 568 /** 569 * @see android.webkit.WebSettings#getUseWebViewBackgroundForOverscrollBackground() 570 */ 571 @Override 572 @Deprecated 573 public boolean getUseWebViewBackgroundForOverscrollBackground() { 574 return mUseWebViewBackgroundForOverscroll; 575 } 576 577 /** 578 * @see android.webkit.WebSettings#setSaveFormData(boolean) 579 */ 580 @Override 581 public void setSaveFormData(boolean save) { 582 mSaveFormData = save; 583 } 584 585 /** 586 * @see android.webkit.WebSettings#getSaveFormData() 587 */ 588 @Override 589 public boolean getSaveFormData() { 590 return mSaveFormData && !mPrivateBrowsingEnabled; 591 } 592 593 /** 594 * @see android.webkit.WebSettings#setSavePassword(boolean) 595 */ 596 @Override 597 public void setSavePassword(boolean save) { 598 mSavePassword = save; 599 } 600 601 /** 602 * @see android.webkit.WebSettings#getSavePassword() 603 */ 604 @Override 605 public boolean getSavePassword() { 606 return mSavePassword; 607 } 608 609 /** 610 * @see android.webkit.WebSettings#setTextZoom(int) 611 */ 612 @Override 613 public synchronized void setTextZoom(int textZoom) { 614 if (mTextSize != textZoom) { 615 if (WebViewClassic.mLogEvent) { 616 EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE, 617 mTextSize, textZoom); 618 } 619 mTextSize = textZoom; 620 postSync(); 621 } 622 } 623 624 /** 625 * @see android.webkit.WebSettings#getTextZoom() 626 */ 627 @Override 628 public synchronized int getTextZoom() { 629 return mTextSize; 630 } 631 632 /** 633 * @see android.webkit.WebSettings#setTextSize(android.webkit.WebSettingsClassic.TextSize) 634 */ 635 @Override 636 public synchronized void setTextSize(TextSize t) { 637 setTextZoom(t.value); 638 } 639 640 /** 641 * @see android.webkit.WebSettings#getTextSize() 642 */ 643 @Override 644 public synchronized TextSize getTextSize() { 645 TextSize closestSize = null; 646 int smallestDelta = Integer.MAX_VALUE; 647 for (TextSize size : TextSize.values()) { 648 int delta = Math.abs(mTextSize - size.value); 649 if (delta == 0) { 650 return size; 651 } 652 if (delta < smallestDelta) { 653 smallestDelta = delta; 654 closestSize = size; 655 } 656 } 657 return closestSize != null ? closestSize : TextSize.NORMAL; 658 } 659 660 /** 661 * Set the double-tap zoom of the page in percent. Default is 100. 662 * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom. 663 */ 664 public void setDoubleTapZoom(int doubleTapZoom) { 665 if (mDoubleTapZoom != doubleTapZoom) { 666 mDoubleTapZoom = doubleTapZoom; 667 mWebView.updateDoubleTapZoom(doubleTapZoom); 668 } 669 } 670 671 /** 672 * Get the double-tap zoom of the page in percent. 673 * @return A percent value describing the double-tap zoom. 674 */ 675 public int getDoubleTapZoom() { 676 return mDoubleTapZoom; 677 } 678 679 /** 680 * @see android.webkit.WebSettings#setDefaultZoom(android.webkit.WebSettingsClassic.ZoomDensity) 681 */ 682 @Override 683 public void setDefaultZoom(ZoomDensity zoom) { 684 if (mDefaultZoom != zoom) { 685 mDefaultZoom = zoom; 686 mWebView.adjustDefaultZoomDensity(zoom.value); 687 } 688 } 689 690 /** 691 * @see android.webkit.WebSettings#getDefaultZoom() 692 */ 693 @Override 694 public ZoomDensity getDefaultZoom() { 695 return mDefaultZoom; 696 } 697 698 /** 699 * @see android.webkit.WebSettings#setLightTouchEnabled(boolean) 700 */ 701 @Override 702 public void setLightTouchEnabled(boolean enabled) { 703 mLightTouchEnabled = enabled; 704 } 705 706 /** 707 * @see android.webkit.WebSettings#getLightTouchEnabled() 708 */ 709 @Override 710 public boolean getLightTouchEnabled() { 711 return mLightTouchEnabled; 712 } 713 714 /** 715 * @see android.webkit.WebSettings#setUseDoubleTree(boolean) 716 */ 717 @Override 718 @Deprecated 719 public synchronized void setUseDoubleTree(boolean use) { 720 return; 721 } 722 723 /** 724 * @see android.webkit.WebSettings#getUseDoubleTree() 725 */ 726 @Override 727 @Deprecated 728 public synchronized boolean getUseDoubleTree() { 729 return false; 730 } 731 732 /** 733 * @see android.webkit.WebSettings#setUserAgent(int) 734 */ 735 @Override 736 @Deprecated 737 public synchronized void setUserAgent(int ua) { 738 String uaString = null; 739 if (ua == 1) { 740 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 741 return; // do nothing 742 } else { 743 uaString = DESKTOP_USERAGENT; 744 } 745 } else if (ua == 2) { 746 if (IPHONE_USERAGENT.equals(mUserAgent)) { 747 return; // do nothing 748 } else { 749 uaString = IPHONE_USERAGENT; 750 } 751 } else if (ua != 0) { 752 return; // do nothing 753 } 754 setUserAgentString(uaString); 755 } 756 757 /** 758 * @see android.webkit.WebSettings#getUserAgent() 759 */ 760 @Override 761 @Deprecated 762 public synchronized int getUserAgent() { 763 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 764 return 1; 765 } else if (IPHONE_USERAGENT.equals(mUserAgent)) { 766 return 2; 767 } else if (mUseDefaultUserAgent) { 768 return 0; 769 } 770 return -1; 771 } 772 773 /** 774 * @see android.webkit.WebSettings#setUseWideViewPort(boolean) 775 */ 776 @Override 777 public synchronized void setUseWideViewPort(boolean use) { 778 if (mUseWideViewport != use) { 779 mUseWideViewport = use; 780 postSync(); 781 } 782 } 783 784 /** 785 * @see android.webkit.WebSettings#getUseWideViewPort() 786 */ 787 @Override 788 public synchronized boolean getUseWideViewPort() { 789 return mUseWideViewport; 790 } 791 792 /** 793 * @see android.webkit.WebSettings#setSupportMultipleWindows(boolean) 794 */ 795 @Override 796 public synchronized void setSupportMultipleWindows(boolean support) { 797 if (mSupportMultipleWindows != support) { 798 mSupportMultipleWindows = support; 799 postSync(); 800 } 801 } 802 803 /** 804 * @see android.webkit.WebSettings#supportMultipleWindows() 805 */ 806 @Override 807 public synchronized boolean supportMultipleWindows() { 808 return mSupportMultipleWindows; 809 } 810 811 /** 812 * @see android.webkit.WebSettings#setLayoutAlgorithm(android.webkit.WebSettingsClassic.LayoutAlgorithm) 813 */ 814 @Override 815 public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) { 816 // XXX: This will only be affective if libwebcore was built with 817 // ANDROID_LAYOUT defined. 818 if (mLayoutAlgorithm != l) { 819 mLayoutAlgorithm = l; 820 postSync(); 821 } 822 } 823 824 /** 825 * @see android.webkit.WebSettings#getLayoutAlgorithm() 826 */ 827 @Override 828 public synchronized LayoutAlgorithm getLayoutAlgorithm() { 829 return mLayoutAlgorithm; 830 } 831 832 /** 833 * @see android.webkit.WebSettings#setStandardFontFamily(java.lang.String) 834 */ 835 @Override 836 public synchronized void setStandardFontFamily(String font) { 837 if (font != null && !font.equals(mStandardFontFamily)) { 838 mStandardFontFamily = font; 839 postSync(); 840 } 841 } 842 843 /** 844 * @see android.webkit.WebSettings#getStandardFontFamily() 845 */ 846 @Override 847 public synchronized String getStandardFontFamily() { 848 return mStandardFontFamily; 849 } 850 851 /** 852 * @see android.webkit.WebSettings#setFixedFontFamily(java.lang.String) 853 */ 854 @Override 855 public synchronized void setFixedFontFamily(String font) { 856 if (font != null && !font.equals(mFixedFontFamily)) { 857 mFixedFontFamily = font; 858 postSync(); 859 } 860 } 861 862 /** 863 * @see android.webkit.WebSettings#getFixedFontFamily() 864 */ 865 @Override 866 public synchronized String getFixedFontFamily() { 867 return mFixedFontFamily; 868 } 869 870 /** 871 * @see android.webkit.WebSettings#setSansSerifFontFamily(java.lang.String) 872 */ 873 @Override 874 public synchronized void setSansSerifFontFamily(String font) { 875 if (font != null && !font.equals(mSansSerifFontFamily)) { 876 mSansSerifFontFamily = font; 877 postSync(); 878 } 879 } 880 881 /** 882 * @see android.webkit.WebSettings#getSansSerifFontFamily() 883 */ 884 @Override 885 public synchronized String getSansSerifFontFamily() { 886 return mSansSerifFontFamily; 887 } 888 889 /** 890 * @see android.webkit.WebSettings#setSerifFontFamily(java.lang.String) 891 */ 892 @Override 893 public synchronized void setSerifFontFamily(String font) { 894 if (font != null && !font.equals(mSerifFontFamily)) { 895 mSerifFontFamily = font; 896 postSync(); 897 } 898 } 899 900 /** 901 * @see android.webkit.WebSettings#getSerifFontFamily() 902 */ 903 @Override 904 public synchronized String getSerifFontFamily() { 905 return mSerifFontFamily; 906 } 907 908 /** 909 * @see android.webkit.WebSettings#setCursiveFontFamily(java.lang.String) 910 */ 911 @Override 912 public synchronized void setCursiveFontFamily(String font) { 913 if (font != null && !font.equals(mCursiveFontFamily)) { 914 mCursiveFontFamily = font; 915 postSync(); 916 } 917 } 918 919 /** 920 * @see android.webkit.WebSettings#getCursiveFontFamily() 921 */ 922 @Override 923 public synchronized String getCursiveFontFamily() { 924 return mCursiveFontFamily; 925 } 926 927 /** 928 * @see android.webkit.WebSettings#setFantasyFontFamily(java.lang.String) 929 */ 930 @Override 931 public synchronized void setFantasyFontFamily(String font) { 932 if (font != null && !font.equals(mFantasyFontFamily)) { 933 mFantasyFontFamily = font; 934 postSync(); 935 } 936 } 937 938 /** 939 * @see android.webkit.WebSettings#getFantasyFontFamily() 940 */ 941 @Override 942 public synchronized String getFantasyFontFamily() { 943 return mFantasyFontFamily; 944 } 945 946 /** 947 * @see android.webkit.WebSettings#setMinimumFontSize(int) 948 */ 949 @Override 950 public synchronized void setMinimumFontSize(int size) { 951 size = pin(size); 952 if (mMinimumFontSize != size) { 953 mMinimumFontSize = size; 954 postSync(); 955 } 956 } 957 958 /** 959 * @see android.webkit.WebSettings#getMinimumFontSize() 960 */ 961 @Override 962 public synchronized int getMinimumFontSize() { 963 return mMinimumFontSize; 964 } 965 966 /** 967 * @see android.webkit.WebSettings#setMinimumLogicalFontSize(int) 968 */ 969 @Override 970 public synchronized void setMinimumLogicalFontSize(int size) { 971 size = pin(size); 972 if (mMinimumLogicalFontSize != size) { 973 mMinimumLogicalFontSize = size; 974 postSync(); 975 } 976 } 977 978 /** 979 * @see android.webkit.WebSettings#getMinimumLogicalFontSize() 980 */ 981 @Override 982 public synchronized int getMinimumLogicalFontSize() { 983 return mMinimumLogicalFontSize; 984 } 985 986 /** 987 * @see android.webkit.WebSettings#setDefaultFontSize(int) 988 */ 989 @Override 990 public synchronized void setDefaultFontSize(int size) { 991 size = pin(size); 992 if (mDefaultFontSize != size) { 993 mDefaultFontSize = size; 994 postSync(); 995 } 996 } 997 998 /** 999 * @see android.webkit.WebSettings#getDefaultFontSize() 1000 */ 1001 @Override 1002 public synchronized int getDefaultFontSize() { 1003 return mDefaultFontSize; 1004 } 1005 1006 /** 1007 * @see android.webkit.WebSettings#setDefaultFixedFontSize(int) 1008 */ 1009 @Override 1010 public synchronized void setDefaultFixedFontSize(int size) { 1011 size = pin(size); 1012 if (mDefaultFixedFontSize != size) { 1013 mDefaultFixedFontSize = size; 1014 postSync(); 1015 } 1016 } 1017 1018 /** 1019 * @see android.webkit.WebSettings#getDefaultFixedFontSize() 1020 */ 1021 @Override 1022 public synchronized int getDefaultFixedFontSize() { 1023 return mDefaultFixedFontSize; 1024 } 1025 1026 /** 1027 * Set the number of pages cached by the WebKit for the history navigation. 1028 * @param size A non-negative integer between 0 (no cache) and 20 (max). 1029 */ 1030 public synchronized void setPageCacheCapacity(int size) { 1031 if (size < 0) size = 0; 1032 if (size > 20) size = 20; 1033 if (mPageCacheCapacity != size) { 1034 mPageCacheCapacity = size; 1035 postSync(); 1036 } 1037 } 1038 1039 /** 1040 * @see android.webkit.WebSettings#setLoadsImagesAutomatically(boolean) 1041 */ 1042 @Override 1043 public synchronized void setLoadsImagesAutomatically(boolean flag) { 1044 if (mLoadsImagesAutomatically != flag) { 1045 mLoadsImagesAutomatically = flag; 1046 postSync(); 1047 } 1048 } 1049 1050 /** 1051 * @see android.webkit.WebSettings#getLoadsImagesAutomatically() 1052 */ 1053 @Override 1054 public synchronized boolean getLoadsImagesAutomatically() { 1055 return mLoadsImagesAutomatically; 1056 } 1057 1058 /** 1059 * @see android.webkit.WebSettings#setBlockNetworkImage(boolean) 1060 */ 1061 @Override 1062 public synchronized void setBlockNetworkImage(boolean flag) { 1063 if (mBlockNetworkImage != flag) { 1064 mBlockNetworkImage = flag; 1065 postSync(); 1066 } 1067 } 1068 1069 /** 1070 * @see android.webkit.WebSettings#getBlockNetworkImage() 1071 */ 1072 @Override 1073 public synchronized boolean getBlockNetworkImage() { 1074 return mBlockNetworkImage; 1075 } 1076 1077 /** 1078 * @see android.webkit.WebSettings#setBlockNetworkLoads(boolean) 1079 */ 1080 @Override 1081 public synchronized void setBlockNetworkLoads(boolean flag) { 1082 if (mBlockNetworkLoads != flag) { 1083 mBlockNetworkLoads = flag; 1084 verifyNetworkAccess(); 1085 postSync(); 1086 } 1087 } 1088 1089 /** 1090 * @see android.webkit.WebSettings#getBlockNetworkLoads() 1091 */ 1092 @Override 1093 public synchronized boolean getBlockNetworkLoads() { 1094 return mBlockNetworkLoads; 1095 } 1096 1097 1098 private void verifyNetworkAccess() { 1099 if (!mBlockNetworkLoads) { 1100 if (mContext.checkPermission("android.permission.INTERNET", 1101 android.os.Process.myPid(), android.os.Process.myUid()) != 1102 PackageManager.PERMISSION_GRANTED) { 1103 throw new SecurityException 1104 ("Permission denied - " + 1105 "application missing INTERNET permission"); 1106 } 1107 } 1108 } 1109 1110 /** 1111 * @see android.webkit.WebSettings#setJavaScriptEnabled(boolean) 1112 */ 1113 @Override 1114 public synchronized void setJavaScriptEnabled(boolean flag) { 1115 if (mJavaScriptEnabled != flag) { 1116 mJavaScriptEnabled = flag; 1117 postSync(); 1118 } 1119 } 1120 1121 /** 1122 * @see android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs 1123 */ 1124 @Override 1125 public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) { 1126 if (mAllowUniversalAccessFromFileURLs != flag) { 1127 mAllowUniversalAccessFromFileURLs = flag; 1128 postSync(); 1129 } 1130 } 1131 1132 /** 1133 * @see android.webkit.WebSettings#setAllowFileAccessFromFileURLs 1134 */ 1135 @Override 1136 public synchronized void setAllowFileAccessFromFileURLs(boolean flag) { 1137 if (mAllowFileAccessFromFileURLs != flag) { 1138 mAllowFileAccessFromFileURLs = flag; 1139 postSync(); 1140 } 1141 } 1142 1143 /** 1144 * Tell the WebView to use Skia's hardware accelerated rendering path 1145 * @param flag True if the WebView should use Skia's hw-accel path 1146 */ 1147 public synchronized void setHardwareAccelSkiaEnabled(boolean flag) { 1148 if (mHardwareAccelSkia != flag) { 1149 mHardwareAccelSkia = flag; 1150 postSync(); 1151 } 1152 } 1153 1154 /** 1155 * @return True if the WebView is using hardware accelerated skia 1156 */ 1157 public synchronized boolean getHardwareAccelSkiaEnabled() { 1158 return mHardwareAccelSkia; 1159 } 1160 1161 /** 1162 * Tell the WebView to show the visual indicator 1163 * @param flag True if the WebView should show the visual indicator 1164 */ 1165 public synchronized void setShowVisualIndicator(boolean flag) { 1166 if (mShowVisualIndicator != flag) { 1167 mShowVisualIndicator = flag; 1168 postSync(); 1169 } 1170 } 1171 1172 /** 1173 * @return True if the WebView is showing the visual indicator 1174 */ 1175 public synchronized boolean getShowVisualIndicator() { 1176 return mShowVisualIndicator; 1177 } 1178 1179 /** 1180 * @see android.webkit.WebSettings#setPluginsEnabled(boolean) 1181 */ 1182 @Override 1183 @Deprecated 1184 public synchronized void setPluginsEnabled(boolean flag) { 1185 setPluginState(flag ? PluginState.ON : PluginState.OFF); 1186 } 1187 1188 /** 1189 * @see android.webkit.WebSettings#setPluginState(android.webkit.WebSettingsClassic.PluginState) 1190 */ 1191 @Override 1192 public synchronized void setPluginState(PluginState state) { 1193 if (mPluginState != state) { 1194 mPluginState = state; 1195 postSync(); 1196 } 1197 } 1198 1199 /** 1200 * @see android.webkit.WebSettings#setPluginsPath(java.lang.String) 1201 */ 1202 @Override 1203 @Deprecated 1204 public synchronized void setPluginsPath(String pluginsPath) { 1205 } 1206 1207 /** 1208 * @see android.webkit.WebSettings#setDatabasePath(java.lang.String) 1209 */ 1210 @Override 1211 public synchronized void setDatabasePath(String databasePath) { 1212 if (databasePath != null && !mDatabasePathHasBeenSet) { 1213 mDatabasePath = databasePath; 1214 mDatabasePathHasBeenSet = true; 1215 postSync(); 1216 } 1217 } 1218 1219 /** 1220 * @see android.webkit.WebSettings#setGeolocationDatabasePath(java.lang.String) 1221 */ 1222 @Override 1223 public synchronized void setGeolocationDatabasePath(String databasePath) { 1224 if (databasePath != null 1225 && !databasePath.equals(mGeolocationDatabasePath)) { 1226 mGeolocationDatabasePath = databasePath; 1227 postSync(); 1228 } 1229 } 1230 1231 /** 1232 * @see android.webkit.WebSettings#setAppCacheEnabled(boolean) 1233 */ 1234 @Override 1235 public synchronized void setAppCacheEnabled(boolean flag) { 1236 if (mAppCacheEnabled != flag) { 1237 mAppCacheEnabled = flag; 1238 postSync(); 1239 } 1240 } 1241 1242 /** 1243 * @see android.webkit.WebSettings#setAppCachePath(java.lang.String) 1244 */ 1245 @Override 1246 public synchronized void setAppCachePath(String path) { 1247 // We test for a valid path and for repeated setting on the native 1248 // side, but we can avoid syncing in some simple cases. 1249 if (mAppCachePath == null && path != null && !path.isEmpty()) { 1250 mAppCachePath = path; 1251 postSync(); 1252 } 1253 } 1254 1255 /** 1256 * @see android.webkit.WebSettings#setAppCacheMaxSize(long) 1257 */ 1258 @Override 1259 public synchronized void setAppCacheMaxSize(long appCacheMaxSize) { 1260 if (appCacheMaxSize != mAppCacheMaxSize) { 1261 mAppCacheMaxSize = appCacheMaxSize; 1262 postSync(); 1263 } 1264 } 1265 1266 /** 1267 * @see android.webkit.WebSettings#setDatabaseEnabled(boolean) 1268 */ 1269 @Override 1270 public synchronized void setDatabaseEnabled(boolean flag) { 1271 if (mDatabaseEnabled != flag) { 1272 mDatabaseEnabled = flag; 1273 postSync(); 1274 } 1275 } 1276 1277 /** 1278 * @see android.webkit.WebSettings#setDomStorageEnabled(boolean) 1279 */ 1280 @Override 1281 public synchronized void setDomStorageEnabled(boolean flag) { 1282 if (mDomStorageEnabled != flag) { 1283 mDomStorageEnabled = flag; 1284 postSync(); 1285 } 1286 } 1287 1288 /** 1289 * @see android.webkit.WebSettings#getDomStorageEnabled() 1290 */ 1291 @Override 1292 public synchronized boolean getDomStorageEnabled() { 1293 return mDomStorageEnabled; 1294 } 1295 1296 /** 1297 * @see android.webkit.WebSettings#getDatabasePath() 1298 */ 1299 @Override 1300 public synchronized String getDatabasePath() { 1301 return mDatabasePath; 1302 } 1303 1304 /** 1305 * @see android.webkit.WebSettings#getDatabaseEnabled() 1306 */ 1307 @Override 1308 public synchronized boolean getDatabaseEnabled() { 1309 return mDatabaseEnabled; 1310 } 1311 1312 /** 1313 * Tell the WebView to enable WebWorkers API. 1314 * @param flag True if the WebView should enable WebWorkers. 1315 * Note that this flag only affects V8. JSC does not have 1316 * an equivalent setting. 1317 */ 1318 public synchronized void setWorkersEnabled(boolean flag) { 1319 if (mWorkersEnabled != flag) { 1320 mWorkersEnabled = flag; 1321 postSync(); 1322 } 1323 } 1324 1325 /** 1326 * @see android.webkit.WebSettings#setGeolocationEnabled(boolean) 1327 */ 1328 @Override 1329 public synchronized void setGeolocationEnabled(boolean flag) { 1330 if (mGeolocationEnabled != flag) { 1331 mGeolocationEnabled = flag; 1332 postSync(); 1333 } 1334 } 1335 1336 /** 1337 * Sets whether XSS Auditor is enabled. 1338 * Only used by LayoutTestController. 1339 * @param flag Whether XSS Auditor should be enabled. 1340 */ 1341 public synchronized void setXSSAuditorEnabled(boolean flag) { 1342 if (mXSSAuditorEnabled != flag) { 1343 mXSSAuditorEnabled = flag; 1344 postSync(); 1345 } 1346 } 1347 1348 /** 1349 * Enables/disables HTML5 link "prefetch" parameter. 1350 */ 1351 public synchronized void setLinkPrefetchEnabled(boolean flag) { 1352 if (mLinkPrefetchEnabled != flag) { 1353 mLinkPrefetchEnabled = flag; 1354 postSync(); 1355 } 1356 } 1357 1358 /** 1359 * @see android.webkit.WebSettings#getJavaScriptEnabled() 1360 */ 1361 @Override 1362 public synchronized boolean getJavaScriptEnabled() { 1363 return mJavaScriptEnabled; 1364 } 1365 1366 /** 1367 * @see android.webkit.WebSettings#getAllowUniversalFileAccessFromFileURLs 1368 */ 1369 @Override 1370 public synchronized boolean getAllowUniversalAccessFromFileURLs() { 1371 return mAllowUniversalAccessFromFileURLs; 1372 } 1373 1374 /** 1375 * @see android.webkit.WebSettings#getAllowFileAccessFromFileURLs 1376 */ 1377 @Override 1378 public synchronized boolean getAllowFileAccessFromFileURLs() { 1379 return mAllowFileAccessFromFileURLs; 1380 } 1381 1382 /** 1383 * @see android.webkit.WebSettings#getPluginsEnabled() 1384 */ 1385 @Override 1386 @Deprecated 1387 public synchronized boolean getPluginsEnabled() { 1388 return mPluginState == PluginState.ON; 1389 } 1390 1391 /** 1392 * @see android.webkit.WebSettings#getPluginState() 1393 */ 1394 @Override 1395 public synchronized PluginState getPluginState() { 1396 return mPluginState; 1397 } 1398 1399 /** 1400 * @see android.webkit.WebSettings#getPluginsPath() 1401 */ 1402 @Override 1403 @Deprecated 1404 public synchronized String getPluginsPath() { 1405 return ""; 1406 } 1407 1408 /** 1409 * @see android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically(boolean) 1410 */ 1411 @Override 1412 public synchronized void setJavaScriptCanOpenWindowsAutomatically( 1413 boolean flag) { 1414 if (mJavaScriptCanOpenWindowsAutomatically != flag) { 1415 mJavaScriptCanOpenWindowsAutomatically = flag; 1416 postSync(); 1417 } 1418 } 1419 1420 /** 1421 * @see android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically() 1422 */ 1423 @Override 1424 public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() { 1425 return mJavaScriptCanOpenWindowsAutomatically; 1426 } 1427 1428 /** 1429 * @see android.webkit.WebSettings#setDefaultTextEncodingName(java.lang.String) 1430 */ 1431 @Override 1432 public synchronized void setDefaultTextEncodingName(String encoding) { 1433 if (encoding != null && !encoding.equals(mDefaultTextEncoding)) { 1434 mDefaultTextEncoding = encoding; 1435 postSync(); 1436 } 1437 } 1438 1439 /** 1440 * @see android.webkit.WebSettings#getDefaultTextEncodingName() 1441 */ 1442 @Override 1443 public synchronized String getDefaultTextEncodingName() { 1444 return mDefaultTextEncoding; 1445 } 1446 1447 /** 1448 * @see android.webkit.WebSettings#setUserAgentString(java.lang.String) 1449 */ 1450 @Override 1451 public synchronized void setUserAgentString(String ua) { 1452 if (ua == null || ua.length() == 0) { 1453 synchronized(sLockForLocaleSettings) { 1454 Locale currentLocale = Locale.getDefault(); 1455 if (!sLocale.equals(currentLocale)) { 1456 sLocale = currentLocale; 1457 mAcceptLanguage = getCurrentAcceptLanguage(); 1458 } 1459 } 1460 ua = getCurrentUserAgent(); 1461 mUseDefaultUserAgent = true; 1462 } else { 1463 mUseDefaultUserAgent = false; 1464 } 1465 1466 if (!ua.equals(mUserAgent)) { 1467 mUserAgent = ua; 1468 postSync(); 1469 } 1470 } 1471 1472 /** 1473 * @see android.webkit.WebSettings#getUserAgentString() 1474 */ 1475 @Override 1476 public synchronized String getUserAgentString() { 1477 if (DESKTOP_USERAGENT.equals(mUserAgent) || 1478 IPHONE_USERAGENT.equals(mUserAgent) || 1479 !mUseDefaultUserAgent) { 1480 return mUserAgent; 1481 } 1482 1483 boolean doPostSync = false; 1484 synchronized(sLockForLocaleSettings) { 1485 Locale currentLocale = Locale.getDefault(); 1486 if (!sLocale.equals(currentLocale)) { 1487 sLocale = currentLocale; 1488 mUserAgent = getCurrentUserAgent(); 1489 mAcceptLanguage = getCurrentAcceptLanguage(); 1490 doPostSync = true; 1491 } 1492 } 1493 if (doPostSync) { 1494 postSync(); 1495 } 1496 return mUserAgent; 1497 } 1498 1499 /* package api to grab the Accept Language string. */ 1500 /*package*/ synchronized String getAcceptLanguage() { 1501 synchronized(sLockForLocaleSettings) { 1502 Locale currentLocale = Locale.getDefault(); 1503 if (!sLocale.equals(currentLocale)) { 1504 sLocale = currentLocale; 1505 mAcceptLanguage = getCurrentAcceptLanguage(); 1506 } 1507 } 1508 return mAcceptLanguage; 1509 } 1510 1511 /* package */ boolean isNarrowColumnLayout() { 1512 return getLayoutAlgorithm() == LayoutAlgorithm.NARROW_COLUMNS; 1513 } 1514 1515 /** 1516 * @see android.webkit.WebSettings#setNeedInitialFocus(boolean) 1517 */ 1518 @Override 1519 public void setNeedInitialFocus(boolean flag) { 1520 if (mNeedInitialFocus != flag) { 1521 mNeedInitialFocus = flag; 1522 } 1523 } 1524 1525 /* Package api to get the choice whether it needs to set initial focus. */ 1526 /* package */ boolean getNeedInitialFocus() { 1527 return mNeedInitialFocus; 1528 } 1529 1530 /** 1531 * @see android.webkit.WebSettings#setRenderPriority(android.webkit.WebSettingsClassic.RenderPriority) 1532 */ 1533 @Override 1534 public synchronized void setRenderPriority(RenderPriority priority) { 1535 if (mRenderPriority != priority) { 1536 mRenderPriority = priority; 1537 mEventHandler.sendMessage(Message.obtain(null, 1538 EventHandler.PRIORITY)); 1539 } 1540 } 1541 1542 /** 1543 * @see android.webkit.WebSettings#setCacheMode(int) 1544 */ 1545 @Override 1546 public void setCacheMode(int mode) { 1547 if (mode != mOverrideCacheMode) { 1548 mOverrideCacheMode = mode; 1549 postSync(); 1550 } 1551 } 1552 1553 /** 1554 * @see android.webkit.WebSettings#getCacheMode() 1555 */ 1556 @Override 1557 public int getCacheMode() { 1558 return mOverrideCacheMode; 1559 } 1560 1561 /** 1562 * If set, webkit alternately shrinks and expands images viewed outside 1563 * of an HTML page to fit the screen. This conflicts with attempts by 1564 * the UI to zoom in and out of an image, so it is set false by default. 1565 * @param shrink Set true to let webkit shrink the standalone image to fit. 1566 */ 1567 public void setShrinksStandaloneImagesToFit(boolean shrink) { 1568 if (mShrinksStandaloneImagesToFit != shrink) { 1569 mShrinksStandaloneImagesToFit = shrink; 1570 postSync(); 1571 } 1572 } 1573 1574 /** 1575 * Specify the maximum decoded image size. The default is 1576 * 2 megs for small memory devices and 8 megs for large memory devices. 1577 * @param size The maximum decoded size, or zero to set to the default. 1578 */ 1579 public void setMaximumDecodedImageSize(long size) { 1580 if (mMaximumDecodedImageSize != size) { 1581 mMaximumDecodedImageSize = size; 1582 postSync(); 1583 } 1584 } 1585 1586 /** 1587 * Returns whether to use fixed viewport. Use fixed viewport 1588 * whenever wide viewport is on. 1589 */ 1590 /* package */ boolean getUseFixedViewport() { 1591 return getUseWideViewPort(); 1592 } 1593 1594 /** 1595 * Returns whether private browsing is enabled. 1596 */ 1597 /* package */ boolean isPrivateBrowsingEnabled() { 1598 return mPrivateBrowsingEnabled; 1599 } 1600 1601 /** 1602 * Sets whether private browsing is enabled. 1603 * @param flag Whether private browsing should be enabled. 1604 */ 1605 /* package */ synchronized void setPrivateBrowsingEnabled(boolean flag) { 1606 if (mPrivateBrowsingEnabled != flag) { 1607 mPrivateBrowsingEnabled = flag; 1608 1609 // AutoFill is dependant on private browsing being enabled so 1610 // reset it to take account of the new value of mPrivateBrowsingEnabled. 1611 setAutoFillEnabled(mAutoFillEnabled); 1612 1613 postSync(); 1614 } 1615 } 1616 1617 /** 1618 * Returns whether the viewport metatag can disable zooming 1619 */ 1620 public boolean forceUserScalable() { 1621 return mForceUserScalable; 1622 } 1623 1624 /** 1625 * Sets whether viewport metatag can disable zooming. 1626 * @param flag Whether or not to forceably enable user scalable. 1627 */ 1628 public synchronized void setForceUserScalable(boolean flag) { 1629 mForceUserScalable = flag; 1630 } 1631 1632 synchronized void setSyntheticLinksEnabled(boolean flag) { 1633 if (mSyntheticLinksEnabled != flag) { 1634 mSyntheticLinksEnabled = flag; 1635 postSync(); 1636 } 1637 } 1638 1639 public synchronized void setAutoFillEnabled(boolean enabled) { 1640 // AutoFill is always disabled in private browsing mode. 1641 boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled; 1642 if (mAutoFillEnabled != autoFillEnabled) { 1643 mAutoFillEnabled = autoFillEnabled; 1644 postSync(); 1645 } 1646 } 1647 1648 public synchronized boolean getAutoFillEnabled() { 1649 return mAutoFillEnabled; 1650 } 1651 1652 public synchronized void setAutoFillProfile(AutoFillProfile profile) { 1653 if (mAutoFillProfile != profile) { 1654 mAutoFillProfile = profile; 1655 postSync(); 1656 } 1657 } 1658 1659 public synchronized AutoFillProfile getAutoFillProfile() { 1660 return mAutoFillProfile; 1661 } 1662 1663 int getDoubleTapToastCount() { 1664 return mDoubleTapToastCount; 1665 } 1666 1667 void setDoubleTapToastCount(int count) { 1668 if (mDoubleTapToastCount != count) { 1669 mDoubleTapToastCount = count; 1670 // write the settings in the non-UI thread 1671 mEventHandler.sendMessage(Message.obtain(null, 1672 EventHandler.SET_DOUBLE_TAP_TOAST_COUNT)); 1673 } 1674 } 1675 1676 public void setProperty(String key, String value) { 1677 if (mWebView.nativeSetProperty(key, value)) { 1678 mWebView.invalidate(); 1679 } 1680 } 1681 1682 public String getProperty(String key) { 1683 return mWebView.nativeGetProperty(key); 1684 } 1685 1686 /** 1687 * Transfer messages from the queue to the new WebCoreThread. Called from 1688 * WebCore thread. 1689 */ 1690 /*package*/ 1691 synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) { 1692 mBrowserFrame = frame; 1693 if (DebugFlags.WEB_SETTINGS) { 1694 junit.framework.Assert.assertTrue(frame.mNativeFrame != 0); 1695 } 1696 1697 SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE, 1698 Context.MODE_PRIVATE); 1699 if (mDoubleTapToastCount > 0) { 1700 mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT, 1701 mDoubleTapToastCount); 1702 } 1703 nativeSync(frame.mNativeFrame); 1704 mSyncPending = false; 1705 mEventHandler.createHandler(); 1706 } 1707 1708 /** 1709 * Let the Settings object know that our owner is being destroyed. 1710 */ 1711 /*package*/ 1712 synchronized void onDestroyed() { 1713 } 1714 1715 private int pin(int size) { 1716 // FIXME: 72 is just an arbitrary max text size value. 1717 if (size < 1) { 1718 return 1; 1719 } else if (size > 72) { 1720 return 72; 1721 } 1722 return size; 1723 } 1724 1725 /* Post a SYNC message to handle syncing the native settings. */ 1726 private synchronized void postSync() { 1727 // Only post if a sync is not pending 1728 if (!mSyncPending) { 1729 mSyncPending = mEventHandler.sendMessage( 1730 Message.obtain(null, EventHandler.SYNC)); 1731 } 1732 } 1733 1734 // Synchronize the native and java settings. 1735 private native void nativeSync(int nativeFrame); 1736 } 1737