• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 package org.chromium.android_webview;
6 
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;
16 
17 import com.google.common.annotations.VisibleForTesting;
18 
19 import org.chromium.base.CalledByNative;
20 import org.chromium.base.JNINamespace;
21 import org.chromium.base.ThreadUtils;
22 
23 /**
24  * Stores Android WebView specific settings that does not need to be synced to WebKit.
25  * Use {@link org.chromium.content.browser.ContentSettings} for WebKit settings.
26  *
27  * Methods in this class can be called from any thread, including threads created by
28  * the client of WebView.
29  */
30 @JNINamespace("android_webview")
31 public class AwSettings {
32     // This enum corresponds to WebSettings.LayoutAlgorithm. We use our own to be
33     // able to extend it.
34     public enum LayoutAlgorithm {
35         NORMAL,
36         SINGLE_COLUMN,
37         NARROW_COLUMNS,
38         TEXT_AUTOSIZING,
39     }
40 
41     // These constants must be kept in sync with the Android framework, defined in WebSettimgs.
42     @VisibleForTesting
43     public static final int MIXED_CONTENT_ALWAYS_ALLOW = 0;
44     @VisibleForTesting
45     public static final int MIXED_CONTENT_NEVER_ALLOW = 1;
46     @VisibleForTesting
47     public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2;
48 
49     private static final String TAG = "AwSettings";
50 
51     // This class must be created on the UI thread. Afterwards, it can be
52     // used from any thread. Internally, the class uses a message queue
53     // to call native code on the UI thread only.
54 
55     // Values passed in on construction.
56     private final boolean mHasInternetPermission;
57 
58     private ZoomSupportChangeListener mZoomChangeListener;
59     private double mDIPScale = 1.0;
60 
61     // Lock to protect all settings.
62     private final Object mAwSettingsLock = new Object();
63 
64     private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
65     private int mTextSizePercent = 100;
66     private String mStandardFontFamily = "sans-serif";
67     private String mFixedFontFamily = "monospace";
68     private String mSansSerifFontFamily = "sans-serif";
69     private String mSerifFontFamily = "serif";
70     private String mCursiveFontFamily = "cursive";
71     private String mFantasyFontFamily = "fantasy";
72     private String mDefaultTextEncoding;
73     private String mUserAgent;
74     private int mMinimumFontSize = 8;
75     private int mMinimumLogicalFontSize = 8;
76     private int mDefaultFontSize = 16;
77     private int mDefaultFixedFontSize = 13;
78     private boolean mLoadsImagesAutomatically = true;
79     private boolean mImagesEnabled = true;
80     private boolean mJavaScriptEnabled = false;
81     private boolean mAllowUniversalAccessFromFileURLs = false;
82     private boolean mAllowFileAccessFromFileURLs = false;
83     private boolean mJavaScriptCanOpenWindowsAutomatically = false;
84     private boolean mSupportMultipleWindows = false;
85     private PluginState mPluginState = PluginState.OFF;
86     private boolean mAppCacheEnabled = false;
87     private boolean mDomStorageEnabled = false;
88     private boolean mDatabaseEnabled = false;
89     private boolean mUseWideViewport = false;
90     private boolean mZeroLayoutHeightDisablesViewportQuirk = false;
91     private boolean mForceZeroLayoutHeight = false;
92     private boolean mLoadWithOverviewMode = false;
93     private boolean mMediaPlaybackRequiresUserGesture = true;
94     private String mDefaultVideoPosterURL;
95     private float mInitialPageScalePercent = 0;
96     private boolean mSpatialNavigationEnabled;  // Default depends on device features.
97     private boolean mEnableSupportedHardwareAcceleratedFeatures = false;
98     private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW;
99     private boolean mVideoOverlayForEmbeddedVideoEnabled = false;
100 
101     // Although this bit is stored on AwSettings it is actually controlled via the CookieManager.
102     private boolean mAcceptThirdPartyCookies;
103 
104     private final boolean mSupportLegacyQuirks;
105 
106     private final boolean mPasswordEchoEnabled;
107 
108     // Not accessed by the native side.
109     private boolean mBlockNetworkLoads;  // Default depends on permission of embedding APK.
110     private boolean mAllowContentUrlAccess = true;
111     private boolean mAllowFileUrlAccess = true;
112     private int mCacheMode = WebSettings.LOAD_DEFAULT;
113     private boolean mShouldFocusFirstNode = true;
114     private boolean mGeolocationEnabled = true;
115     private boolean mAutoCompleteEnabled = true;
116     private boolean mFullscreenSupported = false;
117     private boolean mSupportZoom = true;
118     private boolean mBuiltInZoomControls = false;
119     private boolean mDisplayZoomControls = true;
120 
121     static class LazyDefaultUserAgent{
122         // Lazy Holder pattern
123         private static final String sInstance = nativeGetDefaultUserAgent();
124     }
125 
126     // Protects access to settings global fields.
127     private static final Object sGlobalContentSettingsLock = new Object();
128     // For compatibility with the legacy WebView, we can only enable AppCache when the path is
129     // provided. However, we don't use the path, so we just check if we have received it from the
130     // client.
131     private static boolean sAppCachePathIsSet = false;
132 
133     // The native side of this object. It's lifetime is bounded by the WebContent it is attached to.
134     private long mNativeAwSettings = 0;
135 
136     // Custom handler that queues messages to call native code on the UI thread.
137     private final EventHandler mEventHandler;
138 
139     private static final int MINIMUM_FONT_SIZE = 1;
140     private static final int MAXIMUM_FONT_SIZE = 72;
141 
142     // Class to handle messages to be processed on the UI thread.
143     private class EventHandler {
144         // Message id for running a Runnable with mAwSettingsLock held.
145         private static final int RUN_RUNNABLE_BLOCKING = 0;
146         // Actual UI thread handler
147         private Handler mHandler;
148         // Synchronization flag.
149         private boolean mSynchronizationPending = false;
150 
EventHandler()151         EventHandler() {
152         }
153 
bindUiThread()154         void bindUiThread() {
155             if (mHandler != null) return;
156             mHandler = new Handler(ThreadUtils.getUiThreadLooper()) {
157                 @Override
158                 public void handleMessage(Message msg) {
159                     switch (msg.what) {
160                         case RUN_RUNNABLE_BLOCKING:
161                             synchronized (mAwSettingsLock) {
162                                 if (mNativeAwSettings != 0) {
163                                     ((Runnable)msg.obj).run();
164                                 }
165                                 mSynchronizationPending = false;
166                                 mAwSettingsLock.notifyAll();
167                             }
168                             break;
169                     }
170                 }
171             };
172         }
173 
runOnUiThreadBlockingAndLocked(Runnable r)174         void runOnUiThreadBlockingAndLocked(Runnable r) {
175             assert Thread.holdsLock(mAwSettingsLock);
176             if (mHandler == null) return;
177             if (ThreadUtils.runningOnUiThread()) {
178                 r.run();
179             } else {
180                 assert !mSynchronizationPending;
181                 mSynchronizationPending = true;
182                 mHandler.sendMessage(Message.obtain(null, RUN_RUNNABLE_BLOCKING, r));
183                 try {
184                     while (mSynchronizationPending) {
185                         mAwSettingsLock.wait();
186                     }
187                 } catch (InterruptedException e) {
188                     Log.e(TAG, "Interrupted waiting a Runnable to complete", e);
189                     mSynchronizationPending = false;
190                 }
191             }
192         }
193 
maybePostOnUiThread(Runnable r)194         void maybePostOnUiThread(Runnable r) {
195             if (mHandler != null) {
196                 mHandler.post(r);
197             }
198         }
199 
updateWebkitPreferencesLocked()200         void updateWebkitPreferencesLocked() {
201             runOnUiThreadBlockingAndLocked(new Runnable() {
202                 @Override
203                 public void run() {
204                     updateWebkitPreferencesOnUiThreadLocked();
205                 }
206             });
207         }
208     }
209 
210     interface ZoomSupportChangeListener {
onGestureZoomSupportChanged( boolean supportsDoubleTapZoom, boolean supportsMultiTouchZoom)211         public void onGestureZoomSupportChanged(
212                 boolean supportsDoubleTapZoom, boolean supportsMultiTouchZoom);
213     }
214 
AwSettings(Context context, boolean isAccessFromFileURLsGrantedByDefault, boolean supportsLegacyQuirks)215     public AwSettings(Context context,
216             boolean isAccessFromFileURLsGrantedByDefault,
217             boolean supportsLegacyQuirks) {
218        boolean hasInternetPermission = context.checkPermission(
219                     android.Manifest.permission.INTERNET,
220                     Process.myPid(),
221                     Process.myUid()) == PackageManager.PERMISSION_GRANTED;
222         synchronized (mAwSettingsLock) {
223             mHasInternetPermission = hasInternetPermission;
224             mBlockNetworkLoads = !hasInternetPermission;
225             mEventHandler = new EventHandler();
226             if (isAccessFromFileURLsGrantedByDefault) {
227                 mAllowUniversalAccessFromFileURLs = true;
228                 mAllowFileAccessFromFileURLs = true;
229             }
230 
231             mDefaultTextEncoding = AwResource.getDefaultTextEncoding();
232             mUserAgent = LazyDefaultUserAgent.sInstance;
233 
234             // Best-guess a sensible initial value based on the features supported on the device.
235             mSpatialNavigationEnabled = !context.getPackageManager().hasSystemFeature(
236                     PackageManager.FEATURE_TOUCHSCREEN);
237 
238             // Respect the system setting for password echoing.
239             mPasswordEchoEnabled = Settings.System.getInt(context.getContentResolver(),
240                     Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
241 
242             // By default, scale the text size by the system font scale factor. Embedders
243             // may override this by invoking setTextZoom().
244             mTextSizePercent *= context.getResources().getConfiguration().fontScale;
245 
246             mSupportLegacyQuirks = supportsLegacyQuirks;
247         }
248         // Defer initializing the native side until a native WebContents instance is set.
249     }
250 
251     @CalledByNative
nativeAwSettingsGone(long nativeAwSettings)252     private void nativeAwSettingsGone(long nativeAwSettings) {
253         assert mNativeAwSettings != 0 && mNativeAwSettings == nativeAwSettings;
254         mNativeAwSettings = 0;
255     }
256 
257     @CalledByNative
getDIPScaleLocked()258     private double getDIPScaleLocked() {
259         assert Thread.holdsLock(mAwSettingsLock);
260         return mDIPScale;
261     }
262 
setDIPScale(double dipScale)263     void setDIPScale(double dipScale) {
264         synchronized (mAwSettingsLock) {
265             mDIPScale = dipScale;
266             // TODO(joth): This should also be synced over to native side, but right now
267             // the setDIPScale call is always followed by a setWebContents() which covers this.
268         }
269     }
270 
setZoomListener(ZoomSupportChangeListener zoomChangeListener)271     void setZoomListener(ZoomSupportChangeListener zoomChangeListener) {
272         synchronized (mAwSettingsLock) {
273             mZoomChangeListener = zoomChangeListener;
274         }
275     }
276 
setWebContents(long nativeWebContents)277     void setWebContents(long nativeWebContents) {
278         synchronized (mAwSettingsLock) {
279             if (mNativeAwSettings != 0) {
280                 nativeDestroy(mNativeAwSettings);
281                 assert mNativeAwSettings == 0;  // nativeAwSettingsGone should have been called.
282             }
283             if (nativeWebContents != 0) {
284                 mEventHandler.bindUiThread();
285                 mNativeAwSettings = nativeInit(nativeWebContents);
286                 updateEverythingLocked();
287             }
288         }
289     }
290 
updateEverythingLocked()291     private void updateEverythingLocked() {
292         assert Thread.holdsLock(mAwSettingsLock);
293         assert mNativeAwSettings != 0;
294         nativeUpdateEverythingLocked(mNativeAwSettings);
295         onGestureZoomSupportChanged(
296                 supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
297     }
298 
299     /**
300      * See {@link android.webkit.WebSettings#setBlockNetworkLoads}.
301      */
setBlockNetworkLoads(boolean flag)302     public void setBlockNetworkLoads(boolean flag) {
303         synchronized (mAwSettingsLock) {
304             if (!flag && !mHasInternetPermission) {
305                 throw new SecurityException("Permission denied - " +
306                         "application missing INTERNET permission");
307             }
308             mBlockNetworkLoads = flag;
309         }
310     }
311 
312     /**
313      * See {@link android.webkit.WebSettings#getBlockNetworkLoads}.
314      */
getBlockNetworkLoads()315     public boolean getBlockNetworkLoads() {
316         synchronized (mAwSettingsLock) {
317             return mBlockNetworkLoads;
318         }
319     }
320 
321     /**
322      * Enable/disable third party cookies for an AwContents
323      * @param accept true if we should accept third party cookies
324      */
setAcceptThirdPartyCookies(boolean accept)325     public void setAcceptThirdPartyCookies(boolean accept) {
326         synchronized (mAwSettingsLock) {
327             if (mAcceptThirdPartyCookies != accept) {
328                 mAcceptThirdPartyCookies = accept;
329             }
330         }
331     }
332 
333     /**
334      * Return whether third party cookies are enabled for an AwContents
335      * @return true if accept third party cookies
336      */
getAcceptThirdPartyCookies()337     public boolean getAcceptThirdPartyCookies() {
338         synchronized (mAwSettingsLock) {
339             return mAcceptThirdPartyCookies;
340         }
341     }
342 
343     /**
344      * See {@link android.webkit.WebSettings#setAllowFileAccess}.
345      */
setAllowFileAccess(boolean allow)346     public void setAllowFileAccess(boolean allow) {
347         synchronized (mAwSettingsLock) {
348             if (mAllowFileUrlAccess != allow) {
349                 mAllowFileUrlAccess = allow;
350             }
351         }
352     }
353 
354     /**
355      * See {@link android.webkit.WebSettings#getAllowFileAccess}.
356      */
getAllowFileAccess()357     public boolean getAllowFileAccess() {
358         synchronized (mAwSettingsLock) {
359             return mAllowFileUrlAccess;
360         }
361     }
362 
363     /**
364      * See {@link android.webkit.WebSettings#setAllowContentAccess}.
365      */
setAllowContentAccess(boolean allow)366     public void setAllowContentAccess(boolean allow) {
367         synchronized (mAwSettingsLock) {
368             if (mAllowContentUrlAccess != allow) {
369                 mAllowContentUrlAccess = allow;
370             }
371         }
372     }
373 
374     /**
375      * See {@link android.webkit.WebSettings#getAllowContentAccess}.
376      */
getAllowContentAccess()377     public boolean getAllowContentAccess() {
378         synchronized (mAwSettingsLock) {
379             return mAllowContentUrlAccess;
380         }
381     }
382 
383     /**
384      * See {@link android.webkit.WebSettings#setCacheMode}.
385      */
setCacheMode(int mode)386     public void setCacheMode(int mode) {
387         synchronized (mAwSettingsLock) {
388             if (mCacheMode != mode) {
389                 mCacheMode = mode;
390             }
391         }
392     }
393 
394     /**
395      * See {@link android.webkit.WebSettings#getCacheMode}.
396      */
getCacheMode()397     public int getCacheMode() {
398         synchronized (mAwSettingsLock) {
399             return mCacheMode;
400         }
401     }
402 
403     /**
404      * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
405      */
setShouldFocusFirstNode(boolean flag)406     public void setShouldFocusFirstNode(boolean flag) {
407         synchronized (mAwSettingsLock) {
408             mShouldFocusFirstNode = flag;
409         }
410     }
411 
412     /**
413      * See {@link android.webkit.WebView#setInitialScale}.
414      */
setInitialPageScale(final float scaleInPercent)415     public void setInitialPageScale(final float scaleInPercent) {
416         synchronized (mAwSettingsLock) {
417             if (mInitialPageScalePercent != scaleInPercent) {
418                 mInitialPageScalePercent = scaleInPercent;
419                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
420                     @Override
421                     public void run() {
422                         if (mNativeAwSettings != 0) {
423                             nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
424                         }
425                     }
426                 });
427             }
428         }
429     }
430 
431     @CalledByNative
getInitialPageScalePercentLocked()432     private float getInitialPageScalePercentLocked() {
433         assert Thread.holdsLock(mAwSettingsLock);
434         return mInitialPageScalePercent;
435     }
436 
setSpatialNavigationEnabled(boolean enable)437     void setSpatialNavigationEnabled(boolean enable) {
438         synchronized (mAwSettingsLock) {
439             if (mSpatialNavigationEnabled != enable) {
440                 mSpatialNavigationEnabled = enable;
441                 mEventHandler.updateWebkitPreferencesLocked();
442             }
443         }
444     }
445 
446     @CalledByNative
getSpatialNavigationLocked()447     private boolean getSpatialNavigationLocked() {
448         assert Thread.holdsLock(mAwSettingsLock);
449         return mSpatialNavigationEnabled;
450     }
451 
setEnableSupportedHardwareAcceleratedFeatures(boolean enable)452     void setEnableSupportedHardwareAcceleratedFeatures(boolean enable) {
453         synchronized (mAwSettingsLock) {
454             if (mEnableSupportedHardwareAcceleratedFeatures != enable) {
455                 mEnableSupportedHardwareAcceleratedFeatures = enable;
456                 mEventHandler.updateWebkitPreferencesLocked();
457             }
458         }
459     }
460 
461     @CalledByNative
getEnableSupportedHardwareAcceleratedFeaturesLocked()462     private boolean getEnableSupportedHardwareAcceleratedFeaturesLocked() {
463         assert Thread.holdsLock(mAwSettingsLock);
464         return mEnableSupportedHardwareAcceleratedFeatures;
465     }
466 
setFullscreenSupported(boolean supported)467     public void setFullscreenSupported(boolean supported) {
468         synchronized (mAwSettingsLock) {
469             if (mFullscreenSupported != supported) {
470                 mFullscreenSupported = supported;
471                 mEventHandler.updateWebkitPreferencesLocked();
472             }
473         }
474     }
475 
476     @CalledByNative
getFullscreenSupportedLocked()477     private boolean getFullscreenSupportedLocked() {
478         assert Thread.holdsLock(mAwSettingsLock);
479         return mFullscreenSupported;
480     }
481 
482     /**
483      * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
484      */
shouldFocusFirstNode()485     public boolean shouldFocusFirstNode() {
486         synchronized (mAwSettingsLock) {
487             return mShouldFocusFirstNode;
488         }
489     }
490 
491     /**
492      * See {@link android.webkit.WebSettings#setGeolocationEnabled}.
493      */
setGeolocationEnabled(boolean flag)494     public void setGeolocationEnabled(boolean flag) {
495         synchronized (mAwSettingsLock) {
496             if (mGeolocationEnabled != flag) {
497                 mGeolocationEnabled = flag;
498             }
499         }
500     }
501 
502     /**
503      * @return Returns if geolocation is currently enabled.
504      */
getGeolocationEnabled()505     boolean getGeolocationEnabled() {
506         synchronized (mAwSettingsLock) {
507             return mGeolocationEnabled;
508         }
509     }
510 
511     /**
512      * See {@link android.webkit.WebSettings#setSaveFormData}.
513      */
setSaveFormData(final boolean enable)514     public void setSaveFormData(final boolean enable) {
515         synchronized (mAwSettingsLock) {
516             if (mAutoCompleteEnabled != enable) {
517                 mAutoCompleteEnabled = enable;
518                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
519                     @Override
520                     public void run() {
521                         if (mNativeAwSettings != 0) {
522                             nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
523                         }
524                     }
525                 });
526             }
527         }
528     }
529 
530     /**
531      * See {@link android.webkit.WebSettings#getSaveFormData}.
532      */
getSaveFormData()533     public boolean getSaveFormData() {
534         synchronized (mAwSettingsLock) {
535             return getSaveFormDataLocked();
536         }
537     }
538 
539     @CalledByNative
getSaveFormDataLocked()540     private boolean getSaveFormDataLocked() {
541         assert Thread.holdsLock(mAwSettingsLock);
542         return mAutoCompleteEnabled;
543     }
544 
545     /**
546      * @returns the default User-Agent used by each ContentViewCore instance, i.e. unless
547      * overridden by {@link #setUserAgentString()}
548      */
getDefaultUserAgent()549     public static String getDefaultUserAgent() {
550         return LazyDefaultUserAgent.sInstance;
551     }
552 
553     /**
554      * See {@link android.webkit.WebSettings#setUserAgentString}.
555      */
setUserAgentString(String ua)556     public void setUserAgentString(String ua) {
557         synchronized (mAwSettingsLock) {
558             final String oldUserAgent = mUserAgent;
559             if (ua == null || ua.length() == 0) {
560                 mUserAgent = LazyDefaultUserAgent.sInstance;
561             } else {
562                 mUserAgent = ua;
563             }
564             if (!oldUserAgent.equals(mUserAgent)) {
565                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
566                     @Override
567                     public void run() {
568                         if (mNativeAwSettings != 0) {
569                             nativeUpdateUserAgentLocked(mNativeAwSettings);
570                         }
571                     }
572                 });
573             }
574         }
575     }
576 
577     /**
578      * See {@link android.webkit.WebSettings#getUserAgentString}.
579      */
getUserAgentString()580     public String getUserAgentString() {
581         synchronized (mAwSettingsLock) {
582             return getUserAgentLocked();
583         }
584     }
585 
586     @CalledByNative
getUserAgentLocked()587     private String getUserAgentLocked() {
588         assert Thread.holdsLock(mAwSettingsLock);
589         return mUserAgent;
590     }
591 
592     /**
593      * See {@link android.webkit.WebSettings#setLoadWithOverviewMode}.
594      */
setLoadWithOverviewMode(boolean overview)595     public void setLoadWithOverviewMode(boolean overview) {
596         synchronized (mAwSettingsLock) {
597             if (mLoadWithOverviewMode != overview) {
598                 mLoadWithOverviewMode = overview;
599                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
600                     @Override
601                     public void run() {
602                         if (mNativeAwSettings != 0) {
603                             updateWebkitPreferencesOnUiThreadLocked();
604                             nativeResetScrollAndScaleState(mNativeAwSettings);
605                         }
606                     }
607                 });
608             }
609         }
610     }
611 
612     /**
613      * See {@link android.webkit.WebSettings#getLoadWithOverviewMode}.
614      */
getLoadWithOverviewMode()615     public boolean getLoadWithOverviewMode() {
616         synchronized (mAwSettingsLock) {
617             return getLoadWithOverviewModeLocked();
618         }
619     }
620 
621     @CalledByNative
getLoadWithOverviewModeLocked()622     private boolean getLoadWithOverviewModeLocked() {
623         assert Thread.holdsLock(mAwSettingsLock);
624         return mLoadWithOverviewMode;
625     }
626 
627     /**
628      * See {@link android.webkit.WebSettings#setTextZoom}.
629      */
setTextZoom(final int textZoom)630     public void setTextZoom(final int textZoom) {
631         synchronized (mAwSettingsLock) {
632             if (mTextSizePercent != textZoom) {
633                 mTextSizePercent = textZoom;
634                 mEventHandler.updateWebkitPreferencesLocked();
635             }
636         }
637     }
638 
639     /**
640      * See {@link android.webkit.WebSettings#getTextZoom}.
641      */
getTextZoom()642     public int getTextZoom() {
643         synchronized (mAwSettingsLock) {
644             return getTextSizePercentLocked();
645         }
646     }
647 
648     @CalledByNative
getTextSizePercentLocked()649     private int getTextSizePercentLocked() {
650         assert Thread.holdsLock(mAwSettingsLock);
651         return mTextSizePercent;
652     }
653 
654     /**
655      * See {@link android.webkit.WebSettings#setStandardFontFamily}.
656      */
setStandardFontFamily(String font)657     public void setStandardFontFamily(String font) {
658         synchronized (mAwSettingsLock) {
659             if (font != null && !mStandardFontFamily.equals(font)) {
660                 mStandardFontFamily = font;
661                 mEventHandler.updateWebkitPreferencesLocked();
662             }
663         }
664     }
665 
666     /**
667      * See {@link android.webkit.WebSettings#getStandardFontFamily}.
668      */
getStandardFontFamily()669     public String getStandardFontFamily() {
670         synchronized (mAwSettingsLock) {
671             return getStandardFontFamilyLocked();
672         }
673     }
674 
675     @CalledByNative
getStandardFontFamilyLocked()676     private String getStandardFontFamilyLocked() {
677         assert Thread.holdsLock(mAwSettingsLock);
678         return mStandardFontFamily;
679     }
680 
681     /**
682      * See {@link android.webkit.WebSettings#setFixedFontFamily}.
683      */
setFixedFontFamily(String font)684     public void setFixedFontFamily(String font) {
685         synchronized (mAwSettingsLock) {
686             if (font != null && !mFixedFontFamily.equals(font)) {
687                 mFixedFontFamily = font;
688                 mEventHandler.updateWebkitPreferencesLocked();
689             }
690         }
691     }
692 
693     /**
694      * See {@link android.webkit.WebSettings#getFixedFontFamily}.
695      */
getFixedFontFamily()696     public String getFixedFontFamily() {
697         synchronized (mAwSettingsLock) {
698             return getFixedFontFamilyLocked();
699         }
700     }
701 
702     @CalledByNative
getFixedFontFamilyLocked()703     private String getFixedFontFamilyLocked() {
704         assert Thread.holdsLock(mAwSettingsLock);
705         return mFixedFontFamily;
706     }
707 
708     /**
709      * See {@link android.webkit.WebSettings#setSansSerifFontFamily}.
710      */
setSansSerifFontFamily(String font)711     public void setSansSerifFontFamily(String font) {
712         synchronized (mAwSettingsLock) {
713             if (font != null && !mSansSerifFontFamily.equals(font)) {
714                 mSansSerifFontFamily = font;
715                 mEventHandler.updateWebkitPreferencesLocked();
716             }
717         }
718     }
719 
720     /**
721      * See {@link android.webkit.WebSettings#getSansSerifFontFamily}.
722      */
getSansSerifFontFamily()723     public String getSansSerifFontFamily() {
724         synchronized (mAwSettingsLock) {
725             return getSansSerifFontFamilyLocked();
726         }
727     }
728 
729     @CalledByNative
getSansSerifFontFamilyLocked()730     private String getSansSerifFontFamilyLocked() {
731         assert Thread.holdsLock(mAwSettingsLock);
732         return mSansSerifFontFamily;
733     }
734 
735     /**
736      * See {@link android.webkit.WebSettings#setSerifFontFamily}.
737      */
setSerifFontFamily(String font)738     public void setSerifFontFamily(String font) {
739         synchronized (mAwSettingsLock) {
740             if (font != null && !mSerifFontFamily.equals(font)) {
741                 mSerifFontFamily = font;
742                 mEventHandler.updateWebkitPreferencesLocked();
743             }
744         }
745     }
746 
747     /**
748      * See {@link android.webkit.WebSettings#getSerifFontFamily}.
749      */
getSerifFontFamily()750     public String getSerifFontFamily() {
751         synchronized (mAwSettingsLock) {
752             return getSerifFontFamilyLocked();
753         }
754     }
755 
756     @CalledByNative
getSerifFontFamilyLocked()757     private String getSerifFontFamilyLocked() {
758         assert Thread.holdsLock(mAwSettingsLock);
759         return mSerifFontFamily;
760     }
761 
762     /**
763      * See {@link android.webkit.WebSettings#setCursiveFontFamily}.
764      */
setCursiveFontFamily(String font)765     public void setCursiveFontFamily(String font) {
766         synchronized (mAwSettingsLock) {
767             if (font != null && !mCursiveFontFamily.equals(font)) {
768                 mCursiveFontFamily = font;
769                 mEventHandler.updateWebkitPreferencesLocked();
770             }
771         }
772     }
773 
774     /**
775      * See {@link android.webkit.WebSettings#getCursiveFontFamily}.
776      */
getCursiveFontFamily()777     public String getCursiveFontFamily() {
778         synchronized (mAwSettingsLock) {
779             return getCursiveFontFamilyLocked();
780         }
781     }
782 
783     @CalledByNative
getCursiveFontFamilyLocked()784     private String getCursiveFontFamilyLocked() {
785         assert Thread.holdsLock(mAwSettingsLock);
786         return mCursiveFontFamily;
787     }
788 
789     /**
790      * See {@link android.webkit.WebSettings#setFantasyFontFamily}.
791      */
setFantasyFontFamily(String font)792     public void setFantasyFontFamily(String font) {
793         synchronized (mAwSettingsLock) {
794             if (font != null && !mFantasyFontFamily.equals(font)) {
795                 mFantasyFontFamily = font;
796                 mEventHandler.updateWebkitPreferencesLocked();
797             }
798         }
799     }
800 
801     /**
802      * See {@link android.webkit.WebSettings#getFantasyFontFamily}.
803      */
getFantasyFontFamily()804     public String getFantasyFontFamily() {
805         synchronized (mAwSettingsLock) {
806             return getFantasyFontFamilyLocked();
807         }
808     }
809 
810     @CalledByNative
getFantasyFontFamilyLocked()811     private String getFantasyFontFamilyLocked() {
812         assert Thread.holdsLock(mAwSettingsLock);
813         return mFantasyFontFamily;
814     }
815 
816     /**
817      * See {@link android.webkit.WebSettings#setMinimumFontSize}.
818      */
setMinimumFontSize(int size)819     public void setMinimumFontSize(int size) {
820         synchronized (mAwSettingsLock) {
821             size = clipFontSize(size);
822             if (mMinimumFontSize != size) {
823                 mMinimumFontSize = size;
824                 mEventHandler.updateWebkitPreferencesLocked();
825             }
826         }
827     }
828 
829     /**
830      * See {@link android.webkit.WebSettings#getMinimumFontSize}.
831      */
getMinimumFontSize()832     public int getMinimumFontSize() {
833         synchronized (mAwSettingsLock) {
834             return getMinimumFontSizeLocked();
835         }
836     }
837 
838     @CalledByNative
getMinimumFontSizeLocked()839     private int getMinimumFontSizeLocked() {
840         assert Thread.holdsLock(mAwSettingsLock);
841         return mMinimumFontSize;
842     }
843 
844     /**
845      * See {@link android.webkit.WebSettings#setMinimumLogicalFontSize}.
846      */
setMinimumLogicalFontSize(int size)847     public void setMinimumLogicalFontSize(int size) {
848         synchronized (mAwSettingsLock) {
849             size = clipFontSize(size);
850             if (mMinimumLogicalFontSize != size) {
851                 mMinimumLogicalFontSize = size;
852                 mEventHandler.updateWebkitPreferencesLocked();
853             }
854         }
855     }
856 
857     /**
858      * See {@link android.webkit.WebSettings#getMinimumLogicalFontSize}.
859      */
getMinimumLogicalFontSize()860     public int getMinimumLogicalFontSize() {
861         synchronized (mAwSettingsLock) {
862             return getMinimumLogicalFontSizeLocked();
863         }
864     }
865 
866     @CalledByNative
getMinimumLogicalFontSizeLocked()867     private int getMinimumLogicalFontSizeLocked() {
868         assert Thread.holdsLock(mAwSettingsLock);
869         return mMinimumLogicalFontSize;
870     }
871 
872     /**
873      * See {@link android.webkit.WebSettings#setDefaultFontSize}.
874      */
setDefaultFontSize(int size)875     public void setDefaultFontSize(int size) {
876         synchronized (mAwSettingsLock) {
877             size = clipFontSize(size);
878             if (mDefaultFontSize != size) {
879                 mDefaultFontSize = size;
880                 mEventHandler.updateWebkitPreferencesLocked();
881             }
882         }
883     }
884 
885     /**
886      * See {@link android.webkit.WebSettings#getDefaultFontSize}.
887      */
getDefaultFontSize()888     public int getDefaultFontSize() {
889         synchronized (mAwSettingsLock) {
890             return getDefaultFontSizeLocked();
891         }
892     }
893 
894     @CalledByNative
getDefaultFontSizeLocked()895     private int getDefaultFontSizeLocked() {
896         assert Thread.holdsLock(mAwSettingsLock);
897         return mDefaultFontSize;
898     }
899 
900     /**
901      * See {@link android.webkit.WebSettings#setDefaultFixedFontSize}.
902      */
setDefaultFixedFontSize(int size)903     public void setDefaultFixedFontSize(int size) {
904         synchronized (mAwSettingsLock) {
905             size = clipFontSize(size);
906             if (mDefaultFixedFontSize != size) {
907                 mDefaultFixedFontSize = size;
908                 mEventHandler.updateWebkitPreferencesLocked();
909             }
910         }
911     }
912 
913     /**
914      * See {@link android.webkit.WebSettings#getDefaultFixedFontSize}.
915      */
getDefaultFixedFontSize()916     public int getDefaultFixedFontSize() {
917         synchronized (mAwSettingsLock) {
918             return getDefaultFixedFontSizeLocked();
919         }
920     }
921 
922     @CalledByNative
getDefaultFixedFontSizeLocked()923     private int getDefaultFixedFontSizeLocked() {
924         assert Thread.holdsLock(mAwSettingsLock);
925         return mDefaultFixedFontSize;
926     }
927 
928     /**
929      * See {@link android.webkit.WebSettings#setJavaScriptEnabled}.
930      */
setJavaScriptEnabled(boolean flag)931     public void setJavaScriptEnabled(boolean flag) {
932         synchronized (mAwSettingsLock) {
933             if (mJavaScriptEnabled != flag) {
934                 mJavaScriptEnabled = flag;
935                 mEventHandler.updateWebkitPreferencesLocked();
936             }
937         }
938     }
939 
940     /**
941      * See {@link android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs}.
942      */
setAllowUniversalAccessFromFileURLs(boolean flag)943     public void setAllowUniversalAccessFromFileURLs(boolean flag) {
944         synchronized (mAwSettingsLock) {
945             if (mAllowUniversalAccessFromFileURLs != flag) {
946                 mAllowUniversalAccessFromFileURLs = flag;
947                 mEventHandler.updateWebkitPreferencesLocked();
948             }
949         }
950     }
951 
952     /**
953      * See {@link android.webkit.WebSettings#setAllowFileAccessFromFileURLs}.
954      */
setAllowFileAccessFromFileURLs(boolean flag)955     public void setAllowFileAccessFromFileURLs(boolean flag) {
956         synchronized (mAwSettingsLock) {
957             if (mAllowFileAccessFromFileURLs != flag) {
958                 mAllowFileAccessFromFileURLs = flag;
959                 mEventHandler.updateWebkitPreferencesLocked();
960             }
961         }
962     }
963 
964     /**
965      * See {@link android.webkit.WebSettings#setLoadsImagesAutomatically}.
966      */
setLoadsImagesAutomatically(boolean flag)967     public void setLoadsImagesAutomatically(boolean flag) {
968         synchronized (mAwSettingsLock) {
969             if (mLoadsImagesAutomatically != flag) {
970                 mLoadsImagesAutomatically = flag;
971                 mEventHandler.updateWebkitPreferencesLocked();
972             }
973         }
974     }
975 
976     /**
977      * See {@link android.webkit.WebSettings#getLoadsImagesAutomatically}.
978      */
getLoadsImagesAutomatically()979     public boolean getLoadsImagesAutomatically() {
980         synchronized (mAwSettingsLock) {
981             return getLoadsImagesAutomaticallyLocked();
982         }
983     }
984 
985     @CalledByNative
getLoadsImagesAutomaticallyLocked()986     private boolean getLoadsImagesAutomaticallyLocked() {
987         assert Thread.holdsLock(mAwSettingsLock);
988         return mLoadsImagesAutomatically;
989     }
990 
991     /**
992      * See {@link android.webkit.WebSettings#setImagesEnabled}.
993      */
setImagesEnabled(boolean flag)994     public void setImagesEnabled(boolean flag) {
995         synchronized (mAwSettingsLock) {
996             if (mImagesEnabled != flag) {
997                 mImagesEnabled = flag;
998                 mEventHandler.updateWebkitPreferencesLocked();
999             }
1000         }
1001     }
1002 
1003     /**
1004      * See {@link android.webkit.WebSettings#getImagesEnabled}.
1005      */
getImagesEnabled()1006     public boolean getImagesEnabled() {
1007         synchronized (mAwSettingsLock) {
1008             return mImagesEnabled;
1009         }
1010     }
1011 
1012     @CalledByNative
getImagesEnabledLocked()1013     private boolean getImagesEnabledLocked() {
1014         assert Thread.holdsLock(mAwSettingsLock);
1015         return mImagesEnabled;
1016     }
1017 
1018     /**
1019      * See {@link android.webkit.WebSettings#getJavaScriptEnabled}.
1020      */
getJavaScriptEnabled()1021     public boolean getJavaScriptEnabled() {
1022         synchronized (mAwSettingsLock) {
1023             return mJavaScriptEnabled;
1024         }
1025     }
1026 
1027     @CalledByNative
getJavaScriptEnabledLocked()1028     private boolean getJavaScriptEnabledLocked() {
1029         assert Thread.holdsLock(mAwSettingsLock);
1030         return mJavaScriptEnabled;
1031     }
1032 
1033     /**
1034      * See {@link android.webkit.WebSettings#getAllowUniversalAccessFromFileURLs}.
1035      */
getAllowUniversalAccessFromFileURLs()1036     public boolean getAllowUniversalAccessFromFileURLs() {
1037         synchronized (mAwSettingsLock) {
1038             return getAllowUniversalAccessFromFileURLsLocked();
1039         }
1040     }
1041 
1042     @CalledByNative
getAllowUniversalAccessFromFileURLsLocked()1043     private boolean getAllowUniversalAccessFromFileURLsLocked() {
1044         assert Thread.holdsLock(mAwSettingsLock);
1045         return mAllowUniversalAccessFromFileURLs;
1046     }
1047 
1048     /**
1049      * See {@link android.webkit.WebSettings#getAllowFileAccessFromFileURLs}.
1050      */
getAllowFileAccessFromFileURLs()1051     public boolean getAllowFileAccessFromFileURLs() {
1052         synchronized (mAwSettingsLock) {
1053             return getAllowFileAccessFromFileURLsLocked();
1054         }
1055     }
1056 
1057     @CalledByNative
getAllowFileAccessFromFileURLsLocked()1058     private boolean getAllowFileAccessFromFileURLsLocked() {
1059         assert Thread.holdsLock(mAwSettingsLock);
1060         return mAllowFileAccessFromFileURLs;
1061     }
1062 
1063     /**
1064      * See {@link android.webkit.WebSettings#setPluginsEnabled}.
1065      */
setPluginsEnabled(boolean flag)1066     public void setPluginsEnabled(boolean flag) {
1067         setPluginState(flag ? PluginState.ON : PluginState.OFF);
1068     }
1069 
1070     /**
1071      * See {@link android.webkit.WebSettings#setPluginState}.
1072      */
setPluginState(PluginState state)1073     public void setPluginState(PluginState state) {
1074         synchronized (mAwSettingsLock) {
1075             if (mPluginState != state) {
1076                 mPluginState = state;
1077                 mEventHandler.updateWebkitPreferencesLocked();
1078             }
1079         }
1080     }
1081 
1082     /**
1083      * See {@link android.webkit.WebSettings#getPluginsEnabled}.
1084      */
getPluginsEnabled()1085     public boolean getPluginsEnabled() {
1086         synchronized (mAwSettingsLock) {
1087             return mPluginState == PluginState.ON;
1088         }
1089     }
1090 
1091     /**
1092      * Return true if plugins are disabled.
1093      * @return True if plugins are disabled.
1094      */
1095     @CalledByNative
getPluginsDisabledLocked()1096     private boolean getPluginsDisabledLocked() {
1097         assert Thread.holdsLock(mAwSettingsLock);
1098         return mPluginState == PluginState.OFF;
1099     }
1100 
1101     /**
1102      * See {@link android.webkit.WebSettings#getPluginState}.
1103      */
getPluginState()1104     public PluginState getPluginState() {
1105         synchronized (mAwSettingsLock) {
1106             return mPluginState;
1107         }
1108     }
1109 
1110 
1111     /**
1112      * See {@link android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically}.
1113      */
setJavaScriptCanOpenWindowsAutomatically(boolean flag)1114     public void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
1115         synchronized (mAwSettingsLock) {
1116             if (mJavaScriptCanOpenWindowsAutomatically != flag) {
1117                 mJavaScriptCanOpenWindowsAutomatically = flag;
1118                 mEventHandler.updateWebkitPreferencesLocked();
1119             }
1120         }
1121     }
1122 
1123     /**
1124      * See {@link android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically}.
1125      */
getJavaScriptCanOpenWindowsAutomatically()1126     public boolean getJavaScriptCanOpenWindowsAutomatically() {
1127         synchronized (mAwSettingsLock) {
1128             return getJavaScriptCanOpenWindowsAutomaticallyLocked();
1129         }
1130     }
1131 
1132     @CalledByNative
getJavaScriptCanOpenWindowsAutomaticallyLocked()1133     private boolean getJavaScriptCanOpenWindowsAutomaticallyLocked() {
1134         assert Thread.holdsLock(mAwSettingsLock);
1135         return mJavaScriptCanOpenWindowsAutomatically;
1136     }
1137 
1138     /**
1139      * See {@link android.webkit.WebSettings#setLayoutAlgorithm}.
1140      */
setLayoutAlgorithm(LayoutAlgorithm l)1141     public void setLayoutAlgorithm(LayoutAlgorithm l) {
1142         synchronized (mAwSettingsLock) {
1143             if (mLayoutAlgorithm != l) {
1144                 mLayoutAlgorithm = l;
1145                 mEventHandler.updateWebkitPreferencesLocked();
1146             }
1147         }
1148     }
1149 
1150     /**
1151      * See {@link android.webkit.WebSettings#getLayoutAlgorithm}.
1152      */
getLayoutAlgorithm()1153     public LayoutAlgorithm getLayoutAlgorithm() {
1154         synchronized (mAwSettingsLock) {
1155             return mLayoutAlgorithm;
1156         }
1157     }
1158 
1159     /**
1160      * Gets whether Text Auto-sizing layout algorithm is enabled.
1161      *
1162      * @return true if Text Auto-sizing layout algorithm is enabled
1163      */
1164     @CalledByNative
getTextAutosizingEnabledLocked()1165     private boolean getTextAutosizingEnabledLocked() {
1166         assert Thread.holdsLock(mAwSettingsLock);
1167         return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING;
1168     }
1169 
1170     /**
1171      * See {@link android.webkit.WebSettings#setSupportMultipleWindows}.
1172      */
setSupportMultipleWindows(boolean support)1173     public void setSupportMultipleWindows(boolean support) {
1174         synchronized (mAwSettingsLock) {
1175             if (mSupportMultipleWindows != support) {
1176                 mSupportMultipleWindows = support;
1177                 mEventHandler.updateWebkitPreferencesLocked();
1178             }
1179         }
1180     }
1181 
1182     /**
1183      * See {@link android.webkit.WebSettings#supportMultipleWindows}.
1184      */
supportMultipleWindows()1185     public boolean supportMultipleWindows() {
1186         synchronized (mAwSettingsLock) {
1187             return mSupportMultipleWindows;
1188         }
1189     }
1190 
1191     @CalledByNative
getSupportMultipleWindowsLocked()1192     private boolean getSupportMultipleWindowsLocked() {
1193         assert Thread.holdsLock(mAwSettingsLock);
1194         return mSupportMultipleWindows;
1195     }
1196 
1197     @CalledByNative
getSupportLegacyQuirksLocked()1198     private boolean getSupportLegacyQuirksLocked() {
1199         assert Thread.holdsLock(mAwSettingsLock);
1200         return mSupportLegacyQuirks;
1201     }
1202 
1203     /**
1204      * See {@link android.webkit.WebSettings#setUseWideViewPort}.
1205      */
setUseWideViewPort(boolean use)1206     public void setUseWideViewPort(boolean use) {
1207         synchronized (mAwSettingsLock) {
1208             if (mUseWideViewport != use) {
1209                 mUseWideViewport = use;
1210                 onGestureZoomSupportChanged(
1211                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1212                 mEventHandler.updateWebkitPreferencesLocked();
1213             }
1214         }
1215     }
1216 
1217     /**
1218      * See {@link android.webkit.WebSettings#getUseWideViewPort}.
1219      */
getUseWideViewPort()1220     public boolean getUseWideViewPort() {
1221         synchronized (mAwSettingsLock) {
1222             return getUseWideViewportLocked();
1223         }
1224     }
1225 
1226     @CalledByNative
getUseWideViewportLocked()1227     private boolean getUseWideViewportLocked() {
1228         assert Thread.holdsLock(mAwSettingsLock);
1229         return mUseWideViewport;
1230     }
1231 
setZeroLayoutHeightDisablesViewportQuirk(boolean enabled)1232     public void setZeroLayoutHeightDisablesViewportQuirk(boolean enabled) {
1233         synchronized (mAwSettingsLock) {
1234             if (mZeroLayoutHeightDisablesViewportQuirk != enabled) {
1235                 mZeroLayoutHeightDisablesViewportQuirk = enabled;
1236                 mEventHandler.updateWebkitPreferencesLocked();
1237             }
1238         }
1239     }
1240 
getZeroLayoutHeightDisablesViewportQuirk()1241     public boolean getZeroLayoutHeightDisablesViewportQuirk() {
1242         synchronized (mAwSettingsLock) {
1243             return getZeroLayoutHeightDisablesViewportQuirkLocked();
1244         }
1245     }
1246 
1247     @CalledByNative
getZeroLayoutHeightDisablesViewportQuirkLocked()1248     private boolean getZeroLayoutHeightDisablesViewportQuirkLocked() {
1249         assert Thread.holdsLock(mAwSettingsLock);
1250         return mZeroLayoutHeightDisablesViewportQuirk;
1251     }
1252 
setForceZeroLayoutHeight(boolean enabled)1253     public void setForceZeroLayoutHeight(boolean enabled) {
1254         synchronized (mAwSettingsLock) {
1255             if (mForceZeroLayoutHeight != enabled) {
1256                 mForceZeroLayoutHeight = enabled;
1257                 mEventHandler.updateWebkitPreferencesLocked();
1258             }
1259         }
1260     }
1261 
getForceZeroLayoutHeight()1262     public boolean getForceZeroLayoutHeight() {
1263         synchronized (mAwSettingsLock) {
1264             return getForceZeroLayoutHeightLocked();
1265         }
1266     }
1267 
1268     @CalledByNative
getForceZeroLayoutHeightLocked()1269     private boolean getForceZeroLayoutHeightLocked() {
1270         assert Thread.holdsLock(mAwSettingsLock);
1271         return mForceZeroLayoutHeight;
1272     }
1273 
1274     @CalledByNative
getPasswordEchoEnabledLocked()1275     private boolean getPasswordEchoEnabledLocked() {
1276         assert Thread.holdsLock(mAwSettingsLock);
1277         return mPasswordEchoEnabled;
1278     }
1279 
1280     /**
1281      * See {@link android.webkit.WebSettings#setAppCacheEnabled}.
1282      */
setAppCacheEnabled(boolean flag)1283     public void setAppCacheEnabled(boolean flag) {
1284         synchronized (mAwSettingsLock) {
1285             if (mAppCacheEnabled != flag) {
1286                 mAppCacheEnabled = flag;
1287                 mEventHandler.updateWebkitPreferencesLocked();
1288             }
1289         }
1290     }
1291 
1292     /**
1293      * See {@link android.webkit.WebSettings#setAppCachePath}.
1294      */
setAppCachePath(String path)1295     public void setAppCachePath(String path) {
1296         boolean needToSync = false;
1297         synchronized (sGlobalContentSettingsLock) {
1298             // AppCachePath can only be set once.
1299             if (!sAppCachePathIsSet && path != null && !path.isEmpty()) {
1300                 sAppCachePathIsSet = true;
1301                 needToSync = true;
1302             }
1303         }
1304         // The obvious problem here is that other WebViews will not be updated,
1305         // until they execute synchronization from Java to the native side.
1306         // But this is the same behaviour as it was in the legacy WebView.
1307         if (needToSync) {
1308             synchronized (mAwSettingsLock) {
1309                 mEventHandler.updateWebkitPreferencesLocked();
1310             }
1311         }
1312     }
1313 
1314     /**
1315      * Gets whether Application Cache is enabled.
1316      *
1317      * @return true if Application Cache is enabled
1318      */
1319     @CalledByNative
getAppCacheEnabledLocked()1320     private boolean getAppCacheEnabledLocked() {
1321         assert Thread.holdsLock(mAwSettingsLock);
1322         if (!mAppCacheEnabled) {
1323             return false;
1324         }
1325         synchronized (sGlobalContentSettingsLock) {
1326             return sAppCachePathIsSet;
1327         }
1328     }
1329 
1330     /**
1331      * See {@link android.webkit.WebSettings#setDomStorageEnabled}.
1332      */
setDomStorageEnabled(boolean flag)1333     public void setDomStorageEnabled(boolean flag) {
1334         synchronized (mAwSettingsLock) {
1335             if (mDomStorageEnabled != flag) {
1336                 mDomStorageEnabled = flag;
1337                 mEventHandler.updateWebkitPreferencesLocked();
1338             }
1339         }
1340     }
1341 
1342     /**
1343      * See {@link android.webkit.WebSettings#getDomStorageEnabled}.
1344      */
getDomStorageEnabled()1345     public boolean getDomStorageEnabled() {
1346         synchronized (mAwSettingsLock) {
1347             return mDomStorageEnabled;
1348         }
1349     }
1350 
1351     @CalledByNative
getDomStorageEnabledLocked()1352     private boolean getDomStorageEnabledLocked() {
1353         assert Thread.holdsLock(mAwSettingsLock);
1354         return mDomStorageEnabled;
1355     }
1356 
1357     /**
1358      * See {@link android.webkit.WebSettings#setDatabaseEnabled}.
1359      */
setDatabaseEnabled(boolean flag)1360     public void setDatabaseEnabled(boolean flag) {
1361         synchronized (mAwSettingsLock) {
1362             if (mDatabaseEnabled != flag) {
1363                 mDatabaseEnabled = flag;
1364                 mEventHandler.updateWebkitPreferencesLocked();
1365             }
1366         }
1367     }
1368 
1369     /**
1370      * See {@link android.webkit.WebSettings#getDatabaseEnabled}.
1371      */
getDatabaseEnabled()1372     public boolean getDatabaseEnabled() {
1373         synchronized (mAwSettingsLock) {
1374             return mDatabaseEnabled;
1375         }
1376     }
1377 
1378     @CalledByNative
getDatabaseEnabledLocked()1379     private boolean getDatabaseEnabledLocked() {
1380         assert Thread.holdsLock(mAwSettingsLock);
1381         return mDatabaseEnabled;
1382     }
1383 
1384     /**
1385      * See {@link android.webkit.WebSettings#setDefaultTextEncodingName}.
1386      */
setDefaultTextEncodingName(String encoding)1387     public void setDefaultTextEncodingName(String encoding) {
1388         synchronized (mAwSettingsLock) {
1389             if (encoding != null && !mDefaultTextEncoding.equals(encoding)) {
1390                 mDefaultTextEncoding = encoding;
1391                 mEventHandler.updateWebkitPreferencesLocked();
1392             }
1393         }
1394     }
1395 
1396     /**
1397      * See {@link android.webkit.WebSettings#getDefaultTextEncodingName}.
1398      */
getDefaultTextEncodingName()1399     public String getDefaultTextEncodingName() {
1400         synchronized (mAwSettingsLock) {
1401             return getDefaultTextEncodingLocked();
1402         }
1403     }
1404 
1405     @CalledByNative
getDefaultTextEncodingLocked()1406     private String getDefaultTextEncodingLocked() {
1407         assert Thread.holdsLock(mAwSettingsLock);
1408         return mDefaultTextEncoding;
1409     }
1410 
1411     /**
1412      * See {@link android.webkit.WebSettings#setMediaPlaybackRequiresUserGesture}.
1413      */
setMediaPlaybackRequiresUserGesture(boolean require)1414     public void setMediaPlaybackRequiresUserGesture(boolean require) {
1415         synchronized (mAwSettingsLock) {
1416             if (mMediaPlaybackRequiresUserGesture != require) {
1417                 mMediaPlaybackRequiresUserGesture = require;
1418                 mEventHandler.updateWebkitPreferencesLocked();
1419             }
1420         }
1421     }
1422 
1423     /**
1424      * See {@link android.webkit.WebSettings#getMediaPlaybackRequiresUserGesture}.
1425      */
getMediaPlaybackRequiresUserGesture()1426     public boolean getMediaPlaybackRequiresUserGesture() {
1427         synchronized (mAwSettingsLock) {
1428             return getMediaPlaybackRequiresUserGestureLocked();
1429         }
1430     }
1431 
1432     @CalledByNative
getMediaPlaybackRequiresUserGestureLocked()1433     private boolean getMediaPlaybackRequiresUserGestureLocked() {
1434         assert Thread.holdsLock(mAwSettingsLock);
1435         return mMediaPlaybackRequiresUserGesture;
1436     }
1437 
1438     /**
1439      * See {@link android.webkit.WebSettings#setDefaultVideoPosterURL}.
1440      */
setDefaultVideoPosterURL(String url)1441     public void setDefaultVideoPosterURL(String url) {
1442         synchronized (mAwSettingsLock) {
1443             if (mDefaultVideoPosterURL != null && !mDefaultVideoPosterURL.equals(url) ||
1444                     mDefaultVideoPosterURL == null && url != null) {
1445                 mDefaultVideoPosterURL = url;
1446                 mEventHandler.updateWebkitPreferencesLocked();
1447             }
1448         }
1449     }
1450 
1451     /**
1452      * See {@link android.webkit.WebSettings#getDefaultVideoPosterURL}.
1453      */
getDefaultVideoPosterURL()1454     public String getDefaultVideoPosterURL() {
1455         synchronized (mAwSettingsLock) {
1456             return getDefaultVideoPosterURLLocked();
1457         }
1458     }
1459 
1460     @CalledByNative
getDefaultVideoPosterURLLocked()1461     private String getDefaultVideoPosterURLLocked() {
1462         assert Thread.holdsLock(mAwSettingsLock);
1463         return mDefaultVideoPosterURL;
1464     }
1465 
onGestureZoomSupportChanged( final boolean supportsDoubleTapZoom, final boolean supportsMultiTouchZoom)1466     private void onGestureZoomSupportChanged(
1467             final boolean supportsDoubleTapZoom, final boolean supportsMultiTouchZoom) {
1468         // Always post asynchronously here, to avoid doubling back onto the caller.
1469         mEventHandler.maybePostOnUiThread(new Runnable() {
1470             @Override
1471             public void run() {
1472                 synchronized (mAwSettingsLock) {
1473                     if (mZoomChangeListener != null) {
1474                         mZoomChangeListener.onGestureZoomSupportChanged(
1475                                 supportsDoubleTapZoom, supportsMultiTouchZoom);
1476                     }
1477                 }
1478             }
1479         });
1480     }
1481 
1482     /**
1483      * See {@link android.webkit.WebSettings#setSupportZoom}.
1484      */
setSupportZoom(boolean support)1485     public void setSupportZoom(boolean support) {
1486         synchronized (mAwSettingsLock) {
1487             if (mSupportZoom != support) {
1488                 mSupportZoom = support;
1489                 onGestureZoomSupportChanged(
1490                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1491             }
1492         }
1493     }
1494 
1495     /**
1496      * See {@link android.webkit.WebSettings#supportZoom}.
1497      */
supportZoom()1498     public boolean supportZoom() {
1499         synchronized (mAwSettingsLock) {
1500             return mSupportZoom;
1501         }
1502     }
1503 
1504     /**
1505      * See {@link android.webkit.WebSettings#setBuiltInZoomControls}.
1506      */
setBuiltInZoomControls(boolean enabled)1507     public void setBuiltInZoomControls(boolean enabled) {
1508         synchronized (mAwSettingsLock) {
1509             if (mBuiltInZoomControls != enabled) {
1510                 mBuiltInZoomControls = enabled;
1511                 onGestureZoomSupportChanged(
1512                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1513             }
1514         }
1515     }
1516 
1517     /**
1518      * See {@link android.webkit.WebSettings#getBuiltInZoomControls}.
1519      */
getBuiltInZoomControls()1520     public boolean getBuiltInZoomControls() {
1521         synchronized (mAwSettingsLock) {
1522             return mBuiltInZoomControls;
1523         }
1524     }
1525 
1526     /**
1527      * See {@link android.webkit.WebSettings#setDisplayZoomControls}.
1528      */
setDisplayZoomControls(boolean enabled)1529     public void setDisplayZoomControls(boolean enabled) {
1530         synchronized (mAwSettingsLock) {
1531             mDisplayZoomControls = enabled;
1532         }
1533     }
1534 
1535     /**
1536      * See {@link android.webkit.WebSettings#getDisplayZoomControls}.
1537      */
getDisplayZoomControls()1538     public boolean getDisplayZoomControls() {
1539         synchronized (mAwSettingsLock) {
1540             return mDisplayZoomControls;
1541         }
1542     }
1543 
setMixedContentMode(int mode)1544     public void setMixedContentMode(int mode) {
1545         synchronized (mAwSettingsLock) {
1546             if (mMixedContentMode != mode) {
1547                 mMixedContentMode = mode;
1548                 mEventHandler.updateWebkitPreferencesLocked();
1549             }
1550         }
1551     }
1552 
getMixedContentMode()1553     public int getMixedContentMode() {
1554         synchronized (mAwSettingsLock) {
1555             return mMixedContentMode;
1556         }
1557     }
1558 
1559     @CalledByNative
getAllowRunningInsecureContentLocked()1560     private boolean getAllowRunningInsecureContentLocked() {
1561         assert Thread.holdsLock(mAwSettingsLock);
1562         return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW;
1563     }
1564 
1565     @CalledByNative
getAllowDisplayingInsecureContentLocked()1566     private boolean getAllowDisplayingInsecureContentLocked() {
1567         assert Thread.holdsLock(mAwSettingsLock);
1568         return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW ||
1569                 mMixedContentMode == MIXED_CONTENT_COMPATIBILITY_MODE;
1570     }
1571 
1572     /**
1573      * Sets whether to use the video overlay for the embedded video.
1574      * @param flag whether to enable the video overlay for the embedded video.
1575      */
setVideoOverlayForEmbeddedVideoEnabled(final boolean enabled)1576     public void setVideoOverlayForEmbeddedVideoEnabled(final boolean enabled) {
1577         synchronized (mAwSettingsLock) {
1578             if (mVideoOverlayForEmbeddedVideoEnabled != enabled) {
1579                 mVideoOverlayForEmbeddedVideoEnabled = enabled;
1580                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
1581                     @Override
1582                     public void run() {
1583                         if (mNativeAwSettings != 0) {
1584                             nativeUpdateRendererPreferencesLocked(mNativeAwSettings);
1585                         }
1586                     }
1587                 });
1588             }
1589         }
1590     }
1591 
1592     /**
1593      * Gets whether to use the video overlay for the embedded video.
1594      * @return true if the WebView enables the video overlay for the embedded video.
1595      */
getVideoOverlayForEmbeddedVideoEnabled()1596     public boolean getVideoOverlayForEmbeddedVideoEnabled() {
1597         synchronized (mAwSettingsLock) {
1598             return getVideoOverlayForEmbeddedVideoEnabledLocked();
1599         }
1600     }
1601 
1602     @CalledByNative
getVideoOverlayForEmbeddedVideoEnabledLocked()1603     private boolean getVideoOverlayForEmbeddedVideoEnabledLocked() {
1604         assert Thread.holdsLock(mAwSettingsLock);
1605         return mVideoOverlayForEmbeddedVideoEnabled;
1606     }
1607 
1608     @CalledByNative
supportsDoubleTapZoomLocked()1609     private boolean supportsDoubleTapZoomLocked() {
1610         assert Thread.holdsLock(mAwSettingsLock);
1611         return mSupportZoom && mBuiltInZoomControls && mUseWideViewport;
1612     }
1613 
supportsMultiTouchZoomLocked()1614     private boolean supportsMultiTouchZoomLocked() {
1615         assert Thread.holdsLock(mAwSettingsLock);
1616         return mSupportZoom && mBuiltInZoomControls;
1617     }
1618 
supportsMultiTouchZoom()1619     boolean supportsMultiTouchZoom() {
1620         synchronized (mAwSettingsLock) {
1621             return supportsMultiTouchZoomLocked();
1622         }
1623     }
1624 
shouldDisplayZoomControls()1625     boolean shouldDisplayZoomControls() {
1626         synchronized (mAwSettingsLock) {
1627             return supportsMultiTouchZoomLocked() && mDisplayZoomControls;
1628         }
1629     }
1630 
clipFontSize(int size)1631     private int clipFontSize(int size) {
1632         if (size < MINIMUM_FONT_SIZE) {
1633             return MINIMUM_FONT_SIZE;
1634         } else if (size > MAXIMUM_FONT_SIZE) {
1635             return MAXIMUM_FONT_SIZE;
1636         }
1637         return size;
1638     }
1639 
1640     @CalledByNative
updateEverything()1641     private void updateEverything() {
1642         synchronized (mAwSettingsLock) {
1643             updateEverythingLocked();
1644         }
1645     }
1646 
1647     @CalledByNative
populateWebPreferences(long webPrefsPtr)1648     private void populateWebPreferences(long webPrefsPtr) {
1649         synchronized (mAwSettingsLock) {
1650             assert mNativeAwSettings != 0;
1651             nativePopulateWebPreferencesLocked(mNativeAwSettings, webPrefsPtr);
1652         }
1653     }
1654 
updateWebkitPreferencesOnUiThreadLocked()1655     private void updateWebkitPreferencesOnUiThreadLocked() {
1656         assert mEventHandler.mHandler != null;
1657         ThreadUtils.assertOnUiThread();
1658         if (mNativeAwSettings != 0) {
1659             nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
1660         }
1661     }
1662 
nativeInit(long webContentsPtr)1663     private native long nativeInit(long webContentsPtr);
1664 
nativeDestroy(long nativeAwSettings)1665     private native void nativeDestroy(long nativeAwSettings);
1666 
nativePopulateWebPreferencesLocked(long nativeAwSettings, long webPrefsPtr)1667     private native void nativePopulateWebPreferencesLocked(long nativeAwSettings, long webPrefsPtr);
1668 
nativeResetScrollAndScaleState(long nativeAwSettings)1669     private native void nativeResetScrollAndScaleState(long nativeAwSettings);
1670 
nativeUpdateEverythingLocked(long nativeAwSettings)1671     private native void nativeUpdateEverythingLocked(long nativeAwSettings);
1672 
nativeUpdateInitialPageScaleLocked(long nativeAwSettings)1673     private native void nativeUpdateInitialPageScaleLocked(long nativeAwSettings);
1674 
nativeUpdateUserAgentLocked(long nativeAwSettings)1675     private native void nativeUpdateUserAgentLocked(long nativeAwSettings);
1676 
nativeUpdateWebkitPreferencesLocked(long nativeAwSettings)1677     private native void nativeUpdateWebkitPreferencesLocked(long nativeAwSettings);
1678 
nativeGetDefaultUserAgent()1679     private static native String nativeGetDefaultUserAgent();
1680 
nativeUpdateFormDataPreferencesLocked(long nativeAwSettings)1681     private native void nativeUpdateFormDataPreferencesLocked(long nativeAwSettings);
1682 
nativeUpdateRendererPreferencesLocked(long nativeAwSettings)1683     private native void nativeUpdateRendererPreferencesLocked(long nativeAwSettings);
1684 }
1685