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