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