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