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