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