1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.android_webview;
7 import android.content.Context;
8 import android.content.pm.PackageManager;
9 import android.os.Handler;
10 import android.os.Message;
11 import android.os.Process;
12 import android.provider.Settings;
13 import android.util.Log;
14 import android.webkit.WebSettings;
15 import android.webkit.WebSettings.PluginState;
17 import org.chromium.base.CalledByNative;
18 import org.chromium.base.JNINamespace;
19 import org.chromium.base.ThreadUtils;
20 import org.chromium.base.VisibleForTesting;
23 * Stores Android WebView specific settings that does not need to be synced to WebKit.
24 * Use {@link org.chromium.content.browser.ContentSettings} for WebKit settings.
26 * Methods in this class can be called from any thread, including threads created by
27 * the client of WebView.
29 @JNINamespace("android_webview")
30 public class AwSettings {
31 // This enum corresponds to WebSettings.LayoutAlgorithm. We use our own to be
33 public enum LayoutAlgorithm {
40 // These constants must be kept in sync with the Android framework, defined in WebSettimgs.
42 public static final int MIXED_CONTENT_ALWAYS_ALLOW = 0;
44 public static final int MIXED_CONTENT_NEVER_ALLOW = 1;
46 public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2;
48 private static final String TAG = "AwSettings";
50 // This class must be created on the UI thread. Afterwards, it can be
51 // used from any thread. Internally, the class uses a message queue
52 // to call native code on the UI thread only.
54 // Values passed in on construction.
55 private final boolean mHasInternetPermission;
57 private ZoomSupportChangeListener mZoomChangeListener;
58 private double mDIPScale = 1.0;
60 // Lock to protect all settings.
61 private final Object mAwSettingsLock = new Object();
63 private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
64 private int mTextSizePercent = 100;
65 private String mStandardFontFamily = "sans-serif";
66 private String mFixedFontFamily = "monospace";
67 private String mSansSerifFontFamily = "sans-serif";
68 private String mSerifFontFamily = "serif";
69 private String mCursiveFontFamily = "cursive";
70 private String mFantasyFontFamily = "fantasy";
71 private String mDefaultTextEncoding;
72 private String mUserAgent;
73 private int mMinimumFontSize = 8;
74 private int mMinimumLogicalFontSize = 8;
75 private int mDefaultFontSize = 16;
76 private int mDefaultFixedFontSize = 13;
77 private boolean mLoadsImagesAutomatically = true;
78 private boolean mImagesEnabled = true;
79 private boolean mJavaScriptEnabled = false;
80 private boolean mAllowUniversalAccessFromFileURLs = false;
81 private boolean mAllowFileAccessFromFileURLs = false;
82 private boolean mJavaScriptCanOpenWindowsAutomatically = false;
83 private boolean mSupportMultipleWindows = false;
84 private PluginState mPluginState = PluginState.OFF;
85 private boolean mAppCacheEnabled = false;
86 private boolean mDomStorageEnabled = false;
87 private boolean mDatabaseEnabled = false;
88 private boolean mUseWideViewport = false;
89 private boolean mZeroLayoutHeightDisablesViewportQuirk = false;
90 private boolean mForceZeroLayoutHeight = false;
91 private boolean mLoadWithOverviewMode = false;
92 private boolean mMediaPlaybackRequiresUserGesture = true;
93 private String mDefaultVideoPosterURL;
94 private float mInitialPageScalePercent = 0;
95 private boolean mSpatialNavigationEnabled; // Default depends on device features.
96 private boolean mEnableSupportedHardwareAcceleratedFeatures = false;
97 private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW;
98 private boolean mVideoOverlayForEmbeddedVideoEnabled = false;
100 // Although this bit is stored on AwSettings it is actually controlled via the CookieManager.
101 private boolean mAcceptThirdPartyCookies = false;
103 private final boolean mSupportLegacyQuirks;
105 private final boolean mPasswordEchoEnabled;
107 // Not accessed by the native side.
108 private boolean mBlockNetworkLoads; // Default depends on permission of embedding APK.
109 private boolean mAllowContentUrlAccess = true;
110 private boolean mAllowFileUrlAccess = true;
111 private int mCacheMode = WebSettings.LOAD_DEFAULT;
112 private boolean mShouldFocusFirstNode = true;
113 private boolean mGeolocationEnabled = true;
114 private boolean mAutoCompleteEnabled = true;
115 private boolean mFullscreenSupported = false;
116 private boolean mSupportZoom = true;
117 private boolean mBuiltInZoomControls = false;
118 private boolean mDisplayZoomControls = true;
120 static class LazyDefaultUserAgent{
121 // Lazy Holder pattern
122 private static final String sInstance = nativeGetDefaultUserAgent();
125 // Protects access to settings global fields.
126 private static final Object sGlobalContentSettingsLock = new Object();
127 // For compatibility with the legacy WebView, we can only enable AppCache when the path is
128 // provided. However, we don't use the path, so we just check if we have received it from the
130 private static boolean sAppCachePathIsSet = false;
132 // The native side of this object. It's lifetime is bounded by the WebContent it is attached to.
133 private long mNativeAwSettings = 0;
135 // Custom handler that queues messages to call native code on the UI thread.
136 private final EventHandler mEventHandler;
138 private static final int MINIMUM_FONT_SIZE = 1;
139 private static final int MAXIMUM_FONT_SIZE = 72;
141 // Class to handle messages to be processed on the UI thread.
142 private class EventHandler {
143 // Message id for running a Runnable with mAwSettingsLock held.
144 private static final int RUN_RUNNABLE_BLOCKING = 0;
145 // Actual UI thread handler
146 private Handler mHandler;
147 // Synchronization flag.
148 private boolean mSynchronizationPending = false;
153 void bindUiThread() {
154 if (mHandler != null) return;
155 mHandler = new Handler(ThreadUtils.getUiThreadLooper()) {
157 public void handleMessage(Message msg) {
159 case RUN_RUNNABLE_BLOCKING:
160 synchronized (mAwSettingsLock) {
161 if (mNativeAwSettings != 0) {
162 ((Runnable) msg.obj).run();
164 mSynchronizationPending = false;
165 mAwSettingsLock.notifyAll();
173 void runOnUiThreadBlockingAndLocked(Runnable r) {
174 assert Thread.holdsLock(mAwSettingsLock);
175 if (mHandler == null) return;
176 if (ThreadUtils.runningOnUiThread()) {
179 assert !mSynchronizationPending;
180 mSynchronizationPending = true;
181 mHandler.sendMessage(Message.obtain(null, RUN_RUNNABLE_BLOCKING, r));
183 while (mSynchronizationPending) {
184 mAwSettingsLock.wait();
186 } catch (InterruptedException e) {
187 Log.e(TAG, "Interrupted waiting a Runnable to complete", e);
188 mSynchronizationPending = false;
193 void maybePostOnUiThread(Runnable r) {
194 if (mHandler != null) {
199 void updateWebkitPreferencesLocked() {
200 runOnUiThreadBlockingAndLocked(new Runnable() {
203 updateWebkitPreferencesOnUiThreadLocked();
209 interface ZoomSupportChangeListener {
210 public void onGestureZoomSupportChanged(
211 boolean supportsDoubleTapZoom, boolean supportsMultiTouchZoom);
214 public AwSettings(Context context,
215 boolean isAccessFromFileURLsGrantedByDefault,
216 boolean supportsLegacyQuirks) {
217 boolean hasInternetPermission = context.checkPermission(
218 android.Manifest.permission.INTERNET,
220 Process.myUid()) == PackageManager.PERMISSION_GRANTED;
221 synchronized (mAwSettingsLock) {
222 mHasInternetPermission = hasInternetPermission;
223 mBlockNetworkLoads = !hasInternetPermission;
224 mEventHandler = new EventHandler();
225 if (isAccessFromFileURLsGrantedByDefault) {
226 mAllowUniversalAccessFromFileURLs = true;
227 mAllowFileAccessFromFileURLs = true;
230 mDefaultTextEncoding = AwResource.getDefaultTextEncoding();
231 mUserAgent = LazyDefaultUserAgent.sInstance;
233 // Best-guess a sensible initial value based on the features supported on the device.
234 mSpatialNavigationEnabled = !context.getPackageManager().hasSystemFeature(
235 PackageManager.FEATURE_TOUCHSCREEN);
237 // Respect the system setting for password echoing.
238 mPasswordEchoEnabled = Settings.System.getInt(context.getContentResolver(),
239 Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
241 // By default, scale the text size by the system font scale factor. Embedders
242 // may override this by invoking setTextZoom().
243 mTextSizePercent *= context.getResources().getConfiguration().fontScale;
245 mSupportLegacyQuirks = supportsLegacyQuirks;
247 // Defer initializing the native side until a native WebContents instance is set.
251 private void nativeAwSettingsGone(long nativeAwSettings) {
252 assert mNativeAwSettings != 0 && mNativeAwSettings == nativeAwSettings;
253 mNativeAwSettings = 0;
257 private double getDIPScaleLocked() {
258 assert Thread.holdsLock(mAwSettingsLock);
262 void setDIPScale(double dipScale) {
263 synchronized (mAwSettingsLock) {
264 mDIPScale = dipScale;
265 // TODO(joth): This should also be synced over to native side, but right now
266 // the setDIPScale call is always followed by a setWebContents() which covers this.
270 void setZoomListener(ZoomSupportChangeListener zoomChangeListener) {
271 synchronized (mAwSettingsLock) {
272 mZoomChangeListener = zoomChangeListener;
276 void setWebContents(long nativeWebContents) {
277 synchronized (mAwSettingsLock) {
278 if (mNativeAwSettings != 0) {
279 nativeDestroy(mNativeAwSettings);
280 assert mNativeAwSettings == 0; // nativeAwSettingsGone should have been called.
282 if (nativeWebContents != 0) {
283 mEventHandler.bindUiThread();
284 mNativeAwSettings = nativeInit(nativeWebContents);
285 updateEverythingLocked();
290 private void updateEverythingLocked() {
291 assert Thread.holdsLock(mAwSettingsLock);
292 assert mNativeAwSettings != 0;
293 nativeUpdateEverythingLocked(mNativeAwSettings);
294 onGestureZoomSupportChanged(
295 supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
299 * See {@link android.webkit.WebSettings#setBlockNetworkLoads}.
301 public void setBlockNetworkLoads(boolean flag) {
302 synchronized (mAwSettingsLock) {
303 if (!flag && !mHasInternetPermission) {
304 throw new SecurityException("Permission denied - " +
305 "application missing INTERNET permission");
307 mBlockNetworkLoads = flag;
312 * See {@link android.webkit.WebSettings#getBlockNetworkLoads}.
314 public boolean getBlockNetworkLoads() {
315 synchronized (mAwSettingsLock) {
316 return mBlockNetworkLoads;
321 * Enable/disable third party cookies for an AwContents
322 * @param accept true if we should accept third party cookies
324 public void setAcceptThirdPartyCookies(boolean accept) {
325 synchronized (mAwSettingsLock) {
326 if (mAcceptThirdPartyCookies != accept) {
327 mAcceptThirdPartyCookies = accept;
333 * Return whether third party cookies are enabled for an AwContents
334 * @return true if accept third party cookies
336 public boolean getAcceptThirdPartyCookies() {
337 synchronized (mAwSettingsLock) {
338 return mAcceptThirdPartyCookies;
343 * See {@link android.webkit.WebSettings#setAllowFileAccess}.
345 public void setAllowFileAccess(boolean allow) {
346 synchronized (mAwSettingsLock) {
347 if (mAllowFileUrlAccess != allow) {
348 mAllowFileUrlAccess = allow;
354 * See {@link android.webkit.WebSettings#getAllowFileAccess}.
356 public boolean getAllowFileAccess() {
357 synchronized (mAwSettingsLock) {
358 return mAllowFileUrlAccess;
363 * See {@link android.webkit.WebSettings#setAllowContentAccess}.
365 public void setAllowContentAccess(boolean allow) {
366 synchronized (mAwSettingsLock) {
367 if (mAllowContentUrlAccess != allow) {
368 mAllowContentUrlAccess = allow;
374 * See {@link android.webkit.WebSettings#getAllowContentAccess}.
376 public boolean getAllowContentAccess() {
377 synchronized (mAwSettingsLock) {
378 return mAllowContentUrlAccess;
383 * See {@link android.webkit.WebSettings#setCacheMode}.
385 public void setCacheMode(int mode) {
386 synchronized (mAwSettingsLock) {
387 if (mCacheMode != mode) {
394 * See {@link android.webkit.WebSettings#getCacheMode}.
396 public int getCacheMode() {
397 synchronized (mAwSettingsLock) {
403 * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
405 public void setShouldFocusFirstNode(boolean flag) {
406 synchronized (mAwSettingsLock) {
407 mShouldFocusFirstNode = flag;
412 * See {@link android.webkit.WebView#setInitialScale}.
414 public void setInitialPageScale(final float scaleInPercent) {
415 synchronized (mAwSettingsLock) {
416 if (mInitialPageScalePercent != scaleInPercent) {
417 mInitialPageScalePercent = scaleInPercent;
418 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
421 if (mNativeAwSettings != 0) {
422 nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
431 private float getInitialPageScalePercentLocked() {
432 assert Thread.holdsLock(mAwSettingsLock);
433 return mInitialPageScalePercent;
436 void setSpatialNavigationEnabled(boolean enable) {
437 synchronized (mAwSettingsLock) {
438 if (mSpatialNavigationEnabled != enable) {
439 mSpatialNavigationEnabled = enable;
440 mEventHandler.updateWebkitPreferencesLocked();
446 private boolean getSpatialNavigationLocked() {
447 assert Thread.holdsLock(mAwSettingsLock);
448 return mSpatialNavigationEnabled;
451 void setEnableSupportedHardwareAcceleratedFeatures(boolean enable) {
452 synchronized (mAwSettingsLock) {
453 if (mEnableSupportedHardwareAcceleratedFeatures != enable) {
454 mEnableSupportedHardwareAcceleratedFeatures = enable;
455 mEventHandler.updateWebkitPreferencesLocked();
461 private boolean getEnableSupportedHardwareAcceleratedFeaturesLocked() {
462 assert Thread.holdsLock(mAwSettingsLock);
463 return mEnableSupportedHardwareAcceleratedFeatures;
466 public void setFullscreenSupported(boolean supported) {
467 synchronized (mAwSettingsLock) {
468 if (mFullscreenSupported != supported) {
469 mFullscreenSupported = supported;
470 mEventHandler.updateWebkitPreferencesLocked();
476 private boolean getFullscreenSupportedLocked() {
477 assert Thread.holdsLock(mAwSettingsLock);
478 return mFullscreenSupported;
482 * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
484 public boolean shouldFocusFirstNode() {
485 synchronized (mAwSettingsLock) {
486 return mShouldFocusFirstNode;
491 * See {@link android.webkit.WebSettings#setGeolocationEnabled}.
493 public void setGeolocationEnabled(boolean flag) {
494 synchronized (mAwSettingsLock) {
495 if (mGeolocationEnabled != flag) {
496 mGeolocationEnabled = flag;
502 * @return Returns if geolocation is currently enabled.
504 boolean getGeolocationEnabled() {
505 synchronized (mAwSettingsLock) {
506 return mGeolocationEnabled;
511 * See {@link android.webkit.WebSettings#setSaveFormData}.
513 public void setSaveFormData(final boolean enable) {
514 synchronized (mAwSettingsLock) {
515 if (mAutoCompleteEnabled != enable) {
516 mAutoCompleteEnabled = enable;
517 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
520 if (mNativeAwSettings != 0) {
521 nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
530 * See {@link android.webkit.WebSettings#getSaveFormData}.
532 public boolean getSaveFormData() {
533 synchronized (mAwSettingsLock) {
534 return getSaveFormDataLocked();
539 private boolean getSaveFormDataLocked() {
540 assert Thread.holdsLock(mAwSettingsLock);
541 return mAutoCompleteEnabled;
545 * @returns the default User-Agent used by each ContentViewCore instance, i.e. unless
546 * overridden by {@link #setUserAgentString()}
548 public static String getDefaultUserAgent() {
549 return LazyDefaultUserAgent.sInstance;
553 * See {@link android.webkit.WebSettings#setUserAgentString}.
555 public void setUserAgentString(String ua) {
556 synchronized (mAwSettingsLock) {
557 final String oldUserAgent = mUserAgent;
558 if (ua == null || ua.length() == 0) {
559 mUserAgent = LazyDefaultUserAgent.sInstance;
563 if (!oldUserAgent.equals(mUserAgent)) {
564 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
567 if (mNativeAwSettings != 0) {
568 nativeUpdateUserAgentLocked(mNativeAwSettings);
577 * See {@link android.webkit.WebSettings#getUserAgentString}.
579 public String getUserAgentString() {
580 synchronized (mAwSettingsLock) {
581 return getUserAgentLocked();
586 private String getUserAgentLocked() {
587 assert Thread.holdsLock(mAwSettingsLock);
592 * See {@link android.webkit.WebSettings#setLoadWithOverviewMode}.
594 public void setLoadWithOverviewMode(boolean overview) {
595 synchronized (mAwSettingsLock) {
596 if (mLoadWithOverviewMode != overview) {
597 mLoadWithOverviewMode = overview;
598 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
601 if (mNativeAwSettings != 0) {
602 updateWebkitPreferencesOnUiThreadLocked();
603 nativeResetScrollAndScaleState(mNativeAwSettings);
612 * See {@link android.webkit.WebSettings#getLoadWithOverviewMode}.
614 public boolean getLoadWithOverviewMode() {
615 synchronized (mAwSettingsLock) {
616 return getLoadWithOverviewModeLocked();
621 private boolean getLoadWithOverviewModeLocked() {
622 assert Thread.holdsLock(mAwSettingsLock);
623 return mLoadWithOverviewMode;
627 * See {@link android.webkit.WebSettings#setTextZoom}.
629 public void setTextZoom(final int textZoom) {
630 synchronized (mAwSettingsLock) {
631 if (mTextSizePercent != textZoom) {
632 mTextSizePercent = textZoom;
633 mEventHandler.updateWebkitPreferencesLocked();
639 * See {@link android.webkit.WebSettings#getTextZoom}.
641 public int getTextZoom() {
642 synchronized (mAwSettingsLock) {
643 return getTextSizePercentLocked();
648 private int getTextSizePercentLocked() {
649 assert Thread.holdsLock(mAwSettingsLock);
650 return mTextSizePercent;
654 * See {@link android.webkit.WebSettings#setStandardFontFamily}.
656 public void setStandardFontFamily(String font) {
657 synchronized (mAwSettingsLock) {
658 if (font != null && !mStandardFontFamily.equals(font)) {
659 mStandardFontFamily = font;
660 mEventHandler.updateWebkitPreferencesLocked();
666 * See {@link android.webkit.WebSettings#getStandardFontFamily}.
668 public String getStandardFontFamily() {
669 synchronized (mAwSettingsLock) {
670 return getStandardFontFamilyLocked();
675 private String getStandardFontFamilyLocked() {
676 assert Thread.holdsLock(mAwSettingsLock);
677 return mStandardFontFamily;
681 * See {@link android.webkit.WebSettings#setFixedFontFamily}.
683 public void setFixedFontFamily(String font) {
684 synchronized (mAwSettingsLock) {
685 if (font != null && !mFixedFontFamily.equals(font)) {
686 mFixedFontFamily = font;
687 mEventHandler.updateWebkitPreferencesLocked();
693 * See {@link android.webkit.WebSettings#getFixedFontFamily}.
695 public String getFixedFontFamily() {
696 synchronized (mAwSettingsLock) {
697 return getFixedFontFamilyLocked();
702 private String getFixedFontFamilyLocked() {
703 assert Thread.holdsLock(mAwSettingsLock);
704 return mFixedFontFamily;
708 * See {@link android.webkit.WebSettings#setSansSerifFontFamily}.
710 public void setSansSerifFontFamily(String font) {
711 synchronized (mAwSettingsLock) {
712 if (font != null && !mSansSerifFontFamily.equals(font)) {
713 mSansSerifFontFamily = font;
714 mEventHandler.updateWebkitPreferencesLocked();
720 * See {@link android.webkit.WebSettings#getSansSerifFontFamily}.
722 public String getSansSerifFontFamily() {
723 synchronized (mAwSettingsLock) {
724 return getSansSerifFontFamilyLocked();
729 private String getSansSerifFontFamilyLocked() {
730 assert Thread.holdsLock(mAwSettingsLock);
731 return mSansSerifFontFamily;
735 * See {@link android.webkit.WebSettings#setSerifFontFamily}.
737 public void setSerifFontFamily(String font) {
738 synchronized (mAwSettingsLock) {
739 if (font != null && !mSerifFontFamily.equals(font)) {
740 mSerifFontFamily = font;
741 mEventHandler.updateWebkitPreferencesLocked();
747 * See {@link android.webkit.WebSettings#getSerifFontFamily}.
749 public String getSerifFontFamily() {
750 synchronized (mAwSettingsLock) {
751 return getSerifFontFamilyLocked();
756 private String getSerifFontFamilyLocked() {
757 assert Thread.holdsLock(mAwSettingsLock);
758 return mSerifFontFamily;
762 * See {@link android.webkit.WebSettings#setCursiveFontFamily}.
764 public void setCursiveFontFamily(String font) {
765 synchronized (mAwSettingsLock) {
766 if (font != null && !mCursiveFontFamily.equals(font)) {
767 mCursiveFontFamily = font;
768 mEventHandler.updateWebkitPreferencesLocked();
774 * See {@link android.webkit.WebSettings#getCursiveFontFamily}.
776 public String getCursiveFontFamily() {
777 synchronized (mAwSettingsLock) {
778 return getCursiveFontFamilyLocked();
783 private String getCursiveFontFamilyLocked() {
784 assert Thread.holdsLock(mAwSettingsLock);
785 return mCursiveFontFamily;
789 * See {@link android.webkit.WebSettings#setFantasyFontFamily}.
791 public void setFantasyFontFamily(String font) {
792 synchronized (mAwSettingsLock) {
793 if (font != null && !mFantasyFontFamily.equals(font)) {
794 mFantasyFontFamily = font;
795 mEventHandler.updateWebkitPreferencesLocked();
801 * See {@link android.webkit.WebSettings#getFantasyFontFamily}.
803 public String getFantasyFontFamily() {
804 synchronized (mAwSettingsLock) {
805 return getFantasyFontFamilyLocked();
810 private String getFantasyFontFamilyLocked() {
811 assert Thread.holdsLock(mAwSettingsLock);
812 return mFantasyFontFamily;
816 * See {@link android.webkit.WebSettings#setMinimumFontSize}.
818 public void setMinimumFontSize(int size) {
819 synchronized (mAwSettingsLock) {
820 size = clipFontSize(size);
821 if (mMinimumFontSize != size) {
822 mMinimumFontSize = size;
823 mEventHandler.updateWebkitPreferencesLocked();
829 * See {@link android.webkit.WebSettings#getMinimumFontSize}.
831 public int getMinimumFontSize() {
832 synchronized (mAwSettingsLock) {
833 return getMinimumFontSizeLocked();
838 private int getMinimumFontSizeLocked() {
839 assert Thread.holdsLock(mAwSettingsLock);
840 return mMinimumFontSize;
844 * See {@link android.webkit.WebSettings#setMinimumLogicalFontSize}.
846 public void setMinimumLogicalFontSize(int size) {
847 synchronized (mAwSettingsLock) {
848 size = clipFontSize(size);
849 if (mMinimumLogicalFontSize != size) {
850 mMinimumLogicalFontSize = size;
851 mEventHandler.updateWebkitPreferencesLocked();
857 * See {@link android.webkit.WebSettings#getMinimumLogicalFontSize}.
859 public int getMinimumLogicalFontSize() {
860 synchronized (mAwSettingsLock) {
861 return getMinimumLogicalFontSizeLocked();
866 private int getMinimumLogicalFontSizeLocked() {
867 assert Thread.holdsLock(mAwSettingsLock);
868 return mMinimumLogicalFontSize;
872 * See {@link android.webkit.WebSettings#setDefaultFontSize}.
874 public void setDefaultFontSize(int size) {
875 synchronized (mAwSettingsLock) {
876 size = clipFontSize(size);
877 if (mDefaultFontSize != size) {
878 mDefaultFontSize = size;
879 mEventHandler.updateWebkitPreferencesLocked();
885 * See {@link android.webkit.WebSettings#getDefaultFontSize}.
887 public int getDefaultFontSize() {
888 synchronized (mAwSettingsLock) {
889 return getDefaultFontSizeLocked();
894 private int getDefaultFontSizeLocked() {
895 assert Thread.holdsLock(mAwSettingsLock);
896 return mDefaultFontSize;
900 * See {@link android.webkit.WebSettings#setDefaultFixedFontSize}.
902 public void setDefaultFixedFontSize(int size) {
903 synchronized (mAwSettingsLock) {
904 size = clipFontSize(size);
905 if (mDefaultFixedFontSize != size) {
906 mDefaultFixedFontSize = size;
907 mEventHandler.updateWebkitPreferencesLocked();
913 * See {@link android.webkit.WebSettings#getDefaultFixedFontSize}.
915 public int getDefaultFixedFontSize() {
916 synchronized (mAwSettingsLock) {
917 return getDefaultFixedFontSizeLocked();
922 private int getDefaultFixedFontSizeLocked() {
923 assert Thread.holdsLock(mAwSettingsLock);
924 return mDefaultFixedFontSize;
928 * See {@link android.webkit.WebSettings#setJavaScriptEnabled}.
930 public void setJavaScriptEnabled(boolean flag) {
931 synchronized (mAwSettingsLock) {
932 if (mJavaScriptEnabled != flag) {
933 mJavaScriptEnabled = flag;
934 mEventHandler.updateWebkitPreferencesLocked();
940 * See {@link android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs}.
942 public void setAllowUniversalAccessFromFileURLs(boolean flag) {
943 synchronized (mAwSettingsLock) {
944 if (mAllowUniversalAccessFromFileURLs != flag) {
945 mAllowUniversalAccessFromFileURLs = flag;
946 mEventHandler.updateWebkitPreferencesLocked();
952 * See {@link android.webkit.WebSettings#setAllowFileAccessFromFileURLs}.
954 public void setAllowFileAccessFromFileURLs(boolean flag) {
955 synchronized (mAwSettingsLock) {
956 if (mAllowFileAccessFromFileURLs != flag) {
957 mAllowFileAccessFromFileURLs = flag;
958 mEventHandler.updateWebkitPreferencesLocked();
964 * See {@link android.webkit.WebSettings#setLoadsImagesAutomatically}.
966 public void setLoadsImagesAutomatically(boolean flag) {
967 synchronized (mAwSettingsLock) {
968 if (mLoadsImagesAutomatically != flag) {
969 mLoadsImagesAutomatically = flag;
970 mEventHandler.updateWebkitPreferencesLocked();
976 * See {@link android.webkit.WebSettings#getLoadsImagesAutomatically}.
978 public boolean getLoadsImagesAutomatically() {
979 synchronized (mAwSettingsLock) {
980 return getLoadsImagesAutomaticallyLocked();
985 private boolean getLoadsImagesAutomaticallyLocked() {
986 assert Thread.holdsLock(mAwSettingsLock);
987 return mLoadsImagesAutomatically;
991 * See {@link android.webkit.WebSettings#setImagesEnabled}.
993 public void setImagesEnabled(boolean flag) {
994 synchronized (mAwSettingsLock) {
995 if (mImagesEnabled != flag) {
996 mImagesEnabled = flag;
997 mEventHandler.updateWebkitPreferencesLocked();
1003 * See {@link android.webkit.WebSettings#getImagesEnabled}.
1005 public boolean getImagesEnabled() {
1006 synchronized (mAwSettingsLock) {
1007 return mImagesEnabled;
1012 private boolean getImagesEnabledLocked() {
1013 assert Thread.holdsLock(mAwSettingsLock);
1014 return mImagesEnabled;
1018 * See {@link android.webkit.WebSettings#getJavaScriptEnabled}.
1020 public boolean getJavaScriptEnabled() {
1021 synchronized (mAwSettingsLock) {
1022 return mJavaScriptEnabled;
1027 private boolean getJavaScriptEnabledLocked() {
1028 assert Thread.holdsLock(mAwSettingsLock);
1029 return mJavaScriptEnabled;
1033 * See {@link android.webkit.WebSettings#getAllowUniversalAccessFromFileURLs}.
1035 public boolean getAllowUniversalAccessFromFileURLs() {
1036 synchronized (mAwSettingsLock) {
1037 return getAllowUniversalAccessFromFileURLsLocked();
1042 private boolean getAllowUniversalAccessFromFileURLsLocked() {
1043 assert Thread.holdsLock(mAwSettingsLock);
1044 return mAllowUniversalAccessFromFileURLs;
1048 * See {@link android.webkit.WebSettings#getAllowFileAccessFromFileURLs}.
1050 public boolean getAllowFileAccessFromFileURLs() {
1051 synchronized (mAwSettingsLock) {
1052 return getAllowFileAccessFromFileURLsLocked();
1057 private boolean getAllowFileAccessFromFileURLsLocked() {
1058 assert Thread.holdsLock(mAwSettingsLock);
1059 return mAllowFileAccessFromFileURLs;
1063 * See {@link android.webkit.WebSettings#setPluginsEnabled}.
1065 public void setPluginsEnabled(boolean flag) {
1066 setPluginState(flag ? PluginState.ON : PluginState.OFF);
1070 * See {@link android.webkit.WebSettings#setPluginState}.
1072 public void setPluginState(PluginState state) {
1073 synchronized (mAwSettingsLock) {
1074 if (mPluginState != state) {
1075 mPluginState = state;
1076 mEventHandler.updateWebkitPreferencesLocked();
1082 * See {@link android.webkit.WebSettings#getPluginsEnabled}.
1084 public boolean getPluginsEnabled() {
1085 synchronized (mAwSettingsLock) {
1086 return mPluginState == PluginState.ON;
1091 * Return true if plugins are disabled.
1092 * @return True if plugins are disabled.
1095 private boolean getPluginsDisabledLocked() {
1096 assert Thread.holdsLock(mAwSettingsLock);
1097 return mPluginState == PluginState.OFF;
1101 * See {@link android.webkit.WebSettings#getPluginState}.
1103 public PluginState getPluginState() {
1104 synchronized (mAwSettingsLock) {
1105 return mPluginState;
1111 * See {@link android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically}.
1113 public void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
1114 synchronized (mAwSettingsLock) {
1115 if (mJavaScriptCanOpenWindowsAutomatically != flag) {
1116 mJavaScriptCanOpenWindowsAutomatically = flag;
1117 mEventHandler.updateWebkitPreferencesLocked();
1123 * See {@link android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically}.
1125 public boolean getJavaScriptCanOpenWindowsAutomatically() {
1126 synchronized (mAwSettingsLock) {
1127 return getJavaScriptCanOpenWindowsAutomaticallyLocked();
1132 private boolean getJavaScriptCanOpenWindowsAutomaticallyLocked() {
1133 assert Thread.holdsLock(mAwSettingsLock);
1134 return mJavaScriptCanOpenWindowsAutomatically;
1138 * See {@link android.webkit.WebSettings#setLayoutAlgorithm}.
1140 public void setLayoutAlgorithm(LayoutAlgorithm l) {
1141 synchronized (mAwSettingsLock) {
1142 if (mLayoutAlgorithm != l) {
1143 mLayoutAlgorithm = l;
1144 mEventHandler.updateWebkitPreferencesLocked();
1150 * See {@link android.webkit.WebSettings#getLayoutAlgorithm}.
1152 public LayoutAlgorithm getLayoutAlgorithm() {
1153 synchronized (mAwSettingsLock) {
1154 return mLayoutAlgorithm;
1159 * Gets whether Text Auto-sizing layout algorithm is enabled.
1161 * @return true if Text Auto-sizing layout algorithm is enabled
1164 private boolean getTextAutosizingEnabledLocked() {
1165 assert Thread.holdsLock(mAwSettingsLock);
1166 return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING;
1170 * See {@link android.webkit.WebSettings#setSupportMultipleWindows}.
1172 public void setSupportMultipleWindows(boolean support) {
1173 synchronized (mAwSettingsLock) {
1174 if (mSupportMultipleWindows != support) {
1175 mSupportMultipleWindows = support;
1176 mEventHandler.updateWebkitPreferencesLocked();
1182 * See {@link android.webkit.WebSettings#supportMultipleWindows}.
1184 public boolean supportMultipleWindows() {
1185 synchronized (mAwSettingsLock) {
1186 return mSupportMultipleWindows;
1191 private boolean getSupportMultipleWindowsLocked() {
1192 assert Thread.holdsLock(mAwSettingsLock);
1193 return mSupportMultipleWindows;
1197 private boolean getSupportLegacyQuirksLocked() {
1198 assert Thread.holdsLock(mAwSettingsLock);
1199 return mSupportLegacyQuirks;
1203 * See {@link android.webkit.WebSettings#setUseWideViewPort}.
1205 public void setUseWideViewPort(boolean use) {
1206 synchronized (mAwSettingsLock) {
1207 if (mUseWideViewport != use) {
1208 mUseWideViewport = use;
1209 onGestureZoomSupportChanged(
1210 supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1211 mEventHandler.updateWebkitPreferencesLocked();
1217 * See {@link android.webkit.WebSettings#getUseWideViewPort}.
1219 public boolean getUseWideViewPort() {
1220 synchronized (mAwSettingsLock) {
1221 return getUseWideViewportLocked();
1226 private boolean getUseWideViewportLocked() {
1227 assert Thread.holdsLock(mAwSettingsLock);
1228 return mUseWideViewport;
1231 public void setZeroLayoutHeightDisablesViewportQuirk(boolean enabled) {
1232 synchronized (mAwSettingsLock) {
1233 if (mZeroLayoutHeightDisablesViewportQuirk != enabled) {
1234 mZeroLayoutHeightDisablesViewportQuirk = enabled;
1235 mEventHandler.updateWebkitPreferencesLocked();
1240 public boolean getZeroLayoutHeightDisablesViewportQuirk() {
1241 synchronized (mAwSettingsLock) {
1242 return getZeroLayoutHeightDisablesViewportQuirkLocked();
1247 private boolean getZeroLayoutHeightDisablesViewportQuirkLocked() {
1248 assert Thread.holdsLock(mAwSettingsLock);
1249 return mZeroLayoutHeightDisablesViewportQuirk;
1252 public void setForceZeroLayoutHeight(boolean enabled) {
1253 synchronized (mAwSettingsLock) {
1254 if (mForceZeroLayoutHeight != enabled) {
1255 mForceZeroLayoutHeight = enabled;
1256 mEventHandler.updateWebkitPreferencesLocked();
1261 public boolean getForceZeroLayoutHeight() {
1262 synchronized (mAwSettingsLock) {
1263 return getForceZeroLayoutHeightLocked();
1268 private boolean getForceZeroLayoutHeightLocked() {
1269 assert Thread.holdsLock(mAwSettingsLock);
1270 return mForceZeroLayoutHeight;
1274 private boolean getPasswordEchoEnabledLocked() {
1275 assert Thread.holdsLock(mAwSettingsLock);
1276 return mPasswordEchoEnabled;
1280 * See {@link android.webkit.WebSettings#setAppCacheEnabled}.
1282 public void setAppCacheEnabled(boolean flag) {
1283 synchronized (mAwSettingsLock) {
1284 if (mAppCacheEnabled != flag) {
1285 mAppCacheEnabled = flag;
1286 mEventHandler.updateWebkitPreferencesLocked();
1292 * See {@link android.webkit.WebSettings#setAppCachePath}.
1294 public void setAppCachePath(String path) {
1295 boolean needToSync = false;
1296 synchronized (sGlobalContentSettingsLock) {
1297 // AppCachePath can only be set once.
1298 if (!sAppCachePathIsSet && path != null && !path.isEmpty()) {
1299 sAppCachePathIsSet = true;
1303 // The obvious problem here is that other WebViews will not be updated,
1304 // until they execute synchronization from Java to the native side.
1305 // But this is the same behaviour as it was in the legacy WebView.
1307 synchronized (mAwSettingsLock) {
1308 mEventHandler.updateWebkitPreferencesLocked();
1314 * Gets whether Application Cache is enabled.
1316 * @return true if Application Cache is enabled
1319 private boolean getAppCacheEnabledLocked() {
1320 assert Thread.holdsLock(mAwSettingsLock);
1321 if (!mAppCacheEnabled) {
1324 synchronized (sGlobalContentSettingsLock) {
1325 return sAppCachePathIsSet;
1330 * See {@link android.webkit.WebSettings#setDomStorageEnabled}.
1332 public void setDomStorageEnabled(boolean flag) {
1333 synchronized (mAwSettingsLock) {
1334 if (mDomStorageEnabled != flag) {
1335 mDomStorageEnabled = flag;
1336 mEventHandler.updateWebkitPreferencesLocked();
1342 * See {@link android.webkit.WebSettings#getDomStorageEnabled}.
1344 public boolean getDomStorageEnabled() {
1345 synchronized (mAwSettingsLock) {
1346 return mDomStorageEnabled;
1351 private boolean getDomStorageEnabledLocked() {
1352 assert Thread.holdsLock(mAwSettingsLock);
1353 return mDomStorageEnabled;
1357 * See {@link android.webkit.WebSettings#setDatabaseEnabled}.
1359 public void setDatabaseEnabled(boolean flag) {
1360 synchronized (mAwSettingsLock) {
1361 if (mDatabaseEnabled != flag) {
1362 mDatabaseEnabled = flag;
1363 mEventHandler.updateWebkitPreferencesLocked();
1369 * See {@link android.webkit.WebSettings#getDatabaseEnabled}.
1371 public boolean getDatabaseEnabled() {
1372 synchronized (mAwSettingsLock) {
1373 return mDatabaseEnabled;
1378 private boolean getDatabaseEnabledLocked() {
1379 assert Thread.holdsLock(mAwSettingsLock);
1380 return mDatabaseEnabled;
1384 * See {@link android.webkit.WebSettings#setDefaultTextEncodingName}.
1386 public void setDefaultTextEncodingName(String encoding) {
1387 synchronized (mAwSettingsLock) {
1388 if (encoding != null && !mDefaultTextEncoding.equals(encoding)) {
1389 mDefaultTextEncoding = encoding;
1390 mEventHandler.updateWebkitPreferencesLocked();
1396 * See {@link android.webkit.WebSettings#getDefaultTextEncodingName}.
1398 public String getDefaultTextEncodingName() {
1399 synchronized (mAwSettingsLock) {
1400 return getDefaultTextEncodingLocked();
1405 private String getDefaultTextEncodingLocked() {
1406 assert Thread.holdsLock(mAwSettingsLock);
1407 return mDefaultTextEncoding;
1411 * See {@link android.webkit.WebSettings#setMediaPlaybackRequiresUserGesture}.
1413 public void setMediaPlaybackRequiresUserGesture(boolean require) {
1414 synchronized (mAwSettingsLock) {
1415 if (mMediaPlaybackRequiresUserGesture != require) {
1416 mMediaPlaybackRequiresUserGesture = require;
1417 mEventHandler.updateWebkitPreferencesLocked();
1423 * See {@link android.webkit.WebSettings#getMediaPlaybackRequiresUserGesture}.
1425 public boolean getMediaPlaybackRequiresUserGesture() {
1426 synchronized (mAwSettingsLock) {
1427 return getMediaPlaybackRequiresUserGestureLocked();
1432 private boolean getMediaPlaybackRequiresUserGestureLocked() {
1433 assert Thread.holdsLock(mAwSettingsLock);
1434 return mMediaPlaybackRequiresUserGesture;
1438 * See {@link android.webkit.WebSettings#setDefaultVideoPosterURL}.
1440 public void setDefaultVideoPosterURL(String url) {
1441 synchronized (mAwSettingsLock) {
1442 if (mDefaultVideoPosterURL != null && !mDefaultVideoPosterURL.equals(url) ||
1443 mDefaultVideoPosterURL == null && url != null) {
1444 mDefaultVideoPosterURL = url;
1445 mEventHandler.updateWebkitPreferencesLocked();
1451 * See {@link android.webkit.WebSettings#getDefaultVideoPosterURL}.
1453 public String getDefaultVideoPosterURL() {
1454 synchronized (mAwSettingsLock) {
1455 return getDefaultVideoPosterURLLocked();
1460 private String getDefaultVideoPosterURLLocked() {
1461 assert Thread.holdsLock(mAwSettingsLock);
1462 return mDefaultVideoPosterURL;
1465 private void onGestureZoomSupportChanged(
1466 final boolean supportsDoubleTapZoom, final boolean supportsMultiTouchZoom) {
1467 // Always post asynchronously here, to avoid doubling back onto the caller.
1468 mEventHandler.maybePostOnUiThread(new Runnable() {
1471 synchronized (mAwSettingsLock) {
1472 if (mZoomChangeListener != null) {
1473 mZoomChangeListener.onGestureZoomSupportChanged(
1474 supportsDoubleTapZoom, supportsMultiTouchZoom);
1482 * See {@link android.webkit.WebSettings#setSupportZoom}.
1484 public void setSupportZoom(boolean support) {
1485 synchronized (mAwSettingsLock) {
1486 if (mSupportZoom != support) {
1487 mSupportZoom = support;
1488 onGestureZoomSupportChanged(
1489 supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1495 * See {@link android.webkit.WebSettings#supportZoom}.
1497 public boolean supportZoom() {
1498 synchronized (mAwSettingsLock) {
1499 return mSupportZoom;
1504 * See {@link android.webkit.WebSettings#setBuiltInZoomControls}.
1506 public void setBuiltInZoomControls(boolean enabled) {
1507 synchronized (mAwSettingsLock) {
1508 if (mBuiltInZoomControls != enabled) {
1509 mBuiltInZoomControls = enabled;
1510 onGestureZoomSupportChanged(
1511 supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1517 * See {@link android.webkit.WebSettings#getBuiltInZoomControls}.
1519 public boolean getBuiltInZoomControls() {
1520 synchronized (mAwSettingsLock) {
1521 return mBuiltInZoomControls;
1526 * See {@link android.webkit.WebSettings#setDisplayZoomControls}.
1528 public void setDisplayZoomControls(boolean enabled) {
1529 synchronized (mAwSettingsLock) {
1530 mDisplayZoomControls = enabled;
1535 * See {@link android.webkit.WebSettings#getDisplayZoomControls}.
1537 public boolean getDisplayZoomControls() {
1538 synchronized (mAwSettingsLock) {
1539 return mDisplayZoomControls;
1543 public void setMixedContentMode(int mode) {
1544 synchronized (mAwSettingsLock) {
1545 if (mMixedContentMode != mode) {
1546 mMixedContentMode = mode;
1547 mEventHandler.updateWebkitPreferencesLocked();
1552 public int getMixedContentMode() {
1553 synchronized (mAwSettingsLock) {
1554 return mMixedContentMode;
1559 private boolean getAllowRunningInsecureContentLocked() {
1560 assert Thread.holdsLock(mAwSettingsLock);
1561 return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW;
1565 private boolean getAllowDisplayingInsecureContentLocked() {
1566 assert Thread.holdsLock(mAwSettingsLock);
1567 return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW ||
1568 mMixedContentMode == MIXED_CONTENT_COMPATIBILITY_MODE;
1572 * Sets whether to use the video overlay for the embedded video.
1573 * @param flag whether to enable the video overlay for the embedded video.
1575 public void setVideoOverlayForEmbeddedVideoEnabled(final boolean enabled) {
1576 synchronized (mAwSettingsLock) {
1577 if (mVideoOverlayForEmbeddedVideoEnabled != enabled) {
1578 mVideoOverlayForEmbeddedVideoEnabled = enabled;
1579 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
1582 if (mNativeAwSettings != 0) {
1583 nativeUpdateRendererPreferencesLocked(mNativeAwSettings);
1592 * Gets whether to use the video overlay for the embedded video.
1593 * @return true if the WebView enables the video overlay for the embedded video.
1595 public boolean getVideoOverlayForEmbeddedVideoEnabled() {
1596 synchronized (mAwSettingsLock) {
1597 return getVideoOverlayForEmbeddedVideoEnabledLocked();
1602 private boolean getVideoOverlayForEmbeddedVideoEnabledLocked() {
1603 assert Thread.holdsLock(mAwSettingsLock);
1604 return mVideoOverlayForEmbeddedVideoEnabled;
1608 private boolean supportsDoubleTapZoomLocked() {
1609 assert Thread.holdsLock(mAwSettingsLock);
1610 return mSupportZoom && mBuiltInZoomControls && mUseWideViewport;
1613 private boolean supportsMultiTouchZoomLocked() {
1614 assert Thread.holdsLock(mAwSettingsLock);
1615 return mSupportZoom && mBuiltInZoomControls;
1618 boolean supportsMultiTouchZoom() {
1619 synchronized (mAwSettingsLock) {
1620 return supportsMultiTouchZoomLocked();
1624 boolean shouldDisplayZoomControls() {
1625 synchronized (mAwSettingsLock) {
1626 return supportsMultiTouchZoomLocked() && mDisplayZoomControls;
1630 private int clipFontSize(int size) {
1631 if (size < MINIMUM_FONT_SIZE) {
1632 return MINIMUM_FONT_SIZE;
1633 } else if (size > MAXIMUM_FONT_SIZE) {
1634 return MAXIMUM_FONT_SIZE;
1640 private void updateEverything() {
1641 synchronized (mAwSettingsLock) {
1642 updateEverythingLocked();
1647 private void populateWebPreferences(long webPrefsPtr) {
1648 synchronized (mAwSettingsLock) {
1649 assert mNativeAwSettings != 0;
1650 nativePopulateWebPreferencesLocked(mNativeAwSettings, webPrefsPtr);
1654 private void updateWebkitPreferencesOnUiThreadLocked() {
1655 assert mEventHandler.mHandler != null;
1656 ThreadUtils.assertOnUiThread();
1657 if (mNativeAwSettings != 0) {
1658 nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
1662 private native long nativeInit(long webContentsPtr);
1664 private native void nativeDestroy(long nativeAwSettings);
1666 private native void nativePopulateWebPreferencesLocked(long nativeAwSettings, long webPrefsPtr);
1668 private native void nativeResetScrollAndScaleState(long nativeAwSettings);
1670 private native void nativeUpdateEverythingLocked(long nativeAwSettings);
1672 private native void nativeUpdateInitialPageScaleLocked(long nativeAwSettings);
1674 private native void nativeUpdateUserAgentLocked(long nativeAwSettings);
1676 private native void nativeUpdateWebkitPreferencesLocked(long nativeAwSettings);
1678 private static native String nativeGetDefaultUserAgent();
1680 private native void nativeUpdateFormDataPreferencesLocked(long nativeAwSettings);
1682 private native void nativeUpdateRendererPreferencesLocked(long nativeAwSettings);