• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
initialize(final Context context)132     public static void initialize(final Context context) {
133         sInstance = new BrowserSettings(context);
134     }
135 
getInstance()136     public static BrowserSettings getInstance() {
137         return sInstance;
138     }
139 
BrowserSettings(Context context)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 
setController(Controller controller)150     public void setController(Controller controller) {
151         mController = controller;
152         if (sInitialized) {
153             syncSharedSettings();
154         }
155     }
156 
startManagingSettings(WebSettings settings)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 
stopManagingSettings(WebSettings settings)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 
requireInitialization()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      */
syncSetting(WebSettingsClassic settings)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      */
syncStaticSettings(WebSettingsClassic settings)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 
syncSharedSettings()344     private void syncSharedSettings() {
345         mNeedsSharedSync = false;
346         CookieManager.getInstance().setAcceptCookie(acceptCookies());
347         if (mController != null) {
348             mController.setShouldShowErrorConsole(enableJavascriptConsole());
349         }
350     }
351 
syncManagedSettings()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
onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key)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 
getFactoryResetHomeUrl(Context context)387     public static String getFactoryResetHomeUrl(Context context) {
388         requireInitialization();
389         return sFactoryResetUrl;
390     }
391 
getLayoutAlgorithm()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 
getPageCacheCapacity()411     public int getPageCacheCapacity() {
412         requireInitialization();
413         return mPageCacheCapacity;
414     }
415 
getWebStorageSizeManager()416     public WebStorageSizeManager getWebStorageSizeManager() {
417         requireInitialization();
418         return mWebStorageSizeManager;
419     }
420 
getAppCachePath()421     private String getAppCachePath() {
422         if (mAppCachePath == null) {
423             mAppCachePath = mContext.getDir("appcache", 0).getPath();
424         }
425         return mAppCachePath;
426     }
427 
updateSearchEngine(boolean force)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 
getSearchEngine()436     public SearchEngine getSearchEngine() {
437         if (mSearchEngine == null) {
438             updateSearchEngine(false);
439         }
440         return mSearchEngine;
441     }
442 
isDebugEnabled()443     public boolean isDebugEnabled() {
444         requireInitialization();
445         return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
446     }
447 
setDebugEnabled(boolean value)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 
clearCache()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 
clearCookies()468     public void clearCookies() {
469         CookieManager.getInstance().removeAllCookie();
470     }
471 
clearHistory()472     public void clearHistory() {
473         ContentResolver resolver = mContext.getContentResolver();
474         Browser.clearHistory(resolver);
475         Browser.clearSearches(resolver);
476     }
477 
clearFormData()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 
clearPasswords()488     public void clearPasswords() {
489         WebViewDatabase db = WebViewDatabase.getInstance(mContext);
490         db.clearUsernamePassword();
491         db.clearHttpAuthUsernamePassword();
492     }
493 
clearDatabases()494     public void clearDatabases() {
495         WebStorage.getInstance().deleteAllData();
496     }
497 
clearLocationAccess()498     public void clearLocationAccess() {
499         GeolocationPermissions.getInstance().clearAll();
500     }
501 
resetDefaultPreferences()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 
getAutoFillProfile()512     public AutoFillProfile getAutoFillProfile() {
513         return mAutofillHandler.getAutoFillProfile();
514     }
515 
setAutoFillProfile(AutoFillProfile profile, Message msg)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 
toggleDebugSettings()525     public void toggleDebugSettings() {
526         setDebugEnabled(!isDebugEnabled());
527     }
528 
hasDesktopUseragent(WebView view)529     public boolean hasDesktopUseragent(WebView view) {
530         return view != null && mCustomUserAgents.get(view.getSettings()) != null;
531     }
532 
toggleDesktopUseragent(WebView view)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 
getAdjustedMinimumFontSize(int rawValue)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 
getAdjustedTextZoom(int rawValue)555     public int getAdjustedTextZoom(int rawValue) {
556         rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
557         return (int) ((rawValue + 100) * mFontSizeMult);
558     }
559 
getRawTextZoom(int percent)560     static int getRawTextZoom(int percent) {
561         return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
562     }
563 
getAdjustedDoubleTapZoom(int rawValue)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 
getRawDoubleTapZoom(int percent)569     static int getRawDoubleTapZoom(int percent) {
570         return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
571     }
572 
getPreferences()573     public SharedPreferences getPreferences() {
574         return mPrefs;
575     }
576 
577     // update connectivity-dependent options
updateConnectionType()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
getTextSize()613     private TextSize getTextSize() {
614         String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
615         return TextSize.valueOf(textSize);
616     }
617 
getMinimumFontSize()618     public int getMinimumFontSize() {
619         int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
620         return getAdjustedMinimumFontSize(minFont);
621     }
622 
forceEnableUserScalable()623     public boolean forceEnableUserScalable() {
624         return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
625     }
626 
getTextZoom()627     public int getTextZoom() {
628         requireInitialization();
629         int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
630         return getAdjustedTextZoom(textZoom);
631     }
632 
setTextZoom(int percent)633     public void setTextZoom(int percent) {
634         mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
635     }
636 
getDoubleTapZoom()637     public int getDoubleTapZoom() {
638         requireInitialization();
639         int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
640         return getAdjustedDoubleTapZoom(doubleTapZoom);
641     }
642 
setDoubleTapZoom(int percent)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 
getSearchEngineName()651     public String getSearchEngineName() {
652         return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
653     }
654 
allowAppTabs()655     public boolean allowAppTabs() {
656         return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
657     }
658 
openInBackground()659     public boolean openInBackground() {
660         return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
661     }
662 
enableJavascript()663     public boolean enableJavascript() {
664         return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
665     }
666 
667     // TODO: Cache
getPluginState()668     public PluginState getPluginState() {
669         String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
670         return PluginState.valueOf(state);
671     }
672 
673     // TODO: Cache
getDefaultZoom()674     public ZoomDensity getDefaultZoom() {
675         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
676         return ZoomDensity.valueOf(zoom);
677     }
678 
loadPageInOverviewMode()679     public boolean loadPageInOverviewMode() {
680         return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
681     }
682 
autofitPages()683     public boolean autofitPages() {
684         return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
685     }
686 
blockPopupWindows()687     public boolean blockPopupWindows() {
688         return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
689     }
690 
loadImages()691     public boolean loadImages() {
692         return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
693     }
694 
getDefaultTextEncoding()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 
getHomePage()703     public String getHomePage() {
704         return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
705     }
706 
setHomePage(String value)707     public void setHomePage(String value) {
708         mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
709     }
710 
isAutofillEnabled()711     public boolean isAutofillEnabled() {
712         return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
713     }
714 
setAutofillEnabled(boolean value)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 
isHardwareAccelerated()723     public boolean isHardwareAccelerated() {
724         if (!isDebugEnabled()) {
725             return true;
726         }
727         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
728     }
729 
isSkiaHardwareAccelerated()730     public boolean isSkiaHardwareAccelerated() {
731         if (!isDebugEnabled()) {
732             return false;
733         }
734         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
735     }
736 
getUserAgent()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 
enableVisualIndicator()748     public boolean enableVisualIndicator() {
749         if (!isDebugEnabled()) {
750             return false;
751         }
752         return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
753     }
754 
enableCpuUploadPath()755     public boolean enableCpuUploadPath() {
756         if (!isDebugEnabled()) {
757             return false;
758         }
759         return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
760     }
761 
enableJavascriptConsole()762     public boolean enableJavascriptConsole() {
763         if (!isDebugEnabled()) {
764             return false;
765         }
766         return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
767     }
768 
isSmallScreen()769     public boolean isSmallScreen() {
770         if (!isDebugEnabled()) {
771             return false;
772         }
773         return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
774     }
775 
isWideViewport()776     public boolean isWideViewport() {
777         if (!isDebugEnabled()) {
778             return true;
779         }
780         return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
781     }
782 
isNormalLayout()783     public boolean isNormalLayout() {
784         if (!isDebugEnabled()) {
785             return false;
786         }
787         return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
788     }
789 
isTracing()790     public boolean isTracing() {
791         if (!isDebugEnabled()) {
792             return false;
793         }
794         return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
795     }
796 
enableLightTouch()797     public boolean enableLightTouch() {
798         if (!isDebugEnabled()) {
799             return false;
800         }
801         return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
802     }
803 
enableNavDump()804     public boolean enableNavDump() {
805         if (!isDebugEnabled()) {
806             return false;
807         }
808         return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
809     }
810 
getJsEngineFlags()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 
useQuickControls()822     public boolean useQuickControls() {
823         return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
824     }
825 
useMostVisitedHomepage()826     public boolean useMostVisitedHomepage() {
827         return HomeProvider.MOST_VISITED.equals(getHomePage());
828     }
829 
useFullscreen()830     public boolean useFullscreen() {
831         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
832     }
833 
useInvertedRendering()834     public boolean useInvertedRendering() {
835         return mPrefs.getBoolean(PREF_INVERTED, false);
836     }
837 
getInvertedContrast()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 
showSecurityWarnings()846     public boolean showSecurityWarnings() {
847         return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
848     }
849 
acceptCookies()850     public boolean acceptCookies() {
851         return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
852     }
853 
saveFormdata()854     public boolean saveFormdata() {
855         return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
856     }
857 
enableGeolocation()858     public boolean enableGeolocation() {
859         return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
860     }
861 
rememberPasswords()862     public boolean rememberPasswords() {
863         return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
864     }
865 
866     // -----------------------------
867     // getter/setters for bandwidth_preferences.xml
868     // -----------------------------
869 
getPreloadOnWifiOnlyPreferenceString(Context context)870     public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
871         return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
872     }
873 
getPreloadAlwaysPreferenceString(Context context)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 
getDefaultPreloadSetting()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 
getPreloadEnabled()890     public String getPreloadEnabled() {
891         return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
892     }
893 
getLinkPrefetchOnWifiOnlyPreferenceString(Context context)894     public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
895         return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
896     }
897 
getLinkPrefetchAlwaysPreferenceString(Context context)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 
getDefaultLinkPrefetchSetting()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 
getLinkPrefetchEnabled()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      */
getLastRecovered()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      */
setLastRecovered(long time)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      */
wasLastRunPaused()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      */
setLastRunPaused(boolean isPaused)956     public void setLastRunPaused(boolean isPaused) {
957         mPrefs.edit()
958             .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
959             .apply();
960     }
961 }
962