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