Upstream version 10.39.225.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 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;
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
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     public void setFullscreenSupported(boolean supported) {
467         synchronized (mAwSettingsLock) {
468             if (mFullscreenSupported != supported) {
469                 mFullscreenSupported = supported;
470                 mEventHandler.updateWebkitPreferencesLocked();
471             }
472         }
473     }
474
475     @CalledByNative
476     private boolean getFullscreenSupportedLocked() {
477         assert Thread.holdsLock(mAwSettingsLock);
478         return mFullscreenSupported;
479     }
480
481     /**
482      * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
483      */
484     public boolean shouldFocusFirstNode() {
485         synchronized (mAwSettingsLock) {
486             return mShouldFocusFirstNode;
487         }
488     }
489
490     /**
491      * See {@link android.webkit.WebSettings#setGeolocationEnabled}.
492      */
493     public void setGeolocationEnabled(boolean flag) {
494         synchronized (mAwSettingsLock) {
495             if (mGeolocationEnabled != flag) {
496                 mGeolocationEnabled = flag;
497             }
498         }
499     }
500
501     /**
502      * @return Returns if geolocation is currently enabled.
503      */
504     boolean getGeolocationEnabled() {
505         synchronized (mAwSettingsLock) {
506             return mGeolocationEnabled;
507         }
508     }
509
510     /**
511      * See {@link android.webkit.WebSettings#setSaveFormData}.
512      */
513     public void setSaveFormData(final boolean enable) {
514         synchronized (mAwSettingsLock) {
515             if (mAutoCompleteEnabled != enable) {
516                 mAutoCompleteEnabled = enable;
517                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
518                     @Override
519                     public void run() {
520                         if (mNativeAwSettings != 0) {
521                             nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
522                         }
523                     }
524                 });
525             }
526         }
527     }
528
529     /**
530      * See {@link android.webkit.WebSettings#getSaveFormData}.
531      */
532     public boolean getSaveFormData() {
533         synchronized (mAwSettingsLock) {
534             return getSaveFormDataLocked();
535         }
536     }
537
538     @CalledByNative
539     private boolean getSaveFormDataLocked() {
540         assert Thread.holdsLock(mAwSettingsLock);
541         return mAutoCompleteEnabled;
542     }
543
544     /**
545      * @returns the default User-Agent used by each ContentViewCore instance, i.e. unless
546      * overridden by {@link #setUserAgentString()}
547      */
548     public static String getDefaultUserAgent() {
549         return LazyDefaultUserAgent.sInstance;
550     }
551
552     /**
553      * See {@link android.webkit.WebSettings#setUserAgentString}.
554      */
555     public void setUserAgentString(String ua) {
556         synchronized (mAwSettingsLock) {
557             final String oldUserAgent = mUserAgent;
558             if (ua == null || ua.length() == 0) {
559                 mUserAgent = LazyDefaultUserAgent.sInstance;
560             } else {
561                 mUserAgent = ua;
562             }
563             if (!oldUserAgent.equals(mUserAgent)) {
564                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
565                     @Override
566                     public void run() {
567                         if (mNativeAwSettings != 0) {
568                             nativeUpdateUserAgentLocked(mNativeAwSettings);
569                         }
570                     }
571                 });
572             }
573         }
574     }
575
576     /**
577      * See {@link android.webkit.WebSettings#getUserAgentString}.
578      */
579     public String getUserAgentString() {
580         synchronized (mAwSettingsLock) {
581             return getUserAgentLocked();
582         }
583     }
584
585     @CalledByNative
586     private String getUserAgentLocked() {
587         assert Thread.holdsLock(mAwSettingsLock);
588         return mUserAgent;
589     }
590
591     /**
592      * See {@link android.webkit.WebSettings#setLoadWithOverviewMode}.
593      */
594     public void setLoadWithOverviewMode(boolean overview) {
595         synchronized (mAwSettingsLock) {
596             if (mLoadWithOverviewMode != overview) {
597                 mLoadWithOverviewMode = overview;
598                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
599                     @Override
600                     public void run() {
601                         if (mNativeAwSettings != 0) {
602                             updateWebkitPreferencesOnUiThreadLocked();
603                             nativeResetScrollAndScaleState(mNativeAwSettings);
604                         }
605                     }
606                 });
607             }
608         }
609     }
610
611     /**
612      * See {@link android.webkit.WebSettings#getLoadWithOverviewMode}.
613      */
614     public boolean getLoadWithOverviewMode() {
615         synchronized (mAwSettingsLock) {
616             return getLoadWithOverviewModeLocked();
617         }
618     }
619
620     @CalledByNative
621     private boolean getLoadWithOverviewModeLocked() {
622         assert Thread.holdsLock(mAwSettingsLock);
623         return mLoadWithOverviewMode;
624     }
625
626     /**
627      * See {@link android.webkit.WebSettings#setTextZoom}.
628      */
629     public void setTextZoom(final int textZoom) {
630         synchronized (mAwSettingsLock) {
631             if (mTextSizePercent != textZoom) {
632                 mTextSizePercent = textZoom;
633                 mEventHandler.updateWebkitPreferencesLocked();
634             }
635         }
636     }
637
638     /**
639      * See {@link android.webkit.WebSettings#getTextZoom}.
640      */
641     public int getTextZoom() {
642         synchronized (mAwSettingsLock) {
643             return getTextSizePercentLocked();
644         }
645     }
646
647     @CalledByNative
648     private int getTextSizePercentLocked() {
649         assert Thread.holdsLock(mAwSettingsLock);
650         return mTextSizePercent;
651     }
652
653     /**
654      * See {@link android.webkit.WebSettings#setStandardFontFamily}.
655      */
656     public void setStandardFontFamily(String font) {
657         synchronized (mAwSettingsLock) {
658             if (font != null && !mStandardFontFamily.equals(font)) {
659                 mStandardFontFamily = font;
660                 mEventHandler.updateWebkitPreferencesLocked();
661             }
662         }
663     }
664
665     /**
666      * See {@link android.webkit.WebSettings#getStandardFontFamily}.
667      */
668     public String getStandardFontFamily() {
669         synchronized (mAwSettingsLock) {
670             return getStandardFontFamilyLocked();
671         }
672     }
673
674     @CalledByNative
675     private String getStandardFontFamilyLocked() {
676         assert Thread.holdsLock(mAwSettingsLock);
677         return mStandardFontFamily;
678     }
679
680     /**
681      * See {@link android.webkit.WebSettings#setFixedFontFamily}.
682      */
683     public void setFixedFontFamily(String font) {
684         synchronized (mAwSettingsLock) {
685             if (font != null && !mFixedFontFamily.equals(font)) {
686                 mFixedFontFamily = font;
687                 mEventHandler.updateWebkitPreferencesLocked();
688             }
689         }
690     }
691
692     /**
693      * See {@link android.webkit.WebSettings#getFixedFontFamily}.
694      */
695     public String getFixedFontFamily() {
696         synchronized (mAwSettingsLock) {
697             return getFixedFontFamilyLocked();
698         }
699     }
700
701     @CalledByNative
702     private String getFixedFontFamilyLocked() {
703         assert Thread.holdsLock(mAwSettingsLock);
704         return mFixedFontFamily;
705     }
706
707     /**
708      * See {@link android.webkit.WebSettings#setSansSerifFontFamily}.
709      */
710     public void setSansSerifFontFamily(String font) {
711         synchronized (mAwSettingsLock) {
712             if (font != null && !mSansSerifFontFamily.equals(font)) {
713                 mSansSerifFontFamily = font;
714                 mEventHandler.updateWebkitPreferencesLocked();
715             }
716         }
717     }
718
719     /**
720      * See {@link android.webkit.WebSettings#getSansSerifFontFamily}.
721      */
722     public String getSansSerifFontFamily() {
723         synchronized (mAwSettingsLock) {
724             return getSansSerifFontFamilyLocked();
725         }
726     }
727
728     @CalledByNative
729     private String getSansSerifFontFamilyLocked() {
730         assert Thread.holdsLock(mAwSettingsLock);
731         return mSansSerifFontFamily;
732     }
733
734     /**
735      * See {@link android.webkit.WebSettings#setSerifFontFamily}.
736      */
737     public void setSerifFontFamily(String font) {
738         synchronized (mAwSettingsLock) {
739             if (font != null && !mSerifFontFamily.equals(font)) {
740                 mSerifFontFamily = font;
741                 mEventHandler.updateWebkitPreferencesLocked();
742             }
743         }
744     }
745
746     /**
747      * See {@link android.webkit.WebSettings#getSerifFontFamily}.
748      */
749     public String getSerifFontFamily() {
750         synchronized (mAwSettingsLock) {
751             return getSerifFontFamilyLocked();
752         }
753     }
754
755     @CalledByNative
756     private String getSerifFontFamilyLocked() {
757         assert Thread.holdsLock(mAwSettingsLock);
758         return mSerifFontFamily;
759     }
760
761     /**
762      * See {@link android.webkit.WebSettings#setCursiveFontFamily}.
763      */
764     public void setCursiveFontFamily(String font) {
765         synchronized (mAwSettingsLock) {
766             if (font != null && !mCursiveFontFamily.equals(font)) {
767                 mCursiveFontFamily = font;
768                 mEventHandler.updateWebkitPreferencesLocked();
769             }
770         }
771     }
772
773     /**
774      * See {@link android.webkit.WebSettings#getCursiveFontFamily}.
775      */
776     public String getCursiveFontFamily() {
777         synchronized (mAwSettingsLock) {
778             return getCursiveFontFamilyLocked();
779         }
780     }
781
782     @CalledByNative
783     private String getCursiveFontFamilyLocked() {
784         assert Thread.holdsLock(mAwSettingsLock);
785         return mCursiveFontFamily;
786     }
787
788     /**
789      * See {@link android.webkit.WebSettings#setFantasyFontFamily}.
790      */
791     public void setFantasyFontFamily(String font) {
792         synchronized (mAwSettingsLock) {
793             if (font != null && !mFantasyFontFamily.equals(font)) {
794                 mFantasyFontFamily = font;
795                 mEventHandler.updateWebkitPreferencesLocked();
796             }
797         }
798     }
799
800     /**
801      * See {@link android.webkit.WebSettings#getFantasyFontFamily}.
802      */
803     public String getFantasyFontFamily() {
804         synchronized (mAwSettingsLock) {
805             return getFantasyFontFamilyLocked();
806         }
807     }
808
809     @CalledByNative
810     private String getFantasyFontFamilyLocked() {
811         assert Thread.holdsLock(mAwSettingsLock);
812         return mFantasyFontFamily;
813     }
814
815     /**
816      * See {@link android.webkit.WebSettings#setMinimumFontSize}.
817      */
818     public void setMinimumFontSize(int size) {
819         synchronized (mAwSettingsLock) {
820             size = clipFontSize(size);
821             if (mMinimumFontSize != size) {
822                 mMinimumFontSize = size;
823                 mEventHandler.updateWebkitPreferencesLocked();
824             }
825         }
826     }
827
828     /**
829      * See {@link android.webkit.WebSettings#getMinimumFontSize}.
830      */
831     public int getMinimumFontSize() {
832         synchronized (mAwSettingsLock) {
833             return getMinimumFontSizeLocked();
834         }
835     }
836
837     @CalledByNative
838     private int getMinimumFontSizeLocked() {
839         assert Thread.holdsLock(mAwSettingsLock);
840         return mMinimumFontSize;
841     }
842
843     /**
844      * See {@link android.webkit.WebSettings#setMinimumLogicalFontSize}.
845      */
846     public void setMinimumLogicalFontSize(int size) {
847         synchronized (mAwSettingsLock) {
848             size = clipFontSize(size);
849             if (mMinimumLogicalFontSize != size) {
850                 mMinimumLogicalFontSize = size;
851                 mEventHandler.updateWebkitPreferencesLocked();
852             }
853         }
854     }
855
856     /**
857      * See {@link android.webkit.WebSettings#getMinimumLogicalFontSize}.
858      */
859     public int getMinimumLogicalFontSize() {
860         synchronized (mAwSettingsLock) {
861             return getMinimumLogicalFontSizeLocked();
862         }
863     }
864
865     @CalledByNative
866     private int getMinimumLogicalFontSizeLocked() {
867         assert Thread.holdsLock(mAwSettingsLock);
868         return mMinimumLogicalFontSize;
869     }
870
871     /**
872      * See {@link android.webkit.WebSettings#setDefaultFontSize}.
873      */
874     public void setDefaultFontSize(int size) {
875         synchronized (mAwSettingsLock) {
876             size = clipFontSize(size);
877             if (mDefaultFontSize != size) {
878                 mDefaultFontSize = size;
879                 mEventHandler.updateWebkitPreferencesLocked();
880             }
881         }
882     }
883
884     /**
885      * See {@link android.webkit.WebSettings#getDefaultFontSize}.
886      */
887     public int getDefaultFontSize() {
888         synchronized (mAwSettingsLock) {
889             return getDefaultFontSizeLocked();
890         }
891     }
892
893     @CalledByNative
894     private int getDefaultFontSizeLocked() {
895         assert Thread.holdsLock(mAwSettingsLock);
896         return mDefaultFontSize;
897     }
898
899     /**
900      * See {@link android.webkit.WebSettings#setDefaultFixedFontSize}.
901      */
902     public void setDefaultFixedFontSize(int size) {
903         synchronized (mAwSettingsLock) {
904             size = clipFontSize(size);
905             if (mDefaultFixedFontSize != size) {
906                 mDefaultFixedFontSize = size;
907                 mEventHandler.updateWebkitPreferencesLocked();
908             }
909         }
910     }
911
912     /**
913      * See {@link android.webkit.WebSettings#getDefaultFixedFontSize}.
914      */
915     public int getDefaultFixedFontSize() {
916         synchronized (mAwSettingsLock) {
917             return getDefaultFixedFontSizeLocked();
918         }
919     }
920
921     @CalledByNative
922     private int getDefaultFixedFontSizeLocked() {
923         assert Thread.holdsLock(mAwSettingsLock);
924         return mDefaultFixedFontSize;
925     }
926
927     /**
928      * See {@link android.webkit.WebSettings#setJavaScriptEnabled}.
929      */
930     public void setJavaScriptEnabled(boolean flag) {
931         synchronized (mAwSettingsLock) {
932             if (mJavaScriptEnabled != flag) {
933                 mJavaScriptEnabled = flag;
934                 mEventHandler.updateWebkitPreferencesLocked();
935             }
936         }
937     }
938
939     /**
940      * See {@link android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs}.
941      */
942     public void setAllowUniversalAccessFromFileURLs(boolean flag) {
943         synchronized (mAwSettingsLock) {
944             if (mAllowUniversalAccessFromFileURLs != flag) {
945                 mAllowUniversalAccessFromFileURLs = flag;
946                 mEventHandler.updateWebkitPreferencesLocked();
947             }
948         }
949     }
950
951     /**
952      * See {@link android.webkit.WebSettings#setAllowFileAccessFromFileURLs}.
953      */
954     public void setAllowFileAccessFromFileURLs(boolean flag) {
955         synchronized (mAwSettingsLock) {
956             if (mAllowFileAccessFromFileURLs != flag) {
957                 mAllowFileAccessFromFileURLs = flag;
958                 mEventHandler.updateWebkitPreferencesLocked();
959             }
960         }
961     }
962
963     /**
964      * See {@link android.webkit.WebSettings#setLoadsImagesAutomatically}.
965      */
966     public void setLoadsImagesAutomatically(boolean flag) {
967         synchronized (mAwSettingsLock) {
968             if (mLoadsImagesAutomatically != flag) {
969                 mLoadsImagesAutomatically = flag;
970                 mEventHandler.updateWebkitPreferencesLocked();
971             }
972         }
973     }
974
975     /**
976      * See {@link android.webkit.WebSettings#getLoadsImagesAutomatically}.
977      */
978     public boolean getLoadsImagesAutomatically() {
979         synchronized (mAwSettingsLock) {
980             return getLoadsImagesAutomaticallyLocked();
981         }
982     }
983
984     @CalledByNative
985     private boolean getLoadsImagesAutomaticallyLocked() {
986         assert Thread.holdsLock(mAwSettingsLock);
987         return mLoadsImagesAutomatically;
988     }
989
990     /**
991      * See {@link android.webkit.WebSettings#setImagesEnabled}.
992      */
993     public void setImagesEnabled(boolean flag) {
994         synchronized (mAwSettingsLock) {
995             if (mImagesEnabled != flag) {
996                 mImagesEnabled = flag;
997                 mEventHandler.updateWebkitPreferencesLocked();
998             }
999         }
1000     }
1001
1002     /**
1003      * See {@link android.webkit.WebSettings#getImagesEnabled}.
1004      */
1005     public boolean getImagesEnabled() {
1006         synchronized (mAwSettingsLock) {
1007             return mImagesEnabled;
1008         }
1009     }
1010
1011     @CalledByNative
1012     private boolean getImagesEnabledLocked() {
1013         assert Thread.holdsLock(mAwSettingsLock);
1014         return mImagesEnabled;
1015     }
1016
1017     /**
1018      * See {@link android.webkit.WebSettings#getJavaScriptEnabled}.
1019      */
1020     public boolean getJavaScriptEnabled() {
1021         synchronized (mAwSettingsLock) {
1022             return mJavaScriptEnabled;
1023         }
1024     }
1025
1026     @CalledByNative
1027     private boolean getJavaScriptEnabledLocked() {
1028         assert Thread.holdsLock(mAwSettingsLock);
1029         return mJavaScriptEnabled;
1030     }
1031
1032     /**
1033      * See {@link android.webkit.WebSettings#getAllowUniversalAccessFromFileURLs}.
1034      */
1035     public boolean getAllowUniversalAccessFromFileURLs() {
1036         synchronized (mAwSettingsLock) {
1037             return getAllowUniversalAccessFromFileURLsLocked();
1038         }
1039     }
1040
1041     @CalledByNative
1042     private boolean getAllowUniversalAccessFromFileURLsLocked() {
1043         assert Thread.holdsLock(mAwSettingsLock);
1044         return mAllowUniversalAccessFromFileURLs;
1045     }
1046
1047     /**
1048      * See {@link android.webkit.WebSettings#getAllowFileAccessFromFileURLs}.
1049      */
1050     public boolean getAllowFileAccessFromFileURLs() {
1051         synchronized (mAwSettingsLock) {
1052             return getAllowFileAccessFromFileURLsLocked();
1053         }
1054     }
1055
1056     @CalledByNative
1057     private boolean getAllowFileAccessFromFileURLsLocked() {
1058         assert Thread.holdsLock(mAwSettingsLock);
1059         return mAllowFileAccessFromFileURLs;
1060     }
1061
1062     /**
1063      * See {@link android.webkit.WebSettings#setPluginsEnabled}.
1064      */
1065     public void setPluginsEnabled(boolean flag) {
1066         setPluginState(flag ? PluginState.ON : PluginState.OFF);
1067     }
1068
1069     /**
1070      * See {@link android.webkit.WebSettings#setPluginState}.
1071      */
1072     public void setPluginState(PluginState state) {
1073         synchronized (mAwSettingsLock) {
1074             if (mPluginState != state) {
1075                 mPluginState = state;
1076                 mEventHandler.updateWebkitPreferencesLocked();
1077             }
1078         }
1079     }
1080
1081     /**
1082      * See {@link android.webkit.WebSettings#getPluginsEnabled}.
1083      */
1084     public boolean getPluginsEnabled() {
1085         synchronized (mAwSettingsLock) {
1086             return mPluginState == PluginState.ON;
1087         }
1088     }
1089
1090     /**
1091      * Return true if plugins are disabled.
1092      * @return True if plugins are disabled.
1093      */
1094     @CalledByNative
1095     private boolean getPluginsDisabledLocked() {
1096         assert Thread.holdsLock(mAwSettingsLock);
1097         return mPluginState == PluginState.OFF;
1098     }
1099
1100     /**
1101      * See {@link android.webkit.WebSettings#getPluginState}.
1102      */
1103     public PluginState getPluginState() {
1104         synchronized (mAwSettingsLock) {
1105             return mPluginState;
1106         }
1107     }
1108
1109
1110     /**
1111      * See {@link android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically}.
1112      */
1113     public void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
1114         synchronized (mAwSettingsLock) {
1115             if (mJavaScriptCanOpenWindowsAutomatically != flag) {
1116                 mJavaScriptCanOpenWindowsAutomatically = flag;
1117                 mEventHandler.updateWebkitPreferencesLocked();
1118             }
1119         }
1120     }
1121
1122     /**
1123      * See {@link android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically}.
1124      */
1125     public boolean getJavaScriptCanOpenWindowsAutomatically() {
1126         synchronized (mAwSettingsLock) {
1127             return getJavaScriptCanOpenWindowsAutomaticallyLocked();
1128         }
1129     }
1130
1131     @CalledByNative
1132     private boolean getJavaScriptCanOpenWindowsAutomaticallyLocked() {
1133         assert Thread.holdsLock(mAwSettingsLock);
1134         return mJavaScriptCanOpenWindowsAutomatically;
1135     }
1136
1137     /**
1138      * See {@link android.webkit.WebSettings#setLayoutAlgorithm}.
1139      */
1140     public void setLayoutAlgorithm(LayoutAlgorithm l) {
1141         synchronized (mAwSettingsLock) {
1142             if (mLayoutAlgorithm != l) {
1143                 mLayoutAlgorithm = l;
1144                 mEventHandler.updateWebkitPreferencesLocked();
1145             }
1146         }
1147     }
1148
1149     /**
1150      * See {@link android.webkit.WebSettings#getLayoutAlgorithm}.
1151      */
1152     public LayoutAlgorithm getLayoutAlgorithm() {
1153         synchronized (mAwSettingsLock) {
1154             return mLayoutAlgorithm;
1155         }
1156     }
1157
1158     /**
1159      * Gets whether Text Auto-sizing layout algorithm is enabled.
1160      *
1161      * @return true if Text Auto-sizing layout algorithm is enabled
1162      */
1163     @CalledByNative
1164     private boolean getTextAutosizingEnabledLocked() {
1165         assert Thread.holdsLock(mAwSettingsLock);
1166         return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING;
1167     }
1168
1169     /**
1170      * See {@link android.webkit.WebSettings#setSupportMultipleWindows}.
1171      */
1172     public void setSupportMultipleWindows(boolean support) {
1173         synchronized (mAwSettingsLock) {
1174             if (mSupportMultipleWindows != support) {
1175                 mSupportMultipleWindows = support;
1176                 mEventHandler.updateWebkitPreferencesLocked();
1177             }
1178         }
1179     }
1180
1181     /**
1182      * See {@link android.webkit.WebSettings#supportMultipleWindows}.
1183      */
1184     public boolean supportMultipleWindows() {
1185         synchronized (mAwSettingsLock) {
1186             return mSupportMultipleWindows;
1187         }
1188     }
1189
1190     @CalledByNative
1191     private boolean getSupportMultipleWindowsLocked() {
1192         assert Thread.holdsLock(mAwSettingsLock);
1193         return mSupportMultipleWindows;
1194     }
1195
1196     @CalledByNative
1197     private boolean getSupportLegacyQuirksLocked() {
1198         assert Thread.holdsLock(mAwSettingsLock);
1199         return mSupportLegacyQuirks;
1200     }
1201
1202     /**
1203      * See {@link android.webkit.WebSettings#setUseWideViewPort}.
1204      */
1205     public void setUseWideViewPort(boolean use) {
1206         synchronized (mAwSettingsLock) {
1207             if (mUseWideViewport != use) {
1208                 mUseWideViewport = use;
1209                 onGestureZoomSupportChanged(
1210                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1211                 mEventHandler.updateWebkitPreferencesLocked();
1212             }
1213         }
1214     }
1215
1216     /**
1217      * See {@link android.webkit.WebSettings#getUseWideViewPort}.
1218      */
1219     public boolean getUseWideViewPort() {
1220         synchronized (mAwSettingsLock) {
1221             return getUseWideViewportLocked();
1222         }
1223     }
1224
1225     @CalledByNative
1226     private boolean getUseWideViewportLocked() {
1227         assert Thread.holdsLock(mAwSettingsLock);
1228         return mUseWideViewport;
1229     }
1230
1231     public void setZeroLayoutHeightDisablesViewportQuirk(boolean enabled) {
1232         synchronized (mAwSettingsLock) {
1233             if (mZeroLayoutHeightDisablesViewportQuirk != enabled) {
1234                 mZeroLayoutHeightDisablesViewportQuirk = enabled;
1235                 mEventHandler.updateWebkitPreferencesLocked();
1236             }
1237         }
1238     }
1239
1240     public boolean getZeroLayoutHeightDisablesViewportQuirk() {
1241         synchronized (mAwSettingsLock) {
1242             return getZeroLayoutHeightDisablesViewportQuirkLocked();
1243         }
1244     }
1245
1246     @CalledByNative
1247     private boolean getZeroLayoutHeightDisablesViewportQuirkLocked() {
1248         assert Thread.holdsLock(mAwSettingsLock);
1249         return mZeroLayoutHeightDisablesViewportQuirk;
1250     }
1251
1252     public void setForceZeroLayoutHeight(boolean enabled) {
1253         synchronized (mAwSettingsLock) {
1254             if (mForceZeroLayoutHeight != enabled) {
1255                 mForceZeroLayoutHeight = enabled;
1256                 mEventHandler.updateWebkitPreferencesLocked();
1257             }
1258         }
1259     }
1260
1261     public boolean getForceZeroLayoutHeight() {
1262         synchronized (mAwSettingsLock) {
1263             return getForceZeroLayoutHeightLocked();
1264         }
1265     }
1266
1267     @CalledByNative
1268     private boolean getForceZeroLayoutHeightLocked() {
1269         assert Thread.holdsLock(mAwSettingsLock);
1270         return mForceZeroLayoutHeight;
1271     }
1272
1273     @CalledByNative
1274     private boolean getPasswordEchoEnabledLocked() {
1275         assert Thread.holdsLock(mAwSettingsLock);
1276         return mPasswordEchoEnabled;
1277     }
1278
1279     /**
1280      * See {@link android.webkit.WebSettings#setAppCacheEnabled}.
1281      */
1282     public void setAppCacheEnabled(boolean flag) {
1283         synchronized (mAwSettingsLock) {
1284             if (mAppCacheEnabled != flag) {
1285                 mAppCacheEnabled = flag;
1286                 mEventHandler.updateWebkitPreferencesLocked();
1287             }
1288         }
1289     }
1290
1291     /**
1292      * See {@link android.webkit.WebSettings#setAppCachePath}.
1293      */
1294     public void setAppCachePath(String path) {
1295         boolean needToSync = false;
1296         synchronized (sGlobalContentSettingsLock) {
1297             // AppCachePath can only be set once.
1298             if (!sAppCachePathIsSet && path != null && !path.isEmpty()) {
1299                 sAppCachePathIsSet = true;
1300                 needToSync = true;
1301             }
1302         }
1303         // The obvious problem here is that other WebViews will not be updated,
1304         // until they execute synchronization from Java to the native side.
1305         // But this is the same behaviour as it was in the legacy WebView.
1306         if (needToSync) {
1307             synchronized (mAwSettingsLock) {
1308                 mEventHandler.updateWebkitPreferencesLocked();
1309             }
1310         }
1311     }
1312
1313     /**
1314      * Gets whether Application Cache is enabled.
1315      *
1316      * @return true if Application Cache is enabled
1317      */
1318     @CalledByNative
1319     private boolean getAppCacheEnabledLocked() {
1320         assert Thread.holdsLock(mAwSettingsLock);
1321         if (!mAppCacheEnabled) {
1322             return false;
1323         }
1324         synchronized (sGlobalContentSettingsLock) {
1325             return sAppCachePathIsSet;
1326         }
1327     }
1328
1329     /**
1330      * See {@link android.webkit.WebSettings#setDomStorageEnabled}.
1331      */
1332     public void setDomStorageEnabled(boolean flag) {
1333         synchronized (mAwSettingsLock) {
1334             if (mDomStorageEnabled != flag) {
1335                 mDomStorageEnabled = flag;
1336                 mEventHandler.updateWebkitPreferencesLocked();
1337             }
1338         }
1339     }
1340
1341     /**
1342      * See {@link android.webkit.WebSettings#getDomStorageEnabled}.
1343      */
1344     public boolean getDomStorageEnabled() {
1345         synchronized (mAwSettingsLock) {
1346             return mDomStorageEnabled;
1347         }
1348     }
1349
1350     @CalledByNative
1351     private boolean getDomStorageEnabledLocked() {
1352         assert Thread.holdsLock(mAwSettingsLock);
1353         return mDomStorageEnabled;
1354     }
1355
1356     /**
1357      * See {@link android.webkit.WebSettings#setDatabaseEnabled}.
1358      */
1359     public void setDatabaseEnabled(boolean flag) {
1360         synchronized (mAwSettingsLock) {
1361             if (mDatabaseEnabled != flag) {
1362                 mDatabaseEnabled = flag;
1363                 mEventHandler.updateWebkitPreferencesLocked();
1364             }
1365         }
1366     }
1367
1368     /**
1369      * See {@link android.webkit.WebSettings#getDatabaseEnabled}.
1370      */
1371     public boolean getDatabaseEnabled() {
1372         synchronized (mAwSettingsLock) {
1373             return mDatabaseEnabled;
1374         }
1375     }
1376
1377     @CalledByNative
1378     private boolean getDatabaseEnabledLocked() {
1379         assert Thread.holdsLock(mAwSettingsLock);
1380         return mDatabaseEnabled;
1381     }
1382
1383     /**
1384      * See {@link android.webkit.WebSettings#setDefaultTextEncodingName}.
1385      */
1386     public void setDefaultTextEncodingName(String encoding) {
1387         synchronized (mAwSettingsLock) {
1388             if (encoding != null && !mDefaultTextEncoding.equals(encoding)) {
1389                 mDefaultTextEncoding = encoding;
1390                 mEventHandler.updateWebkitPreferencesLocked();
1391             }
1392         }
1393     }
1394
1395     /**
1396      * See {@link android.webkit.WebSettings#getDefaultTextEncodingName}.
1397      */
1398     public String getDefaultTextEncodingName() {
1399         synchronized (mAwSettingsLock) {
1400             return getDefaultTextEncodingLocked();
1401         }
1402     }
1403
1404     @CalledByNative
1405     private String getDefaultTextEncodingLocked() {
1406         assert Thread.holdsLock(mAwSettingsLock);
1407         return mDefaultTextEncoding;
1408     }
1409
1410     /**
1411      * See {@link android.webkit.WebSettings#setMediaPlaybackRequiresUserGesture}.
1412      */
1413     public void setMediaPlaybackRequiresUserGesture(boolean require) {
1414         synchronized (mAwSettingsLock) {
1415             if (mMediaPlaybackRequiresUserGesture != require) {
1416                 mMediaPlaybackRequiresUserGesture = require;
1417                 mEventHandler.updateWebkitPreferencesLocked();
1418             }
1419         }
1420     }
1421
1422     /**
1423      * See {@link android.webkit.WebSettings#getMediaPlaybackRequiresUserGesture}.
1424      */
1425     public boolean getMediaPlaybackRequiresUserGesture() {
1426         synchronized (mAwSettingsLock) {
1427             return getMediaPlaybackRequiresUserGestureLocked();
1428         }
1429     }
1430
1431     @CalledByNative
1432     private boolean getMediaPlaybackRequiresUserGestureLocked() {
1433         assert Thread.holdsLock(mAwSettingsLock);
1434         return mMediaPlaybackRequiresUserGesture;
1435     }
1436
1437     /**
1438      * See {@link android.webkit.WebSettings#setDefaultVideoPosterURL}.
1439      */
1440     public void setDefaultVideoPosterURL(String url) {
1441         synchronized (mAwSettingsLock) {
1442             if (mDefaultVideoPosterURL != null && !mDefaultVideoPosterURL.equals(url) ||
1443                     mDefaultVideoPosterURL == null && url != null) {
1444                 mDefaultVideoPosterURL = url;
1445                 mEventHandler.updateWebkitPreferencesLocked();
1446             }
1447         }
1448     }
1449
1450     /**
1451      * See {@link android.webkit.WebSettings#getDefaultVideoPosterURL}.
1452      */
1453     public String getDefaultVideoPosterURL() {
1454         synchronized (mAwSettingsLock) {
1455             return getDefaultVideoPosterURLLocked();
1456         }
1457     }
1458
1459     @CalledByNative
1460     private String getDefaultVideoPosterURLLocked() {
1461         assert Thread.holdsLock(mAwSettingsLock);
1462         return mDefaultVideoPosterURL;
1463     }
1464
1465     private void onGestureZoomSupportChanged(
1466             final boolean supportsDoubleTapZoom, final boolean supportsMultiTouchZoom) {
1467         // Always post asynchronously here, to avoid doubling back onto the caller.
1468         mEventHandler.maybePostOnUiThread(new Runnable() {
1469             @Override
1470             public void run() {
1471                 synchronized (mAwSettingsLock) {
1472                     if (mZoomChangeListener != null) {
1473                         mZoomChangeListener.onGestureZoomSupportChanged(
1474                                 supportsDoubleTapZoom, supportsMultiTouchZoom);
1475                     }
1476                 }
1477             }
1478         });
1479     }
1480
1481     /**
1482      * See {@link android.webkit.WebSettings#setSupportZoom}.
1483      */
1484     public void setSupportZoom(boolean support) {
1485         synchronized (mAwSettingsLock) {
1486             if (mSupportZoom != support) {
1487                 mSupportZoom = support;
1488                 onGestureZoomSupportChanged(
1489                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1490             }
1491         }
1492     }
1493
1494     /**
1495      * See {@link android.webkit.WebSettings#supportZoom}.
1496      */
1497     public boolean supportZoom() {
1498         synchronized (mAwSettingsLock) {
1499             return mSupportZoom;
1500         }
1501     }
1502
1503     /**
1504      * See {@link android.webkit.WebSettings#setBuiltInZoomControls}.
1505      */
1506     public void setBuiltInZoomControls(boolean enabled) {
1507         synchronized (mAwSettingsLock) {
1508             if (mBuiltInZoomControls != enabled) {
1509                 mBuiltInZoomControls = enabled;
1510                 onGestureZoomSupportChanged(
1511                         supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
1512             }
1513         }
1514     }
1515
1516     /**
1517      * See {@link android.webkit.WebSettings#getBuiltInZoomControls}.
1518      */
1519     public boolean getBuiltInZoomControls() {
1520         synchronized (mAwSettingsLock) {
1521             return mBuiltInZoomControls;
1522         }
1523     }
1524
1525     /**
1526      * See {@link android.webkit.WebSettings#setDisplayZoomControls}.
1527      */
1528     public void setDisplayZoomControls(boolean enabled) {
1529         synchronized (mAwSettingsLock) {
1530             mDisplayZoomControls = enabled;
1531         }
1532     }
1533
1534     /**
1535      * See {@link android.webkit.WebSettings#getDisplayZoomControls}.
1536      */
1537     public boolean getDisplayZoomControls() {
1538         synchronized (mAwSettingsLock) {
1539             return mDisplayZoomControls;
1540         }
1541     }
1542
1543     public void setMixedContentMode(int mode) {
1544         synchronized (mAwSettingsLock) {
1545             if (mMixedContentMode != mode) {
1546                 mMixedContentMode = mode;
1547                 mEventHandler.updateWebkitPreferencesLocked();
1548             }
1549         }
1550     }
1551
1552     public int getMixedContentMode() {
1553         synchronized (mAwSettingsLock) {
1554             return mMixedContentMode;
1555         }
1556     }
1557
1558     @CalledByNative
1559     private boolean getAllowRunningInsecureContentLocked() {
1560         assert Thread.holdsLock(mAwSettingsLock);
1561         return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW;
1562     }
1563
1564     @CalledByNative
1565     private boolean getAllowDisplayingInsecureContentLocked() {
1566         assert Thread.holdsLock(mAwSettingsLock);
1567         return mMixedContentMode == MIXED_CONTENT_ALWAYS_ALLOW ||
1568                 mMixedContentMode == MIXED_CONTENT_COMPATIBILITY_MODE;
1569     }
1570
1571     /**
1572      * Sets whether to use the video overlay for the embedded video.
1573      * @param flag whether to enable the video overlay for the embedded video.
1574      */
1575     public void setVideoOverlayForEmbeddedVideoEnabled(final boolean enabled) {
1576         synchronized (mAwSettingsLock) {
1577             if (mVideoOverlayForEmbeddedVideoEnabled != enabled) {
1578                 mVideoOverlayForEmbeddedVideoEnabled = enabled;
1579                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
1580                     @Override
1581                     public void run() {
1582                         if (mNativeAwSettings != 0) {
1583                             nativeUpdateRendererPreferencesLocked(mNativeAwSettings);
1584                         }
1585                     }
1586                 });
1587             }
1588         }
1589     }
1590
1591     /**
1592      * Gets whether to use the video overlay for the embedded video.
1593      * @return true if the WebView enables the video overlay for the embedded video.
1594      */
1595     public boolean getVideoOverlayForEmbeddedVideoEnabled() {
1596         synchronized (mAwSettingsLock) {
1597             return getVideoOverlayForEmbeddedVideoEnabledLocked();
1598         }
1599     }
1600
1601     @CalledByNative
1602     private boolean getVideoOverlayForEmbeddedVideoEnabledLocked() {
1603         assert Thread.holdsLock(mAwSettingsLock);
1604         return mVideoOverlayForEmbeddedVideoEnabled;
1605     }
1606
1607     @CalledByNative
1608     private boolean supportsDoubleTapZoomLocked() {
1609         assert Thread.holdsLock(mAwSettingsLock);
1610         return mSupportZoom && mBuiltInZoomControls && mUseWideViewport;
1611     }
1612
1613     private boolean supportsMultiTouchZoomLocked() {
1614         assert Thread.holdsLock(mAwSettingsLock);
1615         return mSupportZoom && mBuiltInZoomControls;
1616     }
1617
1618     boolean supportsMultiTouchZoom() {
1619         synchronized (mAwSettingsLock) {
1620             return supportsMultiTouchZoomLocked();
1621         }
1622     }
1623
1624     boolean shouldDisplayZoomControls() {
1625         synchronized (mAwSettingsLock) {
1626             return supportsMultiTouchZoomLocked() && mDisplayZoomControls;
1627         }
1628     }
1629
1630     private int clipFontSize(int size) {
1631         if (size < MINIMUM_FONT_SIZE) {
1632             return MINIMUM_FONT_SIZE;
1633         } else if (size > MAXIMUM_FONT_SIZE) {
1634             return MAXIMUM_FONT_SIZE;
1635         }
1636         return size;
1637     }
1638
1639     @CalledByNative
1640     private void updateEverything() {
1641         synchronized (mAwSettingsLock) {
1642             updateEverythingLocked();
1643         }
1644     }
1645
1646     @CalledByNative
1647     private void populateWebPreferences(long webPrefsPtr) {
1648         synchronized (mAwSettingsLock) {
1649             assert mNativeAwSettings != 0;
1650             nativePopulateWebPreferencesLocked(mNativeAwSettings, webPrefsPtr);
1651         }
1652     }
1653
1654     private void updateWebkitPreferencesOnUiThreadLocked() {
1655         assert mEventHandler.mHandler != null;
1656         ThreadUtils.assertOnUiThread();
1657         if (mNativeAwSettings != 0) {
1658             nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
1659         }
1660     }
1661
1662     private native long nativeInit(long webContentsPtr);
1663
1664     private native void nativeDestroy(long nativeAwSettings);
1665
1666     private native void nativePopulateWebPreferencesLocked(long nativeAwSettings, long webPrefsPtr);
1667
1668     private native void nativeResetScrollAndScaleState(long nativeAwSettings);
1669
1670     private native void nativeUpdateEverythingLocked(long nativeAwSettings);
1671
1672     private native void nativeUpdateInitialPageScaleLocked(long nativeAwSettings);
1673
1674     private native void nativeUpdateUserAgentLocked(long nativeAwSettings);
1675
1676     private native void nativeUpdateWebkitPreferencesLocked(long nativeAwSettings);
1677
1678     private static native String nativeGetDefaultUserAgent();
1679
1680     private native void nativeUpdateFormDataPreferencesLocked(long nativeAwSettings);
1681
1682     private native void nativeUpdateRendererPreferencesLocked(long nativeAwSettings);
1683 }