• 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 != 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 
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         resetCachedValues();
510         syncManagedSettings();
511     }
512 
resetCachedValues()513     private void resetCachedValues() {
514         updateSearchEngine(false);
515     }
516 
getAutoFillProfile()517     public AutoFillProfile getAutoFillProfile() {
518         return mAutofillHandler.getAutoFillProfile();
519     }
520 
setAutoFillProfile(AutoFillProfile profile, Message msg)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 
toggleDebugSettings()530     public void toggleDebugSettings() {
531         setDebugEnabled(!isDebugEnabled());
532     }
533 
hasDesktopUseragent(WebView view)534     public boolean hasDesktopUseragent(WebView view) {
535         return view != null && mCustomUserAgents.get(view.getSettings()) != null;
536     }
537 
toggleDesktopUseragent(WebView view)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 
getAdjustedMinimumFontSize(int rawValue)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 
getAdjustedTextZoom(int rawValue)560     public int getAdjustedTextZoom(int rawValue) {
561         rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
562         return (int) ((rawValue + 100) * mFontSizeMult);
563     }
564 
getRawTextZoom(int percent)565     static int getRawTextZoom(int percent) {
566         return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
567     }
568 
getAdjustedDoubleTapZoom(int rawValue)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 
getRawDoubleTapZoom(int percent)574     static int getRawDoubleTapZoom(int percent) {
575         return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
576     }
577 
getPreferences()578     public SharedPreferences getPreferences() {
579         return mPrefs;
580     }
581 
582     // update connectivity-dependent options
updateConnectionType()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
getTextSize()618     private TextSize getTextSize() {
619         String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
620         return TextSize.valueOf(textSize);
621     }
622 
getMinimumFontSize()623     public int getMinimumFontSize() {
624         int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
625         return getAdjustedMinimumFontSize(minFont);
626     }
627 
forceEnableUserScalable()628     public boolean forceEnableUserScalable() {
629         return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
630     }
631 
getTextZoom()632     public int getTextZoom() {
633         requireInitialization();
634         int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
635         return getAdjustedTextZoom(textZoom);
636     }
637 
setTextZoom(int percent)638     public void setTextZoom(int percent) {
639         mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
640     }
641 
getDoubleTapZoom()642     public int getDoubleTapZoom() {
643         requireInitialization();
644         int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
645         return getAdjustedDoubleTapZoom(doubleTapZoom);
646     }
647 
setDoubleTapZoom(int percent)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 
getSearchEngineName()656     public String getSearchEngineName() {
657         return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
658     }
659 
allowAppTabs()660     public boolean allowAppTabs() {
661         return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
662     }
663 
openInBackground()664     public boolean openInBackground() {
665         return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
666     }
667 
enableJavascript()668     public boolean enableJavascript() {
669         return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
670     }
671 
672     // TODO: Cache
getPluginState()673     public PluginState getPluginState() {
674         String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
675         return PluginState.valueOf(state);
676     }
677 
678     // TODO: Cache
getDefaultZoom()679     public ZoomDensity getDefaultZoom() {
680         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
681         return ZoomDensity.valueOf(zoom);
682     }
683 
loadPageInOverviewMode()684     public boolean loadPageInOverviewMode() {
685         return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
686     }
687 
autofitPages()688     public boolean autofitPages() {
689         return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
690     }
691 
blockPopupWindows()692     public boolean blockPopupWindows() {
693         return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
694     }
695 
loadImages()696     public boolean loadImages() {
697         return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
698     }
699 
getDefaultTextEncoding()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 
getHomePage()708     public String getHomePage() {
709         return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
710     }
711 
setHomePage(String value)712     public void setHomePage(String value) {
713         mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
714     }
715 
isAutofillEnabled()716     public boolean isAutofillEnabled() {
717         return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
718     }
719 
setAutofillEnabled(boolean value)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 
isHardwareAccelerated()728     public boolean isHardwareAccelerated() {
729         if (!isDebugEnabled()) {
730             return true;
731         }
732         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
733     }
734 
isSkiaHardwareAccelerated()735     public boolean isSkiaHardwareAccelerated() {
736         if (!isDebugEnabled()) {
737             return false;
738         }
739         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
740     }
741 
getUserAgent()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 
enableVisualIndicator()753     public boolean enableVisualIndicator() {
754         if (!isDebugEnabled()) {
755             return false;
756         }
757         return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
758     }
759 
enableCpuUploadPath()760     public boolean enableCpuUploadPath() {
761         if (!isDebugEnabled()) {
762             return false;
763         }
764         return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
765     }
766 
enableJavascriptConsole()767     public boolean enableJavascriptConsole() {
768         if (!isDebugEnabled()) {
769             return false;
770         }
771         return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
772     }
773 
isSmallScreen()774     public boolean isSmallScreen() {
775         if (!isDebugEnabled()) {
776             return false;
777         }
778         return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
779     }
780 
isWideViewport()781     public boolean isWideViewport() {
782         if (!isDebugEnabled()) {
783             return true;
784         }
785         return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
786     }
787 
isNormalLayout()788     public boolean isNormalLayout() {
789         if (!isDebugEnabled()) {
790             return false;
791         }
792         return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
793     }
794 
isTracing()795     public boolean isTracing() {
796         if (!isDebugEnabled()) {
797             return false;
798         }
799         return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
800     }
801 
enableLightTouch()802     public boolean enableLightTouch() {
803         if (!isDebugEnabled()) {
804             return false;
805         }
806         return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
807     }
808 
enableNavDump()809     public boolean enableNavDump() {
810         if (!isDebugEnabled()) {
811             return false;
812         }
813         return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
814     }
815 
getJsEngineFlags()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 
useQuickControls()827     public boolean useQuickControls() {
828         return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
829     }
830 
useMostVisitedHomepage()831     public boolean useMostVisitedHomepage() {
832         return HomeProvider.MOST_VISITED.equals(getHomePage());
833     }
834 
useFullscreen()835     public boolean useFullscreen() {
836         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
837     }
838 
useInvertedRendering()839     public boolean useInvertedRendering() {
840         return mPrefs.getBoolean(PREF_INVERTED, false);
841     }
842 
getInvertedContrast()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 
showSecurityWarnings()851     public boolean showSecurityWarnings() {
852         return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
853     }
854 
acceptCookies()855     public boolean acceptCookies() {
856         return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
857     }
858 
saveFormdata()859     public boolean saveFormdata() {
860         return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
861     }
862 
enableGeolocation()863     public boolean enableGeolocation() {
864         return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
865     }
866 
rememberPasswords()867     public boolean rememberPasswords() {
868         return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
869     }
870 
871     // -----------------------------
872     // getter/setters for bandwidth_preferences.xml
873     // -----------------------------
874 
getPreloadOnWifiOnlyPreferenceString(Context context)875     public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
876         return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
877     }
878 
getPreloadAlwaysPreferenceString(Context context)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 
getDefaultPreloadSetting()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 
getPreloadEnabled()895     public String getPreloadEnabled() {
896         return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
897     }
898 
getLinkPrefetchOnWifiOnlyPreferenceString(Context context)899     public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
900         return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
901     }
902 
getLinkPrefetchAlwaysPreferenceString(Context context)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 
getDefaultLinkPrefetchSetting()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 
getLinkPrefetchEnabled()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      */
getLastRecovered()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      */
setLastRecovered(long time)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      */
wasLastRunPaused()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      */
setLastRunPaused(boolean isPaused)961     public void setLastRunPaused(boolean isPaused) {
962         mPrefs.edit()
963             .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
964             .apply();
965     }
966 }
967