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 != null && mController.getUi() != null) {
    376                 mController.getUi().setFullscreen(useFullscreen());
    377             }
    378         } else if (PREF_ENABLE_QUICK_CONTROLS.equals(key)) {
    379             if (mController != null && 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         resetCachedValues();
    510         syncManagedSettings();
    511     }
    512 
    513     private void resetCachedValues() {
    514         updateSearchEngine(false);
    515     }
    516 
    517     public AutoFillProfile getAutoFillProfile() {
    518         return mAutofillHandler.getAutoFillProfile();
    519     }
    520 
    521     public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
    522         mAutofillHandler.setAutoFillProfile(profile, msg);
    523         // Auto-fill will reuse the same profile ID when making edits to the profile,
    524         // so we need to force a settings sync (otherwise the SharedPreferences
    525         // manager will optimise out the call to onSharedPreferenceChanged(), as
    526         // it thinks nothing has changed).
    527         syncManagedSettings();
    528     }
    529 
    530     public void toggleDebugSettings() {
    531         setDebugEnabled(!isDebugEnabled());
    532     }
    533 
    534     public boolean hasDesktopUseragent(WebView view) {
    535         return view != null && mCustomUserAgents.get(view.getSettings()) != null;
    536     }
    537 
    538     public void toggleDesktopUseragent(WebView view) {
    539         if (view == null) {
    540             return;
    541         }
    542         WebSettings settings = view.getSettings();
    543         if (mCustomUserAgents.get(settings) != null) {
    544             mCustomUserAgents.remove(settings);
    545             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
    546         } else {
    547             mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
    548             settings.setUserAgentString(DESKTOP_USERAGENT);
    549         }
    550     }
    551 
    552     public static int getAdjustedMinimumFontSize(int rawValue) {
    553         rawValue++; // Preference starts at 0, min font at 1
    554         if (rawValue > 1) {
    555             rawValue += (MIN_FONT_SIZE_OFFSET - 2);
    556         }
    557         return rawValue;
    558     }
    559 
    560     public int getAdjustedTextZoom(int rawValue) {
    561         rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
    562         return (int) ((rawValue + 100) * mFontSizeMult);
    563     }
    564 
    565     static int getRawTextZoom(int percent) {
    566         return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
    567     }
    568 
    569     public int getAdjustedDoubleTapZoom(int rawValue) {
    570         rawValue = (rawValue - DOUBLE_TAP_ZOOM_START_VAL) * DOUBLE_TAP_ZOOM_STEP;
    571         return (int) ((rawValue + 100) * mFontSizeMult);
    572     }
    573 
    574     static int getRawDoubleTapZoom(int percent) {
    575         return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
    576     }
    577 
    578     public SharedPreferences getPreferences() {
    579         return mPrefs;
    580     }
    581 
    582     // update connectivity-dependent options
    583     public void updateConnectionType() {
    584         ConnectivityManager cm = (ConnectivityManager)
    585             mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    586         String linkPrefetchPreference = getLinkPrefetchEnabled();
    587         boolean linkPrefetchAllowed = linkPrefetchPreference.
    588             equals(getLinkPrefetchAlwaysPreferenceString(mContext));
    589         NetworkInfo ni = cm.getActiveNetworkInfo();
    590         if (ni != null) {
    591             switch (ni.getType()) {
    592                 case ConnectivityManager.TYPE_WIFI:
    593                 case ConnectivityManager.TYPE_ETHERNET:
    594                 case ConnectivityManager.TYPE_BLUETOOTH:
    595                     linkPrefetchAllowed |= linkPrefetchPreference.
    596                         equals(getLinkPrefetchOnWifiOnlyPreferenceString(mContext));
    597                     break;
    598                 case ConnectivityManager.TYPE_MOBILE:
    599                 case ConnectivityManager.TYPE_MOBILE_DUN:
    600                 case ConnectivityManager.TYPE_MOBILE_MMS:
    601                 case ConnectivityManager.TYPE_MOBILE_SUPL:
    602                 case ConnectivityManager.TYPE_WIMAX:
    603                 default:
    604                     break;
    605             }
    606         }
    607         if (mLinkPrefetchAllowed != linkPrefetchAllowed) {
    608             mLinkPrefetchAllowed = linkPrefetchAllowed;
    609             syncManagedSettings();
    610         }
    611     }
    612 
    613     // -----------------------------
    614     // getter/setters for accessibility_preferences.xml
    615     // -----------------------------
    616 
    617     @Deprecated
    618     private TextSize getTextSize() {
    619         String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
    620         return TextSize.valueOf(textSize);
    621     }
    622 
    623     public int getMinimumFontSize() {
    624         int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
    625         return getAdjustedMinimumFontSize(minFont);
    626     }
    627 
    628     public boolean forceEnableUserScalable() {
    629         return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
    630     }
    631 
    632     public int getTextZoom() {
    633         requireInitialization();
    634         int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
    635         return getAdjustedTextZoom(textZoom);
    636     }
    637 
    638     public void setTextZoom(int percent) {
    639         mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
    640     }
    641 
    642     public int getDoubleTapZoom() {
    643         requireInitialization();
    644         int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
    645         return getAdjustedDoubleTapZoom(doubleTapZoom);
    646     }
    647 
    648     public void setDoubleTapZoom(int percent) {
    649         mPrefs.edit().putInt(PREF_DOUBLE_TAP_ZOOM, getRawDoubleTapZoom(percent)).apply();
    650     }
    651 
    652     // -----------------------------
    653     // getter/setters for advanced_preferences.xml
    654     // -----------------------------
    655 
    656     public String getSearchEngineName() {
    657         return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
    658     }
    659 
    660     public boolean allowAppTabs() {
    661         return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
    662     }
    663 
    664     public boolean openInBackground() {
    665         return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
    666     }
    667 
    668     public boolean enableJavascript() {
    669         return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
    670     }
    671 
    672     // TODO: Cache
    673     public PluginState getPluginState() {
    674         String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
    675         return PluginState.valueOf(state);
    676     }
    677 
    678     // TODO: Cache
    679     public ZoomDensity getDefaultZoom() {
    680         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
    681         return ZoomDensity.valueOf(zoom);
    682     }
    683 
    684     public boolean loadPageInOverviewMode() {
    685         return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
    686     }
    687 
    688     public boolean autofitPages() {
    689         return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
    690     }
    691 
    692     public boolean blockPopupWindows() {
    693         return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
    694     }
    695 
    696     public boolean loadImages() {
    697         return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
    698     }
    699 
    700     public String getDefaultTextEncoding() {
    701         return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
    702     }
    703 
    704     // -----------------------------
    705     // getter/setters for general_preferences.xml
    706     // -----------------------------
    707 
    708     public String getHomePage() {
    709         return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
    710     }
    711 
    712     public void setHomePage(String value) {
    713         mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
    714     }
    715 
    716     public boolean isAutofillEnabled() {
    717         return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
    718     }
    719 
    720     public void setAutofillEnabled(boolean value) {
    721         mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
    722     }
    723 
    724     // -----------------------------
    725     // getter/setters for debug_preferences.xml
    726     // -----------------------------
    727 
    728     public boolean isHardwareAccelerated() {
    729         if (!isDebugEnabled()) {
    730             return true;
    731         }
    732         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
    733     }
    734 
    735     public boolean isSkiaHardwareAccelerated() {
    736         if (!isDebugEnabled()) {
    737             return false;
    738         }
    739         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
    740     }
    741 
    742     public int getUserAgent() {
    743         if (!isDebugEnabled()) {
    744             return 0;
    745         }
    746         return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
    747     }
    748 
    749     // -----------------------------
    750     // getter/setters for hidden_debug_preferences.xml
    751     // -----------------------------
    752 
    753     public boolean enableVisualIndicator() {
    754         if (!isDebugEnabled()) {
    755             return false;
    756         }
    757         return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
    758     }
    759 
    760     public boolean enableCpuUploadPath() {
    761         if (!isDebugEnabled()) {
    762             return false;
    763         }
    764         return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
    765     }
    766 
    767     public boolean enableJavascriptConsole() {
    768         if (!isDebugEnabled()) {
    769             return false;
    770         }
    771         return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
    772     }
    773 
    774     public boolean isSmallScreen() {
    775         if (!isDebugEnabled()) {
    776             return false;
    777         }
    778         return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
    779     }
    780 
    781     public boolean isWideViewport() {
    782         if (!isDebugEnabled()) {
    783             return true;
    784         }
    785         return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
    786     }
    787 
    788     public boolean isNormalLayout() {
    789         if (!isDebugEnabled()) {
    790             return false;
    791         }
    792         return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
    793     }
    794 
    795     public boolean isTracing() {
    796         if (!isDebugEnabled()) {
    797             return false;
    798         }
    799         return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
    800     }
    801 
    802     public boolean enableLightTouch() {
    803         if (!isDebugEnabled()) {
    804             return false;
    805         }
    806         return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
    807     }
    808 
    809     public boolean enableNavDump() {
    810         if (!isDebugEnabled()) {
    811             return false;
    812         }
    813         return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
    814     }
    815 
    816     public String getJsEngineFlags() {
    817         if (!isDebugEnabled()) {
    818             return "";
    819         }
    820         return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
    821     }
    822 
    823     // -----------------------------
    824     // getter/setters for lab_preferences.xml
    825     // -----------------------------
    826 
    827     public boolean useQuickControls() {
    828         return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
    829     }
    830 
    831     public boolean useMostVisitedHomepage() {
    832         return HomeProvider.MOST_VISITED.equals(getHomePage());
    833     }
    834 
    835     public boolean useFullscreen() {
    836         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
    837     }
    838 
    839     public boolean useInvertedRendering() {
    840         return mPrefs.getBoolean(PREF_INVERTED, false);
    841     }
    842 
    843     public float getInvertedContrast() {
    844         return 1 + (mPrefs.getInt(PREF_INVERTED_CONTRAST, 0) / 10f);
    845     }
    846 
    847     // -----------------------------
    848     // getter/setters for privacy_security_preferences.xml
    849     // -----------------------------
    850 
    851     public boolean showSecurityWarnings() {
    852         return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
    853     }
    854 
    855     public boolean acceptCookies() {
    856         return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
    857     }
    858 
    859     public boolean saveFormdata() {
    860         return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
    861     }
    862 
    863     public boolean enableGeolocation() {
    864         return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
    865     }
    866 
    867     public boolean rememberPasswords() {
    868         return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
    869     }
    870 
    871     // -----------------------------
    872     // getter/setters for bandwidth_preferences.xml
    873     // -----------------------------
    874 
    875     public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
    876         return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
    877     }
    878 
    879     public static String getPreloadAlwaysPreferenceString(Context context) {
    880         return context.getResources().getString(R.string.pref_data_preload_value_always);
    881     }
    882 
    883     private static final String DEAULT_PRELOAD_SECURE_SETTING_KEY =
    884             "browser_default_preload_setting";
    885 
    886     public String getDefaultPreloadSetting() {
    887         String preload = Settings.Secure.getString(mContext.getContentResolver(),
    888                 DEAULT_PRELOAD_SECURE_SETTING_KEY);
    889         if (preload == null) {
    890             preload = mContext.getResources().getString(R.string.pref_data_preload_default_value);
    891         }
    892         return preload;
    893     }
    894 
    895     public String getPreloadEnabled() {
    896         return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
    897     }
    898 
    899     public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
    900         return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
    901     }
    902 
    903     public static String getLinkPrefetchAlwaysPreferenceString(Context context) {
    904         return context.getResources().getString(R.string.pref_link_prefetch_value_always);
    905     }
    906 
    907     private static final String DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY =
    908             "browser_default_link_prefetch_setting";
    909 
    910     public String getDefaultLinkPrefetchSetting() {
    911         String preload = Settings.Secure.getString(mContext.getContentResolver(),
    912             DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY);
    913         if (preload == null) {
    914             preload = mContext.getResources().getString(R.string.pref_link_prefetch_default_value);
    915         }
    916         return preload;
    917     }
    918 
    919     public String getLinkPrefetchEnabled() {
    920         return mPrefs.getString(PREF_LINK_PREFETCH, getDefaultLinkPrefetchSetting());
    921     }
    922 
    923     // -----------------------------
    924     // getter/setters for browser recovery
    925     // -----------------------------
    926     /**
    927      * The last time browser was started.
    928      * @return The last browser start time as System.currentTimeMillis. This
    929      * can be 0 if this is the first time or the last tab was closed.
    930      */
    931     public long getLastRecovered() {
    932         return mPrefs.getLong(KEY_LAST_RECOVERED, 0);
    933     }
    934 
    935     /**
    936      * Sets the last browser start time.
    937      * @param time The last time as System.currentTimeMillis that the browser
    938      * was started. This should be set to 0 if the last tab is closed.
    939      */
    940     public void setLastRecovered(long time) {
    941         mPrefs.edit()
    942             .putLong(KEY_LAST_RECOVERED, time)
    943             .apply();
    944     }
    945 
    946     /**
    947      * Used to determine whether or not the previous browser run crashed. Once
    948      * the previous state has been determined, the value will be set to false
    949      * until a pause is received.
    950      * @return true if the last browser run was paused or false if it crashed.
    951      */
    952     public boolean wasLastRunPaused() {
    953         return mPrefs.getBoolean(KEY_LAST_RUN_PAUSED, false);
    954     }
    955 
    956     /**
    957      * Sets whether or not the last run was a pause or crash.
    958      * @param isPaused Set to true When a pause is received or false after
    959      * resuming.
    960      */
    961     public void setLastRunPaused(boolean isPaused) {
    962         mPrefs.edit()
    963             .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
    964             .apply();
    965     }
    966 }
    967