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