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