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