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