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