WebSettingsClassic.java revision 92a5be96d8af6a47e31b8db9467123292ea73fb0
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.webkit;
18
19import android.content.Context;
20import android.content.SharedPreferences;
21import android.content.pm.PackageManager;
22import android.os.Build;
23import android.os.Handler;
24import android.os.Message;
25import android.provider.Settings;
26import android.provider.Settings.SettingNotFoundException;
27import android.util.EventLog;
28
29import java.util.Locale;
30
31/**
32 * WebSettings implementation for the WebViewClassic implementation of WebView.
33 * @hide
34 */
35public class WebSettingsClassic extends WebSettings {
36    // TODO: Keep this up to date
37    private static final String PREVIOUS_VERSION = "4.1.1";
38
39    // WebView associated with this WebSettings.
40    private WebViewClassic mWebView;
41    // BrowserFrame used to access the native frame pointer.
42    private BrowserFrame mBrowserFrame;
43    // Flag to prevent multiple SYNC messages at one time.
44    private boolean mSyncPending = false;
45    // Custom handler that queues messages until the WebCore thread is active.
46    private final EventHandler mEventHandler;
47
48    // Private settings so we don't have to go into native code to
49    // retrieve the values. After setXXX, postSync() needs to be called.
50    //
51    // The default values need to match those in WebSettings.cpp
52    // If the defaults change, please also update the JavaDocs so developers
53    // know what they are.
54    private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
55    private Context         mContext;
56    private int             mTextSize = 100;
57    private String          mStandardFontFamily = "sans-serif";
58    private String          mFixedFontFamily = "monospace";
59    private String          mSansSerifFontFamily = "sans-serif";
60    private String          mSerifFontFamily = "serif";
61    private String          mCursiveFontFamily = "cursive";
62    private String          mFantasyFontFamily = "fantasy";
63    private String          mDefaultTextEncoding;
64    private String          mUserAgent;
65    private boolean         mUseDefaultUserAgent;
66    private String          mAcceptLanguage;
67    private int             mMinimumFontSize = 8;
68    private int             mMinimumLogicalFontSize = 8;
69    private int             mDefaultFontSize = 16;
70    private int             mDefaultFixedFontSize = 13;
71    private int             mPageCacheCapacity = 0;
72    private boolean         mLoadsImagesAutomatically = true;
73    private boolean         mBlockNetworkImage = false;
74    private boolean         mBlockNetworkLoads;
75    private boolean         mJavaScriptEnabled = false;
76    private boolean         mAllowUniversalAccessFromFileURLs = false;
77    private boolean         mAllowFileAccessFromFileURLs = false;
78    private boolean         mHardwareAccelSkia = false;
79    private boolean         mShowVisualIndicator = false;
80    private PluginState     mPluginState = PluginState.OFF;
81    private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
82    private boolean         mUseDoubleTree = false;
83    private boolean         mUseWideViewport = false;
84    private boolean         mSupportMultipleWindows = false;
85    private boolean         mShrinksStandaloneImagesToFit = false;
86    private long            mMaximumDecodedImageSize = 0; // 0 means default
87    private boolean         mPrivateBrowsingEnabled = false;
88    private boolean         mSyntheticLinksEnabled = true;
89    // HTML5 API flags
90    private boolean         mAppCacheEnabled = false;
91    private boolean         mDatabaseEnabled = false;
92    private boolean         mDomStorageEnabled = false;
93    private boolean         mWorkersEnabled = false;  // only affects V8.
94    private boolean         mGeolocationEnabled = true;
95    private boolean         mXSSAuditorEnabled = false;
96    private boolean         mLinkPrefetchEnabled = false;
97    // HTML5 configuration parameters
98    private long            mAppCacheMaxSize = Long.MAX_VALUE;
99    private String          mAppCachePath = null;
100    private String          mDatabasePath = "";
101    // The WebCore DatabaseTracker only allows the database path to be set
102    // once. Keep track of when the path has been set.
103    private boolean         mDatabasePathHasBeenSet = false;
104    private String          mGeolocationDatabasePath = "";
105    // Don't need to synchronize the get/set methods as they
106    // are basic types, also none of these values are used in
107    // native WebCore code.
108    private ZoomDensity     mDefaultZoom = ZoomDensity.MEDIUM;
109    private RenderPriority  mRenderPriority = RenderPriority.NORMAL;
110    private int             mOverrideCacheMode = LOAD_DEFAULT;
111    private int             mDoubleTapZoom = 100;
112    private boolean         mSaveFormData = true;
113    private boolean         mAutoFillEnabled = false;
114    private boolean         mSavePassword = true;
115    private boolean         mLightTouchEnabled = false;
116    private boolean         mNeedInitialFocus = true;
117    private boolean         mNavDump = false;
118    private boolean         mSupportZoom = true;
119    private boolean         mMediaPlaybackRequiresUserGesture = true;
120    private boolean         mBuiltInZoomControls = false;
121    private boolean         mDisplayZoomControls = true;
122    private boolean         mAllowFileAccess = true;
123    private boolean         mAllowContentAccess = true;
124    private boolean         mLoadWithOverviewMode = false;
125    private boolean         mEnableSmoothTransition = false;
126    private boolean         mForceUserScalable = false;
127    private boolean         mPasswordEchoEnabled = true;
128
129    // AutoFill Profile data
130    public static class AutoFillProfile {
131        private int mUniqueId;
132        private String mFullName;
133        private String mEmailAddress;
134        private String mCompanyName;
135        private String mAddressLine1;
136        private String mAddressLine2;
137        private String mCity;
138        private String mState;
139        private String mZipCode;
140        private String mCountry;
141        private String mPhoneNumber;
142
143        public AutoFillProfile(int uniqueId, String fullName, String email,
144                String companyName, String addressLine1, String addressLine2,
145                String city, String state, String zipCode, String country,
146                String phoneNumber) {
147            mUniqueId = uniqueId;
148            mFullName = fullName;
149            mEmailAddress = email;
150            mCompanyName = companyName;
151            mAddressLine1 = addressLine1;
152            mAddressLine2 = addressLine2;
153            mCity = city;
154            mState = state;
155            mZipCode = zipCode;
156            mCountry = country;
157            mPhoneNumber = phoneNumber;
158        }
159
160        public int getUniqueId() { return mUniqueId; }
161        public String getFullName() { return mFullName; }
162        public String getEmailAddress() { return mEmailAddress; }
163        public String getCompanyName() { return mCompanyName; }
164        public String getAddressLine1() { return mAddressLine1; }
165        public String getAddressLine2() { return mAddressLine2; }
166        public String getCity() { return mCity; }
167        public String getState() { return mState; }
168        public String getZipCode() { return mZipCode; }
169        public String getCountry() { return mCountry; }
170        public String getPhoneNumber() { return mPhoneNumber; }
171    }
172
173
174    private AutoFillProfile mAutoFillProfile;
175
176    private boolean         mUseWebViewBackgroundForOverscroll = true;
177
178    // private WebSettings, not accessible by the host activity
179    static private int      mDoubleTapToastCount = 3;
180
181    private static final String PREF_FILE = "WebViewSettings";
182    private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count";
183
184    // Class to handle messages before WebCore is ready.
185    private class EventHandler {
186        // Message id for syncing
187        static final int SYNC = 0;
188        // Message id for setting priority
189        static final int PRIORITY = 1;
190        // Message id for writing double-tap toast count
191        static final int SET_DOUBLE_TAP_TOAST_COUNT = 2;
192        // Actual WebCore thread handler
193        private Handler mHandler;
194
195        private synchronized void createHandler() {
196            // as mRenderPriority can be set before thread is running, sync up
197            setRenderPriority();
198
199            // create a new handler
200            mHandler = new Handler() {
201                @Override
202                public void handleMessage(Message msg) {
203                    switch (msg.what) {
204                        case SYNC:
205                            synchronized (WebSettingsClassic.this) {
206                                if (mBrowserFrame.mNativeFrame != 0) {
207                                    nativeSync(mBrowserFrame.mNativeFrame);
208                                }
209                                mSyncPending = false;
210                            }
211                            break;
212
213                        case PRIORITY: {
214                            setRenderPriority();
215                            break;
216                        }
217
218                        case SET_DOUBLE_TAP_TOAST_COUNT: {
219                            SharedPreferences.Editor editor = mContext
220                                    .getSharedPreferences(PREF_FILE,
221                                            Context.MODE_PRIVATE).edit();
222                            editor.putInt(DOUBLE_TAP_TOAST_COUNT,
223                                    mDoubleTapToastCount);
224                            editor.commit();
225                            break;
226                        }
227                    }
228                }
229            };
230        }
231
232        private void setRenderPriority() {
233            synchronized (WebSettingsClassic.this) {
234                if (mRenderPriority == RenderPriority.NORMAL) {
235                    android.os.Process.setThreadPriority(
236                            android.os.Process.THREAD_PRIORITY_DEFAULT);
237                } else if (mRenderPriority == RenderPriority.HIGH) {
238                    android.os.Process.setThreadPriority(
239                            android.os.Process.THREAD_PRIORITY_FOREGROUND +
240                            android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
241                } else if (mRenderPriority == RenderPriority.LOW) {
242                    android.os.Process.setThreadPriority(
243                            android.os.Process.THREAD_PRIORITY_BACKGROUND);
244                }
245            }
246        }
247
248        /**
249         * Send a message to the private queue or handler.
250         */
251        private synchronized boolean sendMessage(Message msg) {
252            if (mHandler != null) {
253                mHandler.sendMessage(msg);
254                return true;
255            } else {
256                return false;
257            }
258        }
259    }
260
261    // User agent strings.
262    private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
263        "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
264        "Chrome/11.0.696.34 Safari/534.24";
265    private static final String IPHONE_USERAGENT =
266            "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)"
267            + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0"
268            + " Mobile/7A341 Safari/528.16";
269    private static Locale sLocale;
270    private static Object sLockForLocaleSettings;
271
272    /**
273     * Package constructor to prevent clients from creating a new settings
274     * instance.
275     */
276    WebSettingsClassic(Context context, WebViewClassic webview) {
277        mEventHandler = new EventHandler();
278        mContext = context;
279        mWebView = webview;
280        mDefaultTextEncoding = context.getString(com.android.internal.
281                                                 R.string.default_text_encoding);
282
283        if (sLockForLocaleSettings == null) {
284            sLockForLocaleSettings = new Object();
285            sLocale = Locale.getDefault();
286        }
287        mAcceptLanguage = getCurrentAcceptLanguage();
288        mUserAgent = getCurrentUserAgent();
289        mUseDefaultUserAgent = true;
290
291        mBlockNetworkLoads = mContext.checkPermission(
292                "android.permission.INTERNET", android.os.Process.myPid(),
293                android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
294
295        // SDK specific settings. See issue 6212665
296        if (mContext.getApplicationInfo().targetSdkVersion <
297                Build.VERSION_CODES.JELLY_BEAN) {
298            mAllowUniversalAccessFromFileURLs = true;
299            mAllowFileAccessFromFileURLs = true;
300        }
301        try {
302            mPasswordEchoEnabled =
303                    Settings.System.getInt(context.getContentResolver(),
304                        Settings.System.TEXT_SHOW_PASSWORD) != 0;
305        } catch (SettingNotFoundException e) {
306            mPasswordEchoEnabled = true;
307        }
308    }
309
310    private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
311
312    /**
313     * Looks at sLocale and returns current AcceptLanguage String.
314     * @return Current AcceptLanguage String.
315     */
316    private String getCurrentAcceptLanguage() {
317        Locale locale;
318        synchronized(sLockForLocaleSettings) {
319            locale = sLocale;
320        }
321        StringBuilder buffer = new StringBuilder();
322        addLocaleToHttpAcceptLanguage(buffer, locale);
323
324        if (!Locale.US.equals(locale)) {
325            if (buffer.length() > 0) {
326                buffer.append(", ");
327            }
328            buffer.append(ACCEPT_LANG_FOR_US_LOCALE);
329        }
330
331        return buffer.toString();
332    }
333
334    /**
335     * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish,
336     * to new standard.
337     */
338    private static String convertObsoleteLanguageCodeToNew(String langCode) {
339        if (langCode == null) {
340            return null;
341        }
342        if ("iw".equals(langCode)) {
343            // Hebrew
344            return "he";
345        } else if ("in".equals(langCode)) {
346            // Indonesian
347            return "id";
348        } else if ("ji".equals(langCode)) {
349            // Yiddish
350            return "yi";
351        }
352        return langCode;
353    }
354
355    private static void addLocaleToHttpAcceptLanguage(StringBuilder builder,
356                                                      Locale locale) {
357        String language = convertObsoleteLanguageCodeToNew(locale.getLanguage());
358        if (language != null) {
359            builder.append(language);
360            String country = locale.getCountry();
361            if (country != null) {
362                builder.append("-");
363                builder.append(country);
364            }
365        }
366    }
367
368    /**
369     * Looks at sLocale and mContext and returns current UserAgent String.
370     * @return Current UserAgent String.
371     */
372    private synchronized String getCurrentUserAgent() {
373        Locale locale;
374        synchronized(sLockForLocaleSettings) {
375            locale = sLocale;
376        }
377        StringBuffer buffer = new StringBuffer();
378        // Add version
379        final String version = Build.VERSION.RELEASE;
380        if (version.length() > 0) {
381            if (Character.isDigit(version.charAt(0))) {
382                // Release is a version, eg "3.1"
383                buffer.append(version);
384            } else {
385                // Release is a codename, eg "Honeycomb"
386                // In this case, use the previous release's version
387                buffer.append(PREVIOUS_VERSION);
388            }
389        } else {
390            // default to "1.0"
391            buffer.append("1.0");
392        }
393        buffer.append("; ");
394        final String language = locale.getLanguage();
395        if (language != null) {
396            buffer.append(convertObsoleteLanguageCodeToNew(language));
397            final String country = locale.getCountry();
398            if (country != null) {
399                buffer.append("-");
400                buffer.append(country.toLowerCase());
401            }
402        } else {
403            // default to "en"
404            buffer.append("en");
405        }
406        buffer.append(";");
407        // add the model for the release build
408        if ("REL".equals(Build.VERSION.CODENAME)) {
409            final String model = Build.MODEL;
410            if (model.length() > 0) {
411                buffer.append(" ");
412                buffer.append(model);
413            }
414        }
415        final String id = Build.ID;
416        if (id.length() > 0) {
417            buffer.append(" Build/");
418            buffer.append(id);
419        }
420        String mobile = mContext.getResources().getText(
421            com.android.internal.R.string.web_user_agent_target_content).toString();
422        final String base = mContext.getResources().getText(
423                com.android.internal.R.string.web_user_agent).toString();
424        return String.format(base, buffer, mobile);
425    }
426
427    /**
428     * @see android.webkit.WebSettings#setNavDump(boolean)
429     */
430    @Override
431    @Deprecated
432    public void setNavDump(boolean enabled) {
433        mNavDump = enabled;
434    }
435
436    /**
437     * @see android.webkit.WebSettings#getNavDump()
438     */
439    @Override
440    @Deprecated
441    public boolean getNavDump() {
442        return mNavDump;
443    }
444
445    /**
446     * @see android.webkit.WebSettings#setSupportZoom(boolean)
447     */
448    @Override
449    public void setSupportZoom(boolean support) {
450        mSupportZoom = support;
451        mWebView.updateMultiTouchSupport(mContext);
452    }
453
454    /**
455     * @see android.webkit.WebSettings#supportZoom()
456     */
457    @Override
458    public boolean supportZoom() {
459        return mSupportZoom;
460    }
461
462    /**
463     * @see android.webkit.WebSettings#setMediaPlaybackRequiresUserGesture(boolean)
464     */
465    @Override
466    public void setMediaPlaybackRequiresUserGesture(boolean support) {
467        if (mMediaPlaybackRequiresUserGesture != support) {
468            mMediaPlaybackRequiresUserGesture = support;
469            postSync();
470        }
471    }
472
473    /**
474     * @see android.webkit.WebSettings#getMediaPlaybackRequiresUserGesture()
475     */
476    @Override
477    public boolean getMediaPlaybackRequiresUserGesture() {
478        return mMediaPlaybackRequiresUserGesture;
479    }
480
481    /**
482     * @see android.webkit.WebSettings#setBuiltInZoomControls(boolean)
483     */
484    @Override
485    public void setBuiltInZoomControls(boolean enabled) {
486        mBuiltInZoomControls = enabled;
487        mWebView.updateMultiTouchSupport(mContext);
488    }
489
490    /**
491     * @see android.webkit.WebSettings#getBuiltInZoomControls()
492     */
493    @Override
494    public boolean getBuiltInZoomControls() {
495        return mBuiltInZoomControls;
496    }
497
498    /**
499     * @see android.webkit.WebSettings#setDisplayZoomControls(boolean)
500     */
501    @Override
502    public void setDisplayZoomControls(boolean enabled) {
503        mDisplayZoomControls = enabled;
504        mWebView.updateMultiTouchSupport(mContext);
505    }
506
507    /**
508     * @see android.webkit.WebSettings#getDisplayZoomControls()
509     */
510    @Override
511    public boolean getDisplayZoomControls() {
512        return mDisplayZoomControls;
513    }
514
515    /**
516     * @see android.webkit.WebSettings#setAllowFileAccess(boolean)
517     */
518    @Override
519    public void setAllowFileAccess(boolean allow) {
520        mAllowFileAccess = allow;
521    }
522
523    /**
524     * @see android.webkit.WebSettings#getAllowFileAccess()
525     */
526    @Override
527    public boolean getAllowFileAccess() {
528        return mAllowFileAccess;
529    }
530
531    /**
532     * @see android.webkit.WebSettings#setAllowContentAccess(boolean)
533     */
534    @Override
535    public void setAllowContentAccess(boolean allow) {
536        mAllowContentAccess = allow;
537    }
538
539    /**
540     * @see android.webkit.WebSettings#getAllowContentAccess()
541     */
542    @Override
543    public boolean getAllowContentAccess() {
544        return mAllowContentAccess;
545    }
546
547    /**
548     * @see android.webkit.WebSettings#setLoadWithOverviewMode(boolean)
549     */
550    @Override
551    public void setLoadWithOverviewMode(boolean overview) {
552        mLoadWithOverviewMode = overview;
553    }
554
555    /**
556     * @see android.webkit.WebSettings#getLoadWithOverviewMode()
557     */
558    @Override
559    public boolean getLoadWithOverviewMode() {
560        return mLoadWithOverviewMode;
561    }
562
563    /**
564     * @see android.webkit.WebSettings#setEnableSmoothTransition(boolean)
565     */
566    @Override
567    public void setEnableSmoothTransition(boolean enable) {
568        mEnableSmoothTransition = enable;
569    }
570
571    /**
572     * @see android.webkit.WebSettings#enableSmoothTransition()
573     */
574    @Override
575    public boolean enableSmoothTransition() {
576        return mEnableSmoothTransition;
577    }
578
579    /**
580     * @see android.webkit.WebSettings#setUseWebViewBackgroundForOverscrollBackground(boolean)
581     */
582    @Override
583    @Deprecated
584    public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
585        mUseWebViewBackgroundForOverscroll = view;
586    }
587
588    /**
589     * @see android.webkit.WebSettings#getUseWebViewBackgroundForOverscrollBackground()
590     */
591    @Override
592    @Deprecated
593    public boolean getUseWebViewBackgroundForOverscrollBackground() {
594        return mUseWebViewBackgroundForOverscroll;
595    }
596
597    /**
598     * @see android.webkit.WebSettings#setSaveFormData(boolean)
599     */
600    @Override
601    public void setSaveFormData(boolean save) {
602        mSaveFormData = save;
603    }
604
605    /**
606     * @see android.webkit.WebSettings#getSaveFormData()
607     */
608    @Override
609    public boolean getSaveFormData() {
610        return mSaveFormData && !mPrivateBrowsingEnabled;
611    }
612
613    /**
614     * @see android.webkit.WebSettings#setSavePassword(boolean)
615     */
616    @Override
617    public void setSavePassword(boolean save) {
618        mSavePassword = save;
619    }
620
621    /**
622     * @see android.webkit.WebSettings#getSavePassword()
623     */
624    @Override
625    public boolean getSavePassword() {
626        return mSavePassword;
627    }
628
629    /**
630     * @see android.webkit.WebSettings#setTextZoom(int)
631     */
632    @Override
633    public synchronized void setTextZoom(int textZoom) {
634        if (mTextSize != textZoom) {
635            if (WebViewClassic.mLogEvent) {
636                EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
637                        mTextSize, textZoom);
638            }
639            mTextSize = textZoom;
640            postSync();
641        }
642    }
643
644    /**
645     * @see android.webkit.WebSettings#getTextZoom()
646     */
647    @Override
648    public synchronized int getTextZoom() {
649        return mTextSize;
650    }
651
652    /**
653     * @see android.webkit.WebSettings#setTextSize(android.webkit.WebSettingsClassic.TextSize)
654     */
655    @Override
656    public synchronized void setTextSize(TextSize t) {
657        setTextZoom(t.value);
658    }
659
660    /**
661     * @see android.webkit.WebSettings#getTextSize()
662     */
663    @Override
664    public synchronized TextSize getTextSize() {
665        TextSize closestSize = null;
666        int smallestDelta = Integer.MAX_VALUE;
667        for (TextSize size : TextSize.values()) {
668            int delta = Math.abs(mTextSize - size.value);
669            if (delta == 0) {
670                return size;
671            }
672            if (delta < smallestDelta) {
673                smallestDelta = delta;
674                closestSize = size;
675            }
676        }
677        return closestSize != null ? closestSize : TextSize.NORMAL;
678    }
679
680    /**
681     * Set the double-tap zoom of the page in percent. Default is 100.
682     * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
683     */
684    public void setDoubleTapZoom(int doubleTapZoom) {
685        if (mDoubleTapZoom != doubleTapZoom) {
686            mDoubleTapZoom = doubleTapZoom;
687            mWebView.updateDoubleTapZoom(doubleTapZoom);
688        }
689    }
690
691    /**
692     * Get the double-tap zoom of the page in percent.
693     * @return A percent value describing the double-tap zoom.
694     */
695    public int getDoubleTapZoom() {
696        return mDoubleTapZoom;
697    }
698
699    /**
700     * @see android.webkit.WebSettings#setDefaultZoom(android.webkit.WebSettingsClassic.ZoomDensity)
701     */
702    @Override
703    public void setDefaultZoom(ZoomDensity zoom) {
704        if (mDefaultZoom != zoom) {
705            mDefaultZoom = zoom;
706            mWebView.adjustDefaultZoomDensity(zoom.value);
707        }
708    }
709
710    /**
711     * @see android.webkit.WebSettings#getDefaultZoom()
712     */
713    @Override
714    public ZoomDensity getDefaultZoom() {
715        return mDefaultZoom;
716    }
717
718    /**
719     * @see android.webkit.WebSettings#setLightTouchEnabled(boolean)
720     */
721    @Override
722    public void setLightTouchEnabled(boolean enabled) {
723        mLightTouchEnabled = enabled;
724    }
725
726    /**
727     * @see android.webkit.WebSettings#getLightTouchEnabled()
728     */
729    @Override
730    public boolean getLightTouchEnabled() {
731        return mLightTouchEnabled;
732    }
733
734    /**
735     * @see android.webkit.WebSettings#setUseDoubleTree(boolean)
736     */
737    @Override
738    @Deprecated
739    public synchronized void setUseDoubleTree(boolean use) {
740        return;
741    }
742
743    /**
744     * @see android.webkit.WebSettings#getUseDoubleTree()
745     */
746    @Override
747    @Deprecated
748    public synchronized boolean getUseDoubleTree() {
749        return false;
750    }
751
752    /**
753     * @see android.webkit.WebSettings#setUserAgent(int)
754     */
755    @Override
756    @Deprecated
757    public synchronized void setUserAgent(int ua) {
758        String uaString = null;
759        if (ua == 1) {
760            if (DESKTOP_USERAGENT.equals(mUserAgent)) {
761                return; // do nothing
762            } else {
763                uaString = DESKTOP_USERAGENT;
764            }
765        } else if (ua == 2) {
766            if (IPHONE_USERAGENT.equals(mUserAgent)) {
767                return; // do nothing
768            } else {
769                uaString = IPHONE_USERAGENT;
770            }
771        } else if (ua != 0) {
772            return; // do nothing
773        }
774        setUserAgentString(uaString);
775    }
776
777    /**
778     * @see android.webkit.WebSettings#getUserAgent()
779     */
780    @Override
781    @Deprecated
782    public synchronized int getUserAgent() {
783        if (DESKTOP_USERAGENT.equals(mUserAgent)) {
784            return 1;
785        } else if (IPHONE_USERAGENT.equals(mUserAgent)) {
786            return 2;
787        } else if (mUseDefaultUserAgent) {
788            return 0;
789        }
790        return -1;
791    }
792
793    /**
794     * @see android.webkit.WebSettings#setUseWideViewPort(boolean)
795     */
796    @Override
797    public synchronized void setUseWideViewPort(boolean use) {
798        if (mUseWideViewport != use) {
799            mUseWideViewport = use;
800            postSync();
801        }
802    }
803
804    /**
805     * @see android.webkit.WebSettings#getUseWideViewPort()
806     */
807    @Override
808    public synchronized boolean getUseWideViewPort() {
809        return mUseWideViewport;
810    }
811
812    /**
813     * @see android.webkit.WebSettings#setSupportMultipleWindows(boolean)
814     */
815    @Override
816    public synchronized void setSupportMultipleWindows(boolean support) {
817        if (mSupportMultipleWindows != support) {
818            mSupportMultipleWindows = support;
819            postSync();
820        }
821    }
822
823    /**
824     * @see android.webkit.WebSettings#supportMultipleWindows()
825     */
826    @Override
827    public synchronized boolean supportMultipleWindows() {
828        return mSupportMultipleWindows;
829    }
830
831    /**
832     * @see android.webkit.WebSettings#setLayoutAlgorithm(android.webkit.WebSettingsClassic.LayoutAlgorithm)
833     */
834    @Override
835    public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
836        // XXX: This will only be affective if libwebcore was built with
837        // ANDROID_LAYOUT defined.
838        if (mLayoutAlgorithm != l) {
839            mLayoutAlgorithm = l;
840            postSync();
841        }
842    }
843
844    /**
845     * @see android.webkit.WebSettings#getLayoutAlgorithm()
846     */
847    @Override
848    public synchronized LayoutAlgorithm getLayoutAlgorithm() {
849        return mLayoutAlgorithm;
850    }
851
852    /**
853     * @see android.webkit.WebSettings#setStandardFontFamily(java.lang.String)
854     */
855    @Override
856    public synchronized void setStandardFontFamily(String font) {
857        if (font != null && !font.equals(mStandardFontFamily)) {
858            mStandardFontFamily = font;
859            postSync();
860        }
861    }
862
863    /**
864     * @see android.webkit.WebSettings#getStandardFontFamily()
865     */
866    @Override
867    public synchronized String getStandardFontFamily() {
868        return mStandardFontFamily;
869    }
870
871    /**
872     * @see android.webkit.WebSettings#setFixedFontFamily(java.lang.String)
873     */
874    @Override
875    public synchronized void setFixedFontFamily(String font) {
876        if (font != null && !font.equals(mFixedFontFamily)) {
877            mFixedFontFamily = font;
878            postSync();
879        }
880    }
881
882    /**
883     * @see android.webkit.WebSettings#getFixedFontFamily()
884     */
885    @Override
886    public synchronized String getFixedFontFamily() {
887        return mFixedFontFamily;
888    }
889
890    /**
891     * @see android.webkit.WebSettings#setSansSerifFontFamily(java.lang.String)
892     */
893    @Override
894    public synchronized void setSansSerifFontFamily(String font) {
895        if (font != null && !font.equals(mSansSerifFontFamily)) {
896            mSansSerifFontFamily = font;
897            postSync();
898        }
899    }
900
901    /**
902     * @see android.webkit.WebSettings#getSansSerifFontFamily()
903     */
904    @Override
905    public synchronized String getSansSerifFontFamily() {
906        return mSansSerifFontFamily;
907    }
908
909    /**
910     * @see android.webkit.WebSettings#setSerifFontFamily(java.lang.String)
911     */
912    @Override
913    public synchronized void setSerifFontFamily(String font) {
914        if (font != null && !font.equals(mSerifFontFamily)) {
915            mSerifFontFamily = font;
916            postSync();
917        }
918    }
919
920    /**
921     * @see android.webkit.WebSettings#getSerifFontFamily()
922     */
923    @Override
924    public synchronized String getSerifFontFamily() {
925        return mSerifFontFamily;
926    }
927
928    /**
929     * @see android.webkit.WebSettings#setCursiveFontFamily(java.lang.String)
930     */
931    @Override
932    public synchronized void setCursiveFontFamily(String font) {
933        if (font != null && !font.equals(mCursiveFontFamily)) {
934            mCursiveFontFamily = font;
935            postSync();
936        }
937    }
938
939    /**
940     * @see android.webkit.WebSettings#getCursiveFontFamily()
941     */
942    @Override
943    public synchronized String getCursiveFontFamily() {
944        return mCursiveFontFamily;
945    }
946
947    /**
948     * @see android.webkit.WebSettings#setFantasyFontFamily(java.lang.String)
949     */
950    @Override
951    public synchronized void setFantasyFontFamily(String font) {
952        if (font != null && !font.equals(mFantasyFontFamily)) {
953            mFantasyFontFamily = font;
954            postSync();
955        }
956    }
957
958    /**
959     * @see android.webkit.WebSettings#getFantasyFontFamily()
960     */
961    @Override
962    public synchronized String getFantasyFontFamily() {
963        return mFantasyFontFamily;
964    }
965
966    /**
967     * @see android.webkit.WebSettings#setMinimumFontSize(int)
968     */
969    @Override
970    public synchronized void setMinimumFontSize(int size) {
971        size = pin(size);
972        if (mMinimumFontSize != size) {
973            mMinimumFontSize = size;
974            postSync();
975        }
976    }
977
978    /**
979     * @see android.webkit.WebSettings#getMinimumFontSize()
980     */
981    @Override
982    public synchronized int getMinimumFontSize() {
983        return mMinimumFontSize;
984    }
985
986    /**
987     * @see android.webkit.WebSettings#setMinimumLogicalFontSize(int)
988     */
989    @Override
990    public synchronized void setMinimumLogicalFontSize(int size) {
991        size = pin(size);
992        if (mMinimumLogicalFontSize != size) {
993            mMinimumLogicalFontSize = size;
994            postSync();
995        }
996    }
997
998    /**
999     * @see android.webkit.WebSettings#getMinimumLogicalFontSize()
1000     */
1001    @Override
1002    public synchronized int getMinimumLogicalFontSize() {
1003        return mMinimumLogicalFontSize;
1004    }
1005
1006    /**
1007     * @see android.webkit.WebSettings#setDefaultFontSize(int)
1008     */
1009    @Override
1010    public synchronized void setDefaultFontSize(int size) {
1011        size = pin(size);
1012        if (mDefaultFontSize != size) {
1013            mDefaultFontSize = size;
1014            postSync();
1015        }
1016    }
1017
1018    /**
1019     * @see android.webkit.WebSettings#getDefaultFontSize()
1020     */
1021    @Override
1022    public synchronized int getDefaultFontSize() {
1023        return mDefaultFontSize;
1024    }
1025
1026    /**
1027     * @see android.webkit.WebSettings#setDefaultFixedFontSize(int)
1028     */
1029    @Override
1030    public synchronized void setDefaultFixedFontSize(int size) {
1031        size = pin(size);
1032        if (mDefaultFixedFontSize != size) {
1033            mDefaultFixedFontSize = size;
1034            postSync();
1035        }
1036    }
1037
1038    /**
1039     * @see android.webkit.WebSettings#getDefaultFixedFontSize()
1040     */
1041    @Override
1042    public synchronized int getDefaultFixedFontSize() {
1043        return mDefaultFixedFontSize;
1044    }
1045
1046    /**
1047     * Set the number of pages cached by the WebKit for the history navigation.
1048     * @param size A non-negative integer between 0 (no cache) and 20 (max).
1049     */
1050    public synchronized void setPageCacheCapacity(int size) {
1051        if (size < 0) size = 0;
1052        if (size > 20) size = 20;
1053        if (mPageCacheCapacity != size) {
1054            mPageCacheCapacity = size;
1055            postSync();
1056        }
1057    }
1058
1059    /**
1060     * @see android.webkit.WebSettings#setLoadsImagesAutomatically(boolean)
1061     */
1062    @Override
1063    public synchronized void setLoadsImagesAutomatically(boolean flag) {
1064        if (mLoadsImagesAutomatically != flag) {
1065            mLoadsImagesAutomatically = flag;
1066            postSync();
1067        }
1068    }
1069
1070    /**
1071     * @see android.webkit.WebSettings#getLoadsImagesAutomatically()
1072     */
1073    @Override
1074    public synchronized boolean getLoadsImagesAutomatically() {
1075        return mLoadsImagesAutomatically;
1076    }
1077
1078    /**
1079     * @see android.webkit.WebSettings#setBlockNetworkImage(boolean)
1080     */
1081    @Override
1082    public synchronized void setBlockNetworkImage(boolean flag) {
1083        if (mBlockNetworkImage != flag) {
1084            mBlockNetworkImage = flag;
1085            postSync();
1086        }
1087    }
1088
1089    /**
1090     * @see android.webkit.WebSettings#getBlockNetworkImage()
1091     */
1092    @Override
1093    public synchronized boolean getBlockNetworkImage() {
1094        return mBlockNetworkImage;
1095    }
1096
1097    /**
1098     * @see android.webkit.WebSettings#setBlockNetworkLoads(boolean)
1099     */
1100    @Override
1101    public synchronized void setBlockNetworkLoads(boolean flag) {
1102        if (mBlockNetworkLoads != flag) {
1103            mBlockNetworkLoads = flag;
1104            verifyNetworkAccess();
1105            postSync();
1106        }
1107    }
1108
1109    /**
1110     * @see android.webkit.WebSettings#getBlockNetworkLoads()
1111     */
1112    @Override
1113    public synchronized boolean getBlockNetworkLoads() {
1114        return mBlockNetworkLoads;
1115    }
1116
1117
1118    private void verifyNetworkAccess() {
1119        if (!mBlockNetworkLoads) {
1120            if (mContext.checkPermission("android.permission.INTERNET",
1121                    android.os.Process.myPid(), android.os.Process.myUid()) !=
1122                        PackageManager.PERMISSION_GRANTED) {
1123                throw new SecurityException
1124                        ("Permission denied - " +
1125                                "application missing INTERNET permission");
1126            }
1127        }
1128    }
1129
1130    /**
1131     * @see android.webkit.WebSettings#setJavaScriptEnabled(boolean)
1132     */
1133    @Override
1134    public synchronized void setJavaScriptEnabled(boolean flag) {
1135        if (mJavaScriptEnabled != flag) {
1136            mJavaScriptEnabled = flag;
1137            postSync();
1138            mWebView.updateJavaScriptEnabled(flag);
1139        }
1140    }
1141
1142    /**
1143     * @see android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs
1144     */
1145    @Override
1146    public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) {
1147        if (mAllowUniversalAccessFromFileURLs != flag) {
1148            mAllowUniversalAccessFromFileURLs = flag;
1149            postSync();
1150        }
1151    }
1152
1153    /**
1154     * @see android.webkit.WebSettings#setAllowFileAccessFromFileURLs
1155     */
1156    @Override
1157    public synchronized void setAllowFileAccessFromFileURLs(boolean flag) {
1158        if (mAllowFileAccessFromFileURLs != flag) {
1159            mAllowFileAccessFromFileURLs = flag;
1160            postSync();
1161        }
1162    }
1163
1164    /**
1165     * Tell the WebView to use Skia's hardware accelerated rendering path
1166     * @param flag True if the WebView should use Skia's hw-accel path
1167     */
1168    public synchronized void setHardwareAccelSkiaEnabled(boolean flag) {
1169        if (mHardwareAccelSkia != flag) {
1170            mHardwareAccelSkia = flag;
1171            postSync();
1172        }
1173    }
1174
1175    /**
1176     * @return True if the WebView is using hardware accelerated skia
1177     */
1178    public synchronized boolean getHardwareAccelSkiaEnabled() {
1179        return mHardwareAccelSkia;
1180    }
1181
1182    /**
1183     * Tell the WebView to show the visual indicator
1184     * @param flag True if the WebView should show the visual indicator
1185     */
1186    public synchronized void setShowVisualIndicator(boolean flag) {
1187        if (mShowVisualIndicator != flag) {
1188            mShowVisualIndicator = flag;
1189            postSync();
1190        }
1191    }
1192
1193    /**
1194     * @return True if the WebView is showing the visual indicator
1195     */
1196    public synchronized boolean getShowVisualIndicator() {
1197        return mShowVisualIndicator;
1198    }
1199
1200    /**
1201     * @see android.webkit.WebSettings#setPluginsEnabled(boolean)
1202     */
1203    @Override
1204    @Deprecated
1205    public synchronized void setPluginsEnabled(boolean flag) {
1206        setPluginState(flag ? PluginState.ON : PluginState.OFF);
1207    }
1208
1209    /**
1210     * @see android.webkit.WebSettings#setPluginState(android.webkit.WebSettingsClassic.PluginState)
1211     */
1212    @Override
1213    public synchronized void setPluginState(PluginState state) {
1214        if (mPluginState != state) {
1215            mPluginState = state;
1216            postSync();
1217        }
1218    }
1219
1220    /**
1221     * @see android.webkit.WebSettings#setPluginsPath(java.lang.String)
1222     */
1223    @Override
1224    @Deprecated
1225    public synchronized void setPluginsPath(String pluginsPath) {
1226    }
1227
1228    /**
1229     * @see android.webkit.WebSettings#setDatabasePath(java.lang.String)
1230     */
1231    @Override
1232    public synchronized void setDatabasePath(String databasePath) {
1233        if (databasePath != null && !mDatabasePathHasBeenSet) {
1234            mDatabasePath = databasePath;
1235            mDatabasePathHasBeenSet = true;
1236            postSync();
1237        }
1238    }
1239
1240    /**
1241     * @see android.webkit.WebSettings#setGeolocationDatabasePath(java.lang.String)
1242     */
1243    @Override
1244    public synchronized void setGeolocationDatabasePath(String databasePath) {
1245        if (databasePath != null
1246                && !databasePath.equals(mGeolocationDatabasePath)) {
1247            mGeolocationDatabasePath = databasePath;
1248            postSync();
1249        }
1250    }
1251
1252    /**
1253     * @see android.webkit.WebSettings#setAppCacheEnabled(boolean)
1254     */
1255    @Override
1256    public synchronized void setAppCacheEnabled(boolean flag) {
1257        if (mAppCacheEnabled != flag) {
1258            mAppCacheEnabled = flag;
1259            postSync();
1260        }
1261    }
1262
1263    /**
1264     * @see android.webkit.WebSettings#setAppCachePath(java.lang.String)
1265     */
1266    @Override
1267    public synchronized void setAppCachePath(String path) {
1268        // We test for a valid path and for repeated setting on the native
1269        // side, but we can avoid syncing in some simple cases.
1270        if (mAppCachePath == null && path != null && !path.isEmpty()) {
1271            mAppCachePath = path;
1272            postSync();
1273        }
1274    }
1275
1276    /**
1277     * @see android.webkit.WebSettings#setAppCacheMaxSize(long)
1278     */
1279    @Override
1280    public synchronized void setAppCacheMaxSize(long appCacheMaxSize) {
1281        if (appCacheMaxSize != mAppCacheMaxSize) {
1282            mAppCacheMaxSize = appCacheMaxSize;
1283            postSync();
1284        }
1285    }
1286
1287    /**
1288     * @see android.webkit.WebSettings#setDatabaseEnabled(boolean)
1289     */
1290    @Override
1291    public synchronized void setDatabaseEnabled(boolean flag) {
1292       if (mDatabaseEnabled != flag) {
1293           mDatabaseEnabled = flag;
1294           postSync();
1295       }
1296    }
1297
1298    /**
1299     * @see android.webkit.WebSettings#setDomStorageEnabled(boolean)
1300     */
1301    @Override
1302    public synchronized void setDomStorageEnabled(boolean flag) {
1303       if (mDomStorageEnabled != flag) {
1304           mDomStorageEnabled = flag;
1305           postSync();
1306       }
1307    }
1308
1309    /**
1310     * @see android.webkit.WebSettings#getDomStorageEnabled()
1311     */
1312    @Override
1313    public synchronized boolean getDomStorageEnabled() {
1314       return mDomStorageEnabled;
1315    }
1316
1317    /**
1318     * @see android.webkit.WebSettings#getDatabasePath()
1319     */
1320    @Override
1321    public synchronized String getDatabasePath() {
1322        return mDatabasePath;
1323    }
1324
1325    /**
1326     * @see android.webkit.WebSettings#getDatabaseEnabled()
1327     */
1328    @Override
1329    public synchronized boolean getDatabaseEnabled() {
1330        return mDatabaseEnabled;
1331    }
1332
1333    /**
1334     * Tell the WebView to enable WebWorkers API.
1335     * @param flag True if the WebView should enable WebWorkers.
1336     * Note that this flag only affects V8. JSC does not have
1337     * an equivalent setting.
1338     */
1339    public synchronized void setWorkersEnabled(boolean flag) {
1340        if (mWorkersEnabled != flag) {
1341            mWorkersEnabled = flag;
1342            postSync();
1343        }
1344    }
1345
1346    /**
1347     * @see android.webkit.WebSettings#setGeolocationEnabled(boolean)
1348     */
1349    @Override
1350    public synchronized void setGeolocationEnabled(boolean flag) {
1351        if (mGeolocationEnabled != flag) {
1352            mGeolocationEnabled = flag;
1353            postSync();
1354        }
1355    }
1356
1357    /**
1358     * Sets whether XSS Auditor is enabled.
1359     * Only used by LayoutTestController.
1360     * @param flag Whether XSS Auditor should be enabled.
1361     */
1362    public synchronized void setXSSAuditorEnabled(boolean flag) {
1363        if (mXSSAuditorEnabled != flag) {
1364            mXSSAuditorEnabled = flag;
1365            postSync();
1366        }
1367    }
1368
1369    /**
1370     * Enables/disables HTML5 link "prefetch" parameter.
1371     */
1372    public synchronized void setLinkPrefetchEnabled(boolean flag) {
1373        if (mLinkPrefetchEnabled != flag) {
1374            mLinkPrefetchEnabled = flag;
1375            postSync();
1376        }
1377    }
1378
1379    /**
1380     * @see android.webkit.WebSettings#getJavaScriptEnabled()
1381     */
1382    @Override
1383    public synchronized boolean getJavaScriptEnabled() {
1384        return mJavaScriptEnabled;
1385    }
1386
1387    /**
1388     * @see android.webkit.WebSettings#getAllowUniversalFileAccessFromFileURLs
1389     */
1390    @Override
1391    public synchronized boolean getAllowUniversalAccessFromFileURLs() {
1392        return mAllowUniversalAccessFromFileURLs;
1393    }
1394
1395    /**
1396     * @see android.webkit.WebSettings#getAllowFileAccessFromFileURLs
1397     */
1398    @Override
1399    public synchronized boolean getAllowFileAccessFromFileURLs() {
1400        return mAllowFileAccessFromFileURLs;
1401    }
1402
1403    /**
1404     * @see android.webkit.WebSettings#getPluginsEnabled()
1405     */
1406    @Override
1407    @Deprecated
1408    public synchronized boolean getPluginsEnabled() {
1409        return mPluginState == PluginState.ON;
1410    }
1411
1412    /**
1413     * @see android.webkit.WebSettings#getPluginState()
1414     */
1415    @Override
1416    public synchronized PluginState getPluginState() {
1417        return mPluginState;
1418    }
1419
1420    /**
1421     * @see android.webkit.WebSettings#getPluginsPath()
1422     */
1423    @Override
1424    @Deprecated
1425    public synchronized String getPluginsPath() {
1426        return "";
1427    }
1428
1429    /**
1430     * @see android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically(boolean)
1431     */
1432    @Override
1433    public synchronized void setJavaScriptCanOpenWindowsAutomatically(
1434            boolean flag) {
1435        if (mJavaScriptCanOpenWindowsAutomatically != flag) {
1436            mJavaScriptCanOpenWindowsAutomatically = flag;
1437            postSync();
1438        }
1439    }
1440
1441    /**
1442     * @see android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically()
1443     */
1444    @Override
1445    public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
1446        return mJavaScriptCanOpenWindowsAutomatically;
1447    }
1448
1449    /**
1450     * @see android.webkit.WebSettings#setDefaultTextEncodingName(java.lang.String)
1451     */
1452    @Override
1453    public synchronized void setDefaultTextEncodingName(String encoding) {
1454        if (encoding != null && !encoding.equals(mDefaultTextEncoding)) {
1455            mDefaultTextEncoding = encoding;
1456            postSync();
1457        }
1458    }
1459
1460    /**
1461     * @see android.webkit.WebSettings#getDefaultTextEncodingName()
1462     */
1463    @Override
1464    public synchronized String getDefaultTextEncodingName() {
1465        return mDefaultTextEncoding;
1466    }
1467
1468    /**
1469     * @see android.webkit.WebSettings#setUserAgentString(java.lang.String)
1470     */
1471    @Override
1472    public synchronized void setUserAgentString(String ua) {
1473        if (ua == null || ua.length() == 0) {
1474            synchronized(sLockForLocaleSettings) {
1475                Locale currentLocale = Locale.getDefault();
1476                if (!sLocale.equals(currentLocale)) {
1477                    sLocale = currentLocale;
1478                    mAcceptLanguage = getCurrentAcceptLanguage();
1479                }
1480            }
1481            ua = getCurrentUserAgent();
1482            mUseDefaultUserAgent = true;
1483        } else  {
1484            mUseDefaultUserAgent = false;
1485        }
1486
1487        if (!ua.equals(mUserAgent)) {
1488            mUserAgent = ua;
1489            postSync();
1490        }
1491    }
1492
1493    /**
1494     * @see android.webkit.WebSettings#getUserAgentString()
1495     */
1496    @Override
1497    public synchronized String getUserAgentString() {
1498        if (DESKTOP_USERAGENT.equals(mUserAgent) ||
1499                IPHONE_USERAGENT.equals(mUserAgent) ||
1500                !mUseDefaultUserAgent) {
1501            return mUserAgent;
1502        }
1503
1504        boolean doPostSync = false;
1505        synchronized(sLockForLocaleSettings) {
1506            Locale currentLocale = Locale.getDefault();
1507            if (!sLocale.equals(currentLocale)) {
1508                sLocale = currentLocale;
1509                mUserAgent = getCurrentUserAgent();
1510                mAcceptLanguage = getCurrentAcceptLanguage();
1511                doPostSync = true;
1512            }
1513        }
1514        if (doPostSync) {
1515            postSync();
1516        }
1517        return mUserAgent;
1518    }
1519
1520    /* package api to grab the Accept Language string. */
1521    /*package*/ synchronized String getAcceptLanguage() {
1522        synchronized(sLockForLocaleSettings) {
1523            Locale currentLocale = Locale.getDefault();
1524            if (!sLocale.equals(currentLocale)) {
1525                sLocale = currentLocale;
1526                mAcceptLanguage = getCurrentAcceptLanguage();
1527            }
1528        }
1529        return mAcceptLanguage;
1530    }
1531
1532    /* package */ boolean isNarrowColumnLayout() {
1533        return getLayoutAlgorithm() == LayoutAlgorithm.NARROW_COLUMNS;
1534    }
1535
1536    /**
1537     * @see android.webkit.WebSettings#setNeedInitialFocus(boolean)
1538     */
1539    @Override
1540    public void setNeedInitialFocus(boolean flag) {
1541        if (mNeedInitialFocus != flag) {
1542            mNeedInitialFocus = flag;
1543        }
1544    }
1545
1546    /* Package api to get the choice whether it needs to set initial focus. */
1547    /* package */ boolean getNeedInitialFocus() {
1548        return mNeedInitialFocus;
1549    }
1550
1551    /**
1552     * @see android.webkit.WebSettings#setRenderPriority(android.webkit.WebSettingsClassic.RenderPriority)
1553     */
1554    @Override
1555    public synchronized void setRenderPriority(RenderPriority priority) {
1556        if (mRenderPriority != priority) {
1557            mRenderPriority = priority;
1558            mEventHandler.sendMessage(Message.obtain(null,
1559                    EventHandler.PRIORITY));
1560        }
1561    }
1562
1563    /**
1564     * @see android.webkit.WebSettings#setCacheMode(int)
1565     */
1566    @Override
1567    public void setCacheMode(int mode) {
1568        if (mode != mOverrideCacheMode) {
1569            mOverrideCacheMode = mode;
1570            postSync();
1571        }
1572    }
1573
1574    /**
1575     * @see android.webkit.WebSettings#getCacheMode()
1576     */
1577    @Override
1578    public int getCacheMode() {
1579        return mOverrideCacheMode;
1580    }
1581
1582    /**
1583     * If set, webkit alternately shrinks and expands images viewed outside
1584     * of an HTML page to fit the screen. This conflicts with attempts by
1585     * the UI to zoom in and out of an image, so it is set false by default.
1586     * @param shrink Set true to let webkit shrink the standalone image to fit.
1587     */
1588    public void setShrinksStandaloneImagesToFit(boolean shrink) {
1589        if (mShrinksStandaloneImagesToFit != shrink) {
1590            mShrinksStandaloneImagesToFit = shrink;
1591            postSync();
1592        }
1593     }
1594
1595    /**
1596     * Specify the maximum decoded image size. The default is
1597     * 2 megs for small memory devices and 8 megs for large memory devices.
1598     * @param size The maximum decoded size, or zero to set to the default.
1599     */
1600    public void setMaximumDecodedImageSize(long size) {
1601        if (mMaximumDecodedImageSize != size) {
1602            mMaximumDecodedImageSize = size;
1603            postSync();
1604        }
1605    }
1606
1607    /**
1608     * Returns whether to use fixed viewport.  Use fixed viewport
1609     * whenever wide viewport is on.
1610     */
1611    /* package */ boolean getUseFixedViewport() {
1612        return getUseWideViewPort();
1613    }
1614
1615    /**
1616     * Returns whether private browsing is enabled.
1617     */
1618    /* package */ boolean isPrivateBrowsingEnabled() {
1619        return mPrivateBrowsingEnabled;
1620    }
1621
1622    /**
1623     * Sets whether private browsing is enabled.
1624     * @param flag Whether private browsing should be enabled.
1625     */
1626    /* package */ synchronized void setPrivateBrowsingEnabled(boolean flag) {
1627        if (mPrivateBrowsingEnabled != flag) {
1628            mPrivateBrowsingEnabled = flag;
1629
1630            // AutoFill is dependant on private browsing being enabled so
1631            // reset it to take account of the new value of mPrivateBrowsingEnabled.
1632            setAutoFillEnabled(mAutoFillEnabled);
1633
1634            postSync();
1635        }
1636    }
1637
1638    /**
1639     * Returns whether the viewport metatag can disable zooming
1640     */
1641    public boolean forceUserScalable() {
1642        return mForceUserScalable;
1643    }
1644
1645    /**
1646     * Sets whether viewport metatag can disable zooming.
1647     * @param flag Whether or not to forceably enable user scalable.
1648     */
1649    public synchronized void setForceUserScalable(boolean flag) {
1650        mForceUserScalable = flag;
1651    }
1652
1653    synchronized void setSyntheticLinksEnabled(boolean flag) {
1654        if (mSyntheticLinksEnabled != flag) {
1655            mSyntheticLinksEnabled = flag;
1656            postSync();
1657        }
1658    }
1659
1660    public synchronized void setAutoFillEnabled(boolean enabled) {
1661        // AutoFill is always disabled in private browsing mode.
1662        boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled;
1663        if (mAutoFillEnabled != autoFillEnabled) {
1664            mAutoFillEnabled = autoFillEnabled;
1665            postSync();
1666        }
1667    }
1668
1669    public synchronized boolean getAutoFillEnabled() {
1670        return mAutoFillEnabled;
1671    }
1672
1673    public synchronized void setAutoFillProfile(AutoFillProfile profile) {
1674        if (mAutoFillProfile != profile) {
1675            mAutoFillProfile = profile;
1676            postSync();
1677        }
1678    }
1679
1680    public synchronized AutoFillProfile getAutoFillProfile() {
1681        return mAutoFillProfile;
1682    }
1683
1684    int getDoubleTapToastCount() {
1685        return mDoubleTapToastCount;
1686    }
1687
1688    void setDoubleTapToastCount(int count) {
1689        if (mDoubleTapToastCount != count) {
1690            mDoubleTapToastCount = count;
1691            // write the settings in the non-UI thread
1692            mEventHandler.sendMessage(Message.obtain(null,
1693                    EventHandler.SET_DOUBLE_TAP_TOAST_COUNT));
1694        }
1695    }
1696
1697    public void setProperty(String key, String value) {
1698        if (mWebView.nativeSetProperty(key, value)) {
1699            mWebView.invalidate();
1700        }
1701    }
1702
1703    public String getProperty(String key) {
1704        return mWebView.nativeGetProperty(key);
1705    }
1706
1707    /**
1708     * Transfer messages from the queue to the new WebCoreThread. Called from
1709     * WebCore thread.
1710     */
1711    /*package*/
1712    synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) {
1713        mBrowserFrame = frame;
1714        if (DebugFlags.WEB_SETTINGS) {
1715            junit.framework.Assert.assertTrue(frame.mNativeFrame != 0);
1716        }
1717
1718        SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE,
1719                Context.MODE_PRIVATE);
1720        if (mDoubleTapToastCount > 0) {
1721            mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT,
1722                    mDoubleTapToastCount);
1723        }
1724        nativeSync(frame.mNativeFrame);
1725        mSyncPending = false;
1726        mEventHandler.createHandler();
1727    }
1728
1729    /**
1730     * Let the Settings object know that our owner is being destroyed.
1731     */
1732    /*package*/
1733    synchronized void onDestroyed() {
1734    }
1735
1736    private int pin(int size) {
1737        // FIXME: 72 is just an arbitrary max text size value.
1738        if (size < 1) {
1739            return 1;
1740        } else if (size > 72) {
1741            return 72;
1742        }
1743        return size;
1744    }
1745
1746    /* Post a SYNC message to handle syncing the native settings. */
1747    private synchronized void postSync() {
1748        // Only post if a sync is not pending
1749        if (!mSyncPending) {
1750            mSyncPending = mEventHandler.sendMessage(
1751                    Message.obtain(null, EventHandler.SYNC));
1752        }
1753    }
1754
1755    // Synchronize the native and java settings.
1756    private native void nativeSync(int nativeFrame);
1757}
1758