Home | History | Annotate | Download | only in browser
      1 /*
      2  * Copyright (C) 2011 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 com.android.browser;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.ContentResolver;
     21 import android.content.Context;
     22 import android.content.SharedPreferences;
     23 import android.content.SharedPreferences.Editor;
     24 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
     25 import android.net.ConnectivityManager;
     26 import android.net.NetworkInfo;
     27 import android.os.Build;
     28 import android.os.Message;
     29 import android.preference.PreferenceManager;
     30 import android.provider.Browser;
     31 import android.provider.Settings;
     32 import android.util.DisplayMetrics;
     33 import android.webkit.CookieManager;
     34 import android.webkit.GeolocationPermissions;
     35 import android.webkit.WebIconDatabase;
     36 import android.webkit.WebSettings;
     37 import android.webkit.WebSettings.LayoutAlgorithm;
     38 import android.webkit.WebSettings.PluginState;
     39 import android.webkit.WebSettings.TextSize;
     40 import android.webkit.WebSettings.ZoomDensity;
     41 import android.webkit.WebStorage;
     42 import android.webkit.WebView;
     43 import android.webkit.WebViewDatabase;
     44 
     45 import com.android.browser.homepages.HomeProvider;
     46 import com.android.browser.provider.BrowserProvider;
     47 import com.android.browser.search.SearchEngine;
     48 import com.android.browser.search.SearchEngines;
     49 
     50 import java.lang.ref.WeakReference;
     51 import java.util.Iterator;
     52 import java.util.LinkedList;
     53 import java.util.WeakHashMap;
     54 
     55 /**
     56  * Class for managing settings
     57  */
     58 public class BrowserSettings implements OnSharedPreferenceChangeListener,
     59         PreferenceKeys {
     60 
     61     // TODO: Do something with this UserAgent stuff
     62     private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
     63         "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
     64         "Chrome/11.0.696.34 Safari/534.24";
     65 
     66     private static final String IPHONE_USERAGENT = "Mozilla/5.0 (iPhone; U; " +
     67         "CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 " +
     68         "(KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
     69 
     70     private static final String IPAD_USERAGENT = "Mozilla/5.0 (iPad; U; " +
     71         "CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 " +
     72         "(KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10";
     73 
     74     private static final String FROYO_USERAGENT = "Mozilla/5.0 (Linux; U; " +
     75         "Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 " +
     76         "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
     77 
     78     private static final String HONEYCOMB_USERAGENT = "Mozilla/5.0 (Linux; U; " +
     79         "Android 3.1; en-us; Xoom Build/HMJ25) AppleWebKit/534.13 " +
     80         "(KHTML, like Gecko) Version/4.0 Safari/534.13";
     81 
     82     private static final String USER_AGENTS[] = { null,
     83             DESKTOP_USERAGENT,
     84             IPHONE_USERAGENT,
     85             IPAD_USERAGENT,
     86             FROYO_USERAGENT,
     87             HONEYCOMB_USERAGENT,
     88     };
     89 
     90     // The minimum min font size
     91     // Aka, the lower bounds for the min font size range
     92     // which is 1:5..24
     93     private static final int MIN_FONT_SIZE_OFFSET = 5;
     94     // The initial value in the text zoom range
     95     // This is what represents 100% in the SeekBarPreference range
     96     private static final int TEXT_ZOOM_START_VAL = 10;
     97     // The size of a single step in the text zoom range, in percent
     98     private static final int TEXT_ZOOM_STEP = 5;
     99     // The initial value in the double tap zoom range
    100     // This is what represents 100% in the SeekBarPreference range
    101     private static final int DOUBLE_TAP_ZOOM_START_VAL = 5;
    102     // The size of a single step in the double tap zoom range, in percent
    103     private static final int DOUBLE_TAP_ZOOM_STEP = 5;
    104 
    105     private static BrowserSettings sInstance;
    106 
    107     private Context mContext;
    108     private SharedPreferences mPrefs;
    109     private LinkedList<WeakReference<WebSettings>> mManagedSettings;
    110     private Controller mController;
    111     private WebStorageSizeManager mWebStorageSizeManager;
    112     private WeakHashMap<WebSettings, String> mCustomUserAgents;
    113     private static boolean sInitialized = false;
    114     private boolean mNeedsSharedSync = true;
    115     private float mFontSizeMult = 1.0f;
    116 
    117     // Current state of network-dependent settings
    118     private boolean mLinkPrefetchAllowed = true;
    119 
    120     // Cached values
    121     private int mPageCacheCapacity = 1;
    122     private String mAppCachePath;
    123 
    124     // Cached settings
    125     private SearchEngine mSearchEngine;
    126 
    127     private static String sFactoryResetUrl;
    128 
    129     public static void initialize(final Context context) {
    130         sInstance = new BrowserSettings(context);
    131     }
    132 
    133     public static BrowserSettings getInstance() {
    134         return sInstance;
    135     }
    136 
    137     private BrowserSettings(Context context) {
    138         mContext = context.getApplicationContext();
    139         mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    140         mManagedSettings = new LinkedList<WeakReference<WebSettings>>();
    141         mCustomUserAgents = new WeakHashMap<WebSettings, String>();
    142         BackgroundHandler.execute(mSetup);
    143     }
    144 
    145     public void setController(Controller controller) {
    146         mController = controller;
    147         if (sInitialized) {
    148             syncSharedSettings();
    149         }
    150     }
    151 
    152     public void startManagingSettings(WebSettings settings) {
    153 
    154         if (mNeedsSharedSync) {
    155             syncSharedSettings();
    156         }
    157 
    158         synchronized (mManagedSettings) {
    159             syncStaticSettings(settings);
    160             syncSetting(settings);
    161             mManagedSettings.add(new WeakReference<WebSettings>(settings));
    162         }
    163     }
    164 
    165     public void stopManagingSettings(WebSettings settings) {
    166         Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
    167         while (iter.hasNext()) {
    168             WeakReference<WebSettings> ref = iter.next();
    169             if (ref.get() == settings) {
    170                 iter.remove();
    171                 return;
    172             }
    173         }
    174     }
    175 
    176     private Runnable mSetup = new Runnable() {
    177 
    178         @Override
    179         public void run() {
    180             DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
    181             mFontSizeMult = metrics.scaledDensity / metrics.density;
    182             // the cost of one cached page is ~3M (measured using nytimes.com). For
    183             // low end devices, we only cache one page. For high end devices, we try
    184             // to cache more pages, currently choose 5.
    185             if (ActivityManager.staticGetMemoryClass() > 16) {
    186                 mPageCacheCapacity = 5;
    187             }
    188             mWebStorageSizeManager = new WebStorageSizeManager(mContext,
    189                     new WebStorageSizeManager.StatFsDiskInfo(getAppCachePath()),
    190                     new WebStorageSizeManager.WebKitAppCacheInfo(getAppCachePath()));
    191             // Workaround b/5254577
    192             mPrefs.registerOnSharedPreferenceChangeListener(BrowserSettings.this);
    193             if (Build.VERSION.CODENAME.equals("REL")) {
    194                 // This is a release build, always startup with debug disabled
    195                 setDebugEnabled(false);
    196             }
    197             if (mPrefs.contains(PREF_TEXT_SIZE)) {
    198                 /*
    199                  * Update from TextSize enum to zoom percent
    200                  * SMALLEST is 50%
    201                  * SMALLER is 75%
    202                  * NORMAL is 100%
    203                  * LARGER is 150%
    204                  * LARGEST is 200%
    205                  */
    206                 switch (getTextSize()) {
    207                 case SMALLEST:
    208                     setTextZoom(50);
    209                     break;
    210                 case SMALLER:
    211                     setTextZoom(75);
    212                     break;
    213                 case LARGER:
    214                     setTextZoom(150);
    215                     break;
    216                 case LARGEST:
    217                     setTextZoom(200);
    218                     break;
    219                 }
    220                 mPrefs.edit().remove(PREF_TEXT_SIZE).apply();
    221             }
    222 
    223             sFactoryResetUrl = mContext.getResources().getString(R.string.homepage_base);
    224             if (sFactoryResetUrl.indexOf("{CID}") != -1) {
    225                 sFactoryResetUrl = sFactoryResetUrl.replace("{CID}",
    226                     BrowserProvider.getClientId(mContext.getContentResolver()));
    227             }
    228 
    229             synchronized (BrowserSettings.class) {
    230                 sInitialized = true;
    231                 BrowserSettings.class.notifyAll();
    232             }
    233         }
    234     };
    235 
    236     private static void requireInitialization() {
    237         synchronized (BrowserSettings.class) {
    238             while (!sInitialized) {
    239                 try {
    240                     BrowserSettings.class.wait();
    241                 } catch (InterruptedException e) {
    242                 }
    243             }
    244         }
    245     }
    246 
    247     /**
    248      * Syncs all the settings that have a Preference UI
    249      */
    250     private void syncSetting(WebSettings settings) {
    251         settings.setGeolocationEnabled(enableGeolocation());
    252         settings.setJavaScriptEnabled(enableJavascript());
    253         settings.setLightTouchEnabled(enableLightTouch());
    254         settings.setNavDump(enableNavDump());
    255         settings.setDefaultTextEncodingName(getDefaultTextEncoding());
    256         settings.setDefaultZoom(getDefaultZoom());
    257         settings.setMinimumFontSize(getMinimumFontSize());
    258         settings.setMinimumLogicalFontSize(getMinimumFontSize());
    259         settings.setPluginState(getPluginState());
    260         settings.setTextZoom(getTextZoom());
    261         settings.setLayoutAlgorithm(getLayoutAlgorithm());
    262         settings.setJavaScriptCanOpenWindowsAutomatically(!blockPopupWindows());
    263         settings.setLoadsImagesAutomatically(loadImages());
    264         settings.setLoadWithOverviewMode(loadPageInOverviewMode());
    265         settings.setSavePassword(rememberPasswords());
    266         settings.setSaveFormData(saveFormdata());
    267         settings.setUseWideViewPort(isWideViewport());
    268 
    269         String ua = mCustomUserAgents.get(settings);
    270         if (ua != null) {
    271             settings.setUserAgentString(ua);
    272         } else {
    273             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
    274         }
    275     }
    276 
    277     /**
    278      * Syncs all the settings that have no UI
    279      * These cannot change, so we only need to set them once per WebSettings
    280      */
    281     private void syncStaticSettings(WebSettings settings) {
    282         settings.setDefaultFontSize(16);
    283         settings.setDefaultFixedFontSize(13);
    284 
    285         // WebView inside Browser doesn't want initial focus to be set.
    286         settings.setNeedInitialFocus(false);
    287         // Browser supports multiple windows
    288         settings.setSupportMultipleWindows(true);
    289         // enable smooth transition for better performance during panning or
    290         // zooming
    291         settings.setEnableSmoothTransition(true);
    292         // disable content url access
    293         settings.setAllowContentAccess(false);
    294 
    295         // HTML5 API flags
    296         settings.setAppCacheEnabled(true);
    297         settings.setDatabaseEnabled(true);
    298         settings.setDomStorageEnabled(true);
    299 
    300         // HTML5 configuration parametersettings.
    301         settings.setAppCacheMaxSize(getWebStorageSizeManager().getAppCacheMaxSize());
    302         settings.setAppCachePath(getAppCachePath());
    303         settings.setDatabasePath(mContext.getDir("databases", 0).getPath());
    304         settings.setGeolocationDatabasePath(mContext.getDir("geolocation", 0).getPath());
    305         // origin policy for file access
    306         settings.setAllowUniversalAccessFromFileURLs(false);
    307         settings.setAllowFileAccessFromFileURLs(false);
    308     }
    309 
    310     private void syncSharedSettings() {
    311         mNeedsSharedSync = false;
    312         CookieManager.getInstance().setAcceptCookie(acceptCookies());
    313         if (mController != null) {
    314             for (Tab tab : mController.getTabs()) {
    315                 tab.setAcceptThirdPartyCookies(acceptCookies());
    316             }
    317             mController.setShouldShowErrorConsole(enableJavascriptConsole());
    318         }
    319     }
    320 
    321     private void syncManagedSettings() {
    322         syncSharedSettings();
    323         synchronized (mManagedSettings) {
    324             Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
    325             while (iter.hasNext()) {
    326                 WeakReference<WebSettings> ref = iter.next();
    327                 WebSettings settings = ref.get();
    328                 if (settings == null) {
    329                     iter.remove();
    330                     continue;
    331                 }
    332                 syncSetting(settings);
    333             }
    334         }
    335     }
    336 
    337     @Override
    338     public void onSharedPreferenceChanged(
    339             SharedPreferences sharedPreferences, String key) {
    340         syncManagedSettings();
    341         if (PREF_SEARCH_ENGINE.equals(key)) {
    342             updateSearchEngine(false);
    343         } else if (PREF_FULLSCREEN.equals(key)) {
    344             if (mController != null && mController.getUi() != null) {
    345                 mController.getUi().setFullscreen(useFullscreen());
    346             }
    347         } else if (PREF_ENABLE_QUICK_CONTROLS.equals(key)) {
    348             if (mController != null && mController.getUi() != null) {
    349                 mController.getUi().setUseQuickControls(sharedPreferences.getBoolean(key, false));
    350             }
    351         } else if (PREF_LINK_PREFETCH.equals(key)) {
    352             updateConnectionType();
    353         }
    354     }
    355 
    356     public static String getFactoryResetHomeUrl(Context context) {
    357         requireInitialization();
    358         return sFactoryResetUrl;
    359     }
    360 
    361     public LayoutAlgorithm getLayoutAlgorithm() {
    362         LayoutAlgorithm layoutAlgorithm = LayoutAlgorithm.NORMAL;
    363         final LayoutAlgorithm autosize = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ?
    364                 LayoutAlgorithm.TEXT_AUTOSIZING : LayoutAlgorithm.NARROW_COLUMNS;
    365 
    366         if (autofitPages()) {
    367             layoutAlgorithm = autosize;
    368         }
    369         if (isDebugEnabled()) {
    370             if (isNormalLayout()) {
    371                 layoutAlgorithm = LayoutAlgorithm.NORMAL;
    372             } else {
    373                 layoutAlgorithm = autosize;
    374             }
    375         }
    376         return layoutAlgorithm;
    377     }
    378 
    379     public int getPageCacheCapacity() {
    380         requireInitialization();
    381         return mPageCacheCapacity;
    382     }
    383 
    384     public WebStorageSizeManager getWebStorageSizeManager() {
    385         requireInitialization();
    386         return mWebStorageSizeManager;
    387     }
    388 
    389     private String getAppCachePath() {
    390         if (mAppCachePath == null) {
    391             mAppCachePath = mContext.getDir("appcache", 0).getPath();
    392         }
    393         return mAppCachePath;
    394     }
    395 
    396     private void updateSearchEngine(boolean force) {
    397         String searchEngineName = getSearchEngineName();
    398         if (force || mSearchEngine == null ||
    399                 !mSearchEngine.getName().equals(searchEngineName)) {
    400             mSearchEngine = SearchEngines.get(mContext, searchEngineName);
    401          }
    402     }
    403 
    404     public SearchEngine getSearchEngine() {
    405         if (mSearchEngine == null) {
    406             updateSearchEngine(false);
    407         }
    408         return mSearchEngine;
    409     }
    410 
    411     public boolean isDebugEnabled() {
    412         requireInitialization();
    413         return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
    414     }
    415 
    416     public void setDebugEnabled(boolean value) {
    417         Editor edit = mPrefs.edit();
    418         edit.putBoolean(PREF_DEBUG_MENU, value);
    419         if (!value) {
    420             // Reset to "safe" value
    421             edit.putBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
    422         }
    423         edit.apply();
    424     }
    425 
    426     public void clearCache() {
    427         WebIconDatabase.getInstance().removeAllIcons();
    428         if (mController != null) {
    429             WebView current = mController.getCurrentWebView();
    430             if (current != null) {
    431                 current.clearCache(true);
    432             }
    433         }
    434     }
    435 
    436     public void clearCookies() {
    437         CookieManager.getInstance().removeAllCookie();
    438     }
    439 
    440     public void clearHistory() {
    441         ContentResolver resolver = mContext.getContentResolver();
    442         Browser.clearHistory(resolver);
    443         Browser.clearSearches(resolver);
    444     }
    445 
    446     public void clearFormData() {
    447         WebViewDatabase.getInstance(mContext).clearFormData();
    448         if (mController!= null) {
    449             WebView currentTopView = mController.getCurrentTopWebView();
    450             if (currentTopView != null) {
    451                 currentTopView.clearFormData();
    452             }
    453         }
    454     }
    455 
    456     public void clearPasswords() {
    457         WebViewDatabase db = WebViewDatabase.getInstance(mContext);
    458         db.clearUsernamePassword();
    459         db.clearHttpAuthUsernamePassword();
    460     }
    461 
    462     public void clearDatabases() {
    463         WebStorage.getInstance().deleteAllData();
    464     }
    465 
    466     public void clearLocationAccess() {
    467         GeolocationPermissions.getInstance().clearAll();
    468     }
    469 
    470     public void resetDefaultPreferences() {
    471         // Preserve autologin setting
    472         long gal = mPrefs.getLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, -1);
    473         mPrefs.edit()
    474                 .clear()
    475                 .putLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, gal)
    476                 .apply();
    477         resetCachedValues();
    478         syncManagedSettings();
    479     }
    480 
    481     private void resetCachedValues() {
    482         updateSearchEngine(false);
    483     }
    484 
    485     public void toggleDebugSettings() {
    486         setDebugEnabled(!isDebugEnabled());
    487     }
    488 
    489     public boolean hasDesktopUseragent(WebView view) {
    490         return view != null && mCustomUserAgents.get(view.getSettings()) != null;
    491     }
    492 
    493     public void toggleDesktopUseragent(WebView view) {
    494         if (view == null) {
    495             return;
    496         }
    497         WebSettings settings = view.getSettings();
    498         if (mCustomUserAgents.get(settings) != null) {
    499             mCustomUserAgents.remove(settings);
    500             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
    501         } else {
    502             mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
    503             settings.setUserAgentString(DESKTOP_USERAGENT);
    504         }
    505     }
    506 
    507     public static int getAdjustedMinimumFontSize(int rawValue) {
    508         rawValue++; // Preference starts at 0, min font at 1
    509         if (rawValue > 1) {
    510             rawValue += (MIN_FONT_SIZE_OFFSET - 2);
    511         }
    512         return rawValue;
    513     }
    514 
    515     public int getAdjustedTextZoom(int rawValue) {
    516         rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
    517         return (int) ((rawValue + 100) * mFontSizeMult);
    518     }
    519 
    520     static int getRawTextZoom(int percent) {
    521         return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
    522     }
    523 
    524     public int getAdjustedDoubleTapZoom(int rawValue) {
    525         rawValue = (rawValue - DOUBLE_TAP_ZOOM_START_VAL) * DOUBLE_TAP_ZOOM_STEP;
    526         return (int) ((rawValue + 100) * mFontSizeMult);
    527     }
    528 
    529     static int getRawDoubleTapZoom(int percent) {
    530         return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
    531     }
    532 
    533     public SharedPreferences getPreferences() {
    534         return mPrefs;
    535     }
    536 
    537     // update connectivity-dependent options
    538     public void updateConnectionType() {
    539         ConnectivityManager cm = (ConnectivityManager)
    540             mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    541         String linkPrefetchPreference = getLinkPrefetchEnabled();
    542         boolean linkPrefetchAllowed = linkPrefetchPreference.
    543             equals(getLinkPrefetchAlwaysPreferenceString(mContext));
    544         NetworkInfo ni = cm.getActiveNetworkInfo();
    545         if (ni != null) {
    546             switch (ni.getType()) {
    547                 case ConnectivityManager.TYPE_WIFI:
    548                 case ConnectivityManager.TYPE_ETHERNET:
    549                 case ConnectivityManager.TYPE_BLUETOOTH:
    550                     linkPrefetchAllowed |= linkPrefetchPreference.
    551                         equals(getLinkPrefetchOnWifiOnlyPreferenceString(mContext));
    552                     break;
    553                 case ConnectivityManager.TYPE_MOBILE:
    554                 case ConnectivityManager.TYPE_MOBILE_DUN:
    555                 case ConnectivityManager.TYPE_MOBILE_MMS:
    556                 case ConnectivityManager.TYPE_MOBILE_SUPL:
    557                 case ConnectivityManager.TYPE_WIMAX:
    558                 default:
    559                     break;
    560             }
    561         }
    562         if (mLinkPrefetchAllowed != linkPrefetchAllowed) {
    563             mLinkPrefetchAllowed = linkPrefetchAllowed;
    564             syncManagedSettings();
    565         }
    566     }
    567 
    568     // -----------------------------
    569     // getter/setters for accessibility_preferences.xml
    570     // -----------------------------
    571 
    572     @Deprecated
    573     private TextSize getTextSize() {
    574         String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
    575         return TextSize.valueOf(textSize);
    576     }
    577 
    578     public int getMinimumFontSize() {
    579         int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
    580         return getAdjustedMinimumFontSize(minFont);
    581     }
    582 
    583     public boolean forceEnableUserScalable() {
    584         return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
    585     }
    586 
    587     public int getTextZoom() {
    588         requireInitialization();
    589         int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
    590         return getAdjustedTextZoom(textZoom);
    591     }
    592 
    593     public void setTextZoom(int percent) {
    594         mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
    595     }
    596 
    597     public int getDoubleTapZoom() {
    598         requireInitialization();
    599         int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
    600         return getAdjustedDoubleTapZoom(doubleTapZoom);
    601     }
    602 
    603     public void setDoubleTapZoom(int percent) {
    604         mPrefs.edit().putInt(PREF_DOUBLE_TAP_ZOOM, getRawDoubleTapZoom(percent)).apply();
    605     }
    606 
    607     // -----------------------------
    608     // getter/setters for advanced_preferences.xml
    609     // -----------------------------
    610 
    611     public String getSearchEngineName() {
    612         return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
    613     }
    614 
    615     public boolean allowAppTabs() {
    616         return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
    617     }
    618 
    619     public boolean openInBackground() {
    620         return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
    621     }
    622 
    623     public boolean enableJavascript() {
    624         return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
    625     }
    626 
    627     // TODO: Cache
    628     public PluginState getPluginState() {
    629         String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
    630         return PluginState.valueOf(state);
    631     }
    632 
    633     // TODO: Cache
    634     public ZoomDensity getDefaultZoom() {
    635         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
    636         return ZoomDensity.valueOf(zoom);
    637     }
    638 
    639     public boolean loadPageInOverviewMode() {
    640         return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
    641     }
    642 
    643     public boolean autofitPages() {
    644         return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
    645     }
    646 
    647     public boolean blockPopupWindows() {
    648         return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
    649     }
    650 
    651     public boolean loadImages() {
    652         return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
    653     }
    654 
    655     public String getDefaultTextEncoding() {
    656         return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
    657     }
    658 
    659     // -----------------------------
    660     // getter/setters for general_preferences.xml
    661     // -----------------------------
    662 
    663     public String getHomePage() {
    664         return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
    665     }
    666 
    667     public void setHomePage(String value) {
    668         mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
    669     }
    670 
    671     public boolean isAutofillEnabled() {
    672         return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
    673     }
    674 
    675     public void setAutofillEnabled(boolean value) {
    676         mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
    677     }
    678 
    679     // -----------------------------
    680     // getter/setters for debug_preferences.xml
    681     // -----------------------------
    682 
    683     public boolean isHardwareAccelerated() {
    684         if (!isDebugEnabled()) {
    685             return true;
    686         }
    687         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
    688     }
    689 
    690     public boolean isSkiaHardwareAccelerated() {
    691         if (!isDebugEnabled()) {
    692             return false;
    693         }
    694         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
    695     }
    696 
    697     public int getUserAgent() {
    698         if (!isDebugEnabled()) {
    699             return 0;
    700         }
    701         return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
    702     }
    703 
    704     // -----------------------------
    705     // getter/setters for hidden_debug_preferences.xml
    706     // -----------------------------
    707 
    708     public boolean enableVisualIndicator() {
    709         if (!isDebugEnabled()) {
    710             return false;
    711         }
    712         return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
    713     }
    714 
    715     public boolean enableCpuUploadPath() {
    716         if (!isDebugEnabled()) {
    717             return false;
    718         }
    719         return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
    720     }
    721 
    722     public boolean enableJavascriptConsole() {
    723         if (!isDebugEnabled()) {
    724             return false;
    725         }
    726         return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
    727     }
    728 
    729     public boolean isWideViewport() {
    730         if (!isDebugEnabled()) {
    731             return true;
    732         }
    733         return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
    734     }
    735 
    736     public boolean isNormalLayout() {
    737         if (!isDebugEnabled()) {
    738             return false;
    739         }
    740         return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
    741     }
    742 
    743     public boolean isTracing() {
    744         if (!isDebugEnabled()) {
    745             return false;
    746         }
    747         return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
    748     }
    749 
    750     public boolean enableLightTouch() {
    751         if (!isDebugEnabled()) {
    752             return false;
    753         }
    754         return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
    755     }
    756 
    757     public boolean enableNavDump() {
    758         if (!isDebugEnabled()) {
    759             return false;
    760         }
    761         return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
    762     }
    763 
    764     public String getJsEngineFlags() {
    765         if (!isDebugEnabled()) {
    766             return "";
    767         }
    768         return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
    769     }
    770 
    771     // -----------------------------
    772     // getter/setters for lab_preferences.xml
    773     // -----------------------------
    774 
    775     public boolean useQuickControls() {
    776         return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
    777     }
    778 
    779     public boolean useMostVisitedHomepage() {
    780         return HomeProvider.MOST_VISITED.equals(getHomePage());
    781     }
    782 
    783     public boolean useFullscreen() {
    784         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
    785     }
    786 
    787     public boolean useInvertedRendering() {
    788         return mPrefs.getBoolean(PREF_INVERTED, false);
    789     }
    790 
    791     public float getInvertedContrast() {
    792         return 1 + (mPrefs.getInt(PREF_INVERTED_CONTRAST, 0) / 10f);
    793     }
    794 
    795     // -----------------------------
    796     // getter/setters for privacy_security_preferences.xml
    797     // -----------------------------
    798 
    799     public boolean showSecurityWarnings() {
    800         return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
    801     }
    802 
    803     public boolean acceptCookies() {
    804         return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
    805     }
    806 
    807     public boolean saveFormdata() {
    808         return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
    809     }
    810 
    811     public boolean enableGeolocation() {
    812         return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
    813     }
    814 
    815     public boolean rememberPasswords() {
    816         return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
    817     }
    818 
    819     // -----------------------------
    820     // getter/setters for bandwidth_preferences.xml
    821     // -----------------------------
    822 
    823     public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
    824         return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
    825     }
    826 
    827     public static String getPreloadAlwaysPreferenceString(Context context) {
    828         return context.getResources().getString(R.string.pref_data_preload_value_always);
    829     }
    830 
    831     private static final String DEAULT_PRELOAD_SECURE_SETTING_KEY =
    832             "browser_default_preload_setting";
    833 
    834     public String getDefaultPreloadSetting() {
    835         String preload = Settings.Secure.getString(mContext.getContentResolver(),
    836                 DEAULT_PRELOAD_SECURE_SETTING_KEY);
    837         if (preload == null) {
    838             preload = mContext.getResources().getString(R.string.pref_data_preload_default_value);
    839         }
    840         return preload;
    841     }
    842 
    843     public String getPreloadEnabled() {
    844         return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
    845     }
    846 
    847     public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
    848         return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
    849     }
    850 
    851     public static String getLinkPrefetchAlwaysPreferenceString(Context context) {
    852         return context.getResources().getString(R.string.pref_link_prefetch_value_always);
    853     }
    854 
    855     private static final String DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY =
    856             "browser_default_link_prefetch_setting";
    857 
    858     public String getDefaultLinkPrefetchSetting() {
    859         String preload = Settings.Secure.getString(mContext.getContentResolver(),
    860             DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY);
    861         if (preload == null) {
    862             preload = mContext.getResources().getString(R.string.pref_link_prefetch_default_value);
    863         }
    864         return preload;
    865     }
    866 
    867     public String getLinkPrefetchEnabled() {
    868         return mPrefs.getString(PREF_LINK_PREFETCH, getDefaultLinkPrefetchSetting());
    869     }
    870 
    871     // -----------------------------
    872     // getter/setters for browser recovery
    873     // -----------------------------
    874     /**
    875      * The last time browser was started.
    876      * @return The last browser start time as System.currentTimeMillis. This
    877      * can be 0 if this is the first time or the last tab was closed.
    878      */
    879     public long getLastRecovered() {
    880         return mPrefs.getLong(KEY_LAST_RECOVERED, 0);
    881     }
    882 
    883     /**
    884      * Sets the last browser start time.
    885      * @param time The last time as System.currentTimeMillis that the browser
    886      * was started. This should be set to 0 if the last tab is closed.
    887      */
    888     public void setLastRecovered(long time) {
    889         mPrefs.edit()
    890             .putLong(KEY_LAST_RECOVERED, time)
    891             .apply();
    892     }
    893 
    894     /**
    895      * Used to determine whether or not the previous browser run crashed. Once
    896      * the previous state has been determined, the value will be set to false
    897      * until a pause is received.
    898      * @return true if the last browser run was paused or false if it crashed.
    899      */
    900     public boolean wasLastRunPaused() {
    901         return mPrefs.getBoolean(KEY_LAST_RUN_PAUSED, false);
    902     }
    903 
    904     /**
    905      * Sets whether or not the last run was a pause or crash.
    906      * @param isPaused Set to true When a pause is received or false after
    907      * resuming.
    908      */
    909     public void setLastRunPaused(boolean isPaused) {
    910         mPrefs.edit()
    911             .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
    912             .apply();
    913     }
    914 }
    915