• 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 
159         if (mNeedsSharedSync) {
160             syncSharedSettings();
161         }
162 
163         synchronized (mManagedSettings) {
164             syncStaticSettings(settings);
165             syncSetting(settings);
166             mManagedSettings.add(new WeakReference<WebSettings>(settings));
167         }
168     }
169 
stopManagingSettings(WebSettings settings)170     public void stopManagingSettings(WebSettings settings) {
171         Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
172         while (iter.hasNext()) {
173             WeakReference<WebSettings> ref = iter.next();
174             if (ref.get() == settings) {
175                 iter.remove();
176                 return;
177             }
178         }
179     }
180 
181     private Runnable mSetup = new Runnable() {
182 
183         @Override
184         public void run() {
185             DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
186             mFontSizeMult = metrics.scaledDensity / metrics.density;
187             // the cost of one cached page is ~3M (measured using nytimes.com). For
188             // low end devices, we only cache one page. For high end devices, we try
189             // to cache more pages, currently choose 5.
190             if (ActivityManager.staticGetMemoryClass() > 16) {
191                 mPageCacheCapacity = 5;
192             }
193             mWebStorageSizeManager = new WebStorageSizeManager(mContext,
194                     new WebStorageSizeManager.StatFsDiskInfo(getAppCachePath()),
195                     new WebStorageSizeManager.WebKitAppCacheInfo(getAppCachePath()));
196             // Workaround b/5254577
197             mPrefs.registerOnSharedPreferenceChangeListener(BrowserSettings.this);
198             if (Build.VERSION.CODENAME.equals("REL")) {
199                 // This is a release build, always startup with debug disabled
200                 setDebugEnabled(false);
201             }
202             if (mPrefs.contains(PREF_TEXT_SIZE)) {
203                 /*
204                  * Update from TextSize enum to zoom percent
205                  * SMALLEST is 50%
206                  * SMALLER is 75%
207                  * NORMAL is 100%
208                  * LARGER is 150%
209                  * LARGEST is 200%
210                  */
211                 switch (getTextSize()) {
212                 case SMALLEST:
213                     setTextZoom(50);
214                     break;
215                 case SMALLER:
216                     setTextZoom(75);
217                     break;
218                 case LARGER:
219                     setTextZoom(150);
220                     break;
221                 case LARGEST:
222                     setTextZoom(200);
223                     break;
224                 }
225                 mPrefs.edit().remove(PREF_TEXT_SIZE).apply();
226             }
227 
228             sFactoryResetUrl = mContext.getResources().getString(R.string.homepage_base);
229             if (sFactoryResetUrl.indexOf("{CID}") != -1) {
230                 sFactoryResetUrl = sFactoryResetUrl.replace("{CID}",
231                     BrowserProvider.getClientId(mContext.getContentResolver()));
232             }
233 
234             synchronized (BrowserSettings.class) {
235                 sInitialized = true;
236                 BrowserSettings.class.notifyAll();
237             }
238         }
239     };
240 
requireInitialization()241     private static void requireInitialization() {
242         synchronized (BrowserSettings.class) {
243             while (!sInitialized) {
244                 try {
245                     BrowserSettings.class.wait();
246                 } catch (InterruptedException e) {
247                 }
248             }
249         }
250     }
251 
252     /**
253      * Syncs all the settings that have a Preference UI
254      */
syncSetting(WebSettings settings)255     private void syncSetting(WebSettings settings) {
256         settings.setGeolocationEnabled(enableGeolocation());
257         settings.setJavaScriptEnabled(enableJavascript());
258         settings.setLightTouchEnabled(enableLightTouch());
259         settings.setNavDump(enableNavDump());
260         settings.setDefaultTextEncodingName(getDefaultTextEncoding());
261         settings.setDefaultZoom(getDefaultZoom());
262         settings.setMinimumFontSize(getMinimumFontSize());
263         settings.setMinimumLogicalFontSize(getMinimumFontSize());
264         settings.setPluginState(getPluginState());
265         settings.setTextZoom(getTextZoom());
266         settings.setLayoutAlgorithm(getLayoutAlgorithm());
267         settings.setJavaScriptCanOpenWindowsAutomatically(!blockPopupWindows());
268         settings.setLoadsImagesAutomatically(loadImages());
269         settings.setLoadWithOverviewMode(loadPageInOverviewMode());
270         settings.setSavePassword(rememberPasswords());
271         settings.setSaveFormData(saveFormdata());
272         settings.setUseWideViewPort(isWideViewport());
273 
274         String ua = mCustomUserAgents.get(settings);
275         if (ua != null) {
276             settings.setUserAgentString(ua);
277         } else {
278             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
279         }
280 
281         if (!(settings instanceof WebSettingsClassic)) return;
282 
283         WebSettingsClassic settingsClassic = (WebSettingsClassic) settings;
284         settingsClassic.setHardwareAccelSkiaEnabled(isSkiaHardwareAccelerated());
285         settingsClassic.setShowVisualIndicator(enableVisualIndicator());
286         settingsClassic.setForceUserScalable(forceEnableUserScalable());
287         settingsClassic.setDoubleTapZoom(getDoubleTapZoom());
288         settingsClassic.setAutoFillEnabled(isAutofillEnabled());
289         settingsClassic.setAutoFillProfile(getAutoFillProfile());
290 
291         boolean useInverted = useInvertedRendering();
292         settingsClassic.setProperty(WebViewProperties.gfxInvertedScreen,
293                 useInverted ? "true" : "false");
294         if (useInverted) {
295           settingsClassic.setProperty(WebViewProperties.gfxInvertedScreenContrast,
296                     Float.toString(getInvertedContrast()));
297         }
298 
299         if (isDebugEnabled()) {
300           settingsClassic.setProperty(WebViewProperties.gfxEnableCpuUploadPath,
301                     enableCpuUploadPath() ? "true" : "false");
302         }
303 
304         settingsClassic.setLinkPrefetchEnabled(mLinkPrefetchAllowed);
305     }
306 
307     /**
308      * Syncs all the settings that have no UI
309      * These cannot change, so we only need to set them once per WebSettings
310      */
syncStaticSettings(WebSettings settings)311     private void syncStaticSettings(WebSettings settings) {
312         settings.setDefaultFontSize(16);
313         settings.setDefaultFixedFontSize(13);
314 
315         // WebView inside Browser doesn't want initial focus to be set.
316         settings.setNeedInitialFocus(false);
317         // Browser supports multiple windows
318         settings.setSupportMultipleWindows(true);
319         // enable smooth transition for better performance during panning or
320         // zooming
321         settings.setEnableSmoothTransition(true);
322         // disable content url access
323         settings.setAllowContentAccess(false);
324 
325         // HTML5 API flags
326         settings.setAppCacheEnabled(true);
327         settings.setDatabaseEnabled(true);
328         settings.setDomStorageEnabled(true);
329 
330         // HTML5 configuration parametersettings.
331         settings.setAppCacheMaxSize(getWebStorageSizeManager().getAppCacheMaxSize());
332         settings.setAppCachePath(getAppCachePath());
333         settings.setDatabasePath(mContext.getDir("databases", 0).getPath());
334         settings.setGeolocationDatabasePath(mContext.getDir("geolocation", 0).getPath());
335         // origin policy for file access
336         settings.setAllowUniversalAccessFromFileURLs(false);
337         settings.setAllowFileAccessFromFileURLs(false);
338 
339         if (!(settings instanceof WebSettingsClassic)) return;
340 
341         WebSettingsClassic settingsClassic = (WebSettingsClassic) settings;
342         settingsClassic.setPageCacheCapacity(getPageCacheCapacity());
343         // WebView should be preserving the memory as much as possible.
344         // However, apps like browser wish to turn on the performance mode which
345         // would require more memory.
346         // TODO: We need to dynamically allocate/deallocate temporary memory for
347         // apps which are trying to use minimal memory. Currently, double
348         // buffering is always turned on, which is unnecessary.
349         settingsClassic.setProperty(WebViewProperties.gfxUseMinimalMemory, "false");
350         settingsClassic.setWorkersEnabled(true);  // This only affects V8.
351     }
352 
syncSharedSettings()353     private void syncSharedSettings() {
354         mNeedsSharedSync = false;
355         CookieManager.getInstance().setAcceptCookie(acceptCookies());
356         if (mController != null) {
357             mController.setShouldShowErrorConsole(enableJavascriptConsole());
358         }
359     }
360 
syncManagedSettings()361     private void syncManagedSettings() {
362         syncSharedSettings();
363         synchronized (mManagedSettings) {
364             Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
365             while (iter.hasNext()) {
366                 WeakReference<WebSettings> ref = iter.next();
367                 WebSettings settings = ref.get();
368                 if (settings == null) {
369                     iter.remove();
370                     continue;
371                 }
372                 syncSetting(settings);
373             }
374         }
375     }
376 
377     @Override
onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key)378     public void onSharedPreferenceChanged(
379             SharedPreferences sharedPreferences, String key) {
380         syncManagedSettings();
381         if (PREF_SEARCH_ENGINE.equals(key)) {
382             updateSearchEngine(false);
383         } else if (PREF_FULLSCREEN.equals(key)) {
384             if (mController != null && mController.getUi() != null) {
385                 mController.getUi().setFullscreen(useFullscreen());
386             }
387         } else if (PREF_ENABLE_QUICK_CONTROLS.equals(key)) {
388             if (mController != null && mController.getUi() != null) {
389                 mController.getUi().setUseQuickControls(sharedPreferences.getBoolean(key, false));
390             }
391         } else if (PREF_LINK_PREFETCH.equals(key)) {
392             updateConnectionType();
393         }
394     }
395 
getFactoryResetHomeUrl(Context context)396     public static String getFactoryResetHomeUrl(Context context) {
397         requireInitialization();
398         return sFactoryResetUrl;
399     }
400 
getLayoutAlgorithm()401     public LayoutAlgorithm getLayoutAlgorithm() {
402         LayoutAlgorithm layoutAlgorithm = LayoutAlgorithm.NORMAL;
403         if (autofitPages()) {
404             layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
405         }
406         if (isDebugEnabled()) {
407             if (isSmallScreen()) {
408                 layoutAlgorithm = LayoutAlgorithm.SINGLE_COLUMN;
409             } else {
410                 if (isNormalLayout()) {
411                     layoutAlgorithm = LayoutAlgorithm.NORMAL;
412                 } else {
413                     layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
414                 }
415             }
416         }
417         return layoutAlgorithm;
418     }
419 
getPageCacheCapacity()420     public int getPageCacheCapacity() {
421         requireInitialization();
422         return mPageCacheCapacity;
423     }
424 
getWebStorageSizeManager()425     public WebStorageSizeManager getWebStorageSizeManager() {
426         requireInitialization();
427         return mWebStorageSizeManager;
428     }
429 
getAppCachePath()430     private String getAppCachePath() {
431         if (mAppCachePath == null) {
432             mAppCachePath = mContext.getDir("appcache", 0).getPath();
433         }
434         return mAppCachePath;
435     }
436 
updateSearchEngine(boolean force)437     private void updateSearchEngine(boolean force) {
438         String searchEngineName = getSearchEngineName();
439         if (force || mSearchEngine == null ||
440                 !mSearchEngine.getName().equals(searchEngineName)) {
441             mSearchEngine = SearchEngines.get(mContext, searchEngineName);
442          }
443     }
444 
getSearchEngine()445     public SearchEngine getSearchEngine() {
446         if (mSearchEngine == null) {
447             updateSearchEngine(false);
448         }
449         return mSearchEngine;
450     }
451 
isDebugEnabled()452     public boolean isDebugEnabled() {
453         requireInitialization();
454         return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
455     }
456 
setDebugEnabled(boolean value)457     public void setDebugEnabled(boolean value) {
458         Editor edit = mPrefs.edit();
459         edit.putBoolean(PREF_DEBUG_MENU, value);
460         if (!value) {
461             // Reset to "safe" value
462             edit.putBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
463         }
464         edit.apply();
465     }
466 
clearCache()467     public void clearCache() {
468         WebIconDatabase.getInstance().removeAllIcons();
469         if (mController != null) {
470             WebView current = mController.getCurrentWebView();
471             if (current != null) {
472                 current.clearCache(true);
473             }
474         }
475     }
476 
clearCookies()477     public void clearCookies() {
478         CookieManager.getInstance().removeAllCookie();
479     }
480 
clearHistory()481     public void clearHistory() {
482         ContentResolver resolver = mContext.getContentResolver();
483         Browser.clearHistory(resolver);
484         Browser.clearSearches(resolver);
485     }
486 
clearFormData()487     public void clearFormData() {
488         WebViewDatabase.getInstance(mContext).clearFormData();
489         if (mController!= null) {
490             WebView currentTopView = mController.getCurrentTopWebView();
491             if (currentTopView != null) {
492                 currentTopView.clearFormData();
493             }
494         }
495     }
496 
clearPasswords()497     public void clearPasswords() {
498         WebViewDatabase db = WebViewDatabase.getInstance(mContext);
499         db.clearUsernamePassword();
500         db.clearHttpAuthUsernamePassword();
501     }
502 
clearDatabases()503     public void clearDatabases() {
504         WebStorage.getInstance().deleteAllData();
505     }
506 
clearLocationAccess()507     public void clearLocationAccess() {
508         GeolocationPermissions.getInstance().clearAll();
509     }
510 
resetDefaultPreferences()511     public void resetDefaultPreferences() {
512         // Preserve autologin setting
513         long gal = mPrefs.getLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, -1);
514         mPrefs.edit()
515                 .clear()
516                 .putLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, gal)
517                 .apply();
518         resetCachedValues();
519         syncManagedSettings();
520     }
521 
resetCachedValues()522     private void resetCachedValues() {
523         updateSearchEngine(false);
524     }
525 
getAutoFillProfile()526     public AutoFillProfile getAutoFillProfile() {
527         return mAutofillHandler.getAutoFillProfile();
528     }
529 
setAutoFillProfile(AutoFillProfile profile, Message msg)530     public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
531         mAutofillHandler.setAutoFillProfile(profile, msg);
532         // Auto-fill will reuse the same profile ID when making edits to the profile,
533         // so we need to force a settings sync (otherwise the SharedPreferences
534         // manager will optimise out the call to onSharedPreferenceChanged(), as
535         // it thinks nothing has changed).
536         syncManagedSettings();
537     }
538 
toggleDebugSettings()539     public void toggleDebugSettings() {
540         setDebugEnabled(!isDebugEnabled());
541     }
542 
hasDesktopUseragent(WebView view)543     public boolean hasDesktopUseragent(WebView view) {
544         return view != null && mCustomUserAgents.get(view.getSettings()) != null;
545     }
546 
toggleDesktopUseragent(WebView view)547     public void toggleDesktopUseragent(WebView view) {
548         if (view == null) {
549             return;
550         }
551         WebSettings settings = view.getSettings();
552         if (mCustomUserAgents.get(settings) != null) {
553             mCustomUserAgents.remove(settings);
554             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
555         } else {
556             mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
557             settings.setUserAgentString(DESKTOP_USERAGENT);
558         }
559     }
560 
getAdjustedMinimumFontSize(int rawValue)561     public static int getAdjustedMinimumFontSize(int rawValue) {
562         rawValue++; // Preference starts at 0, min font at 1
563         if (rawValue > 1) {
564             rawValue += (MIN_FONT_SIZE_OFFSET - 2);
565         }
566         return rawValue;
567     }
568 
getAdjustedTextZoom(int rawValue)569     public int getAdjustedTextZoom(int rawValue) {
570         rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
571         return (int) ((rawValue + 100) * mFontSizeMult);
572     }
573 
getRawTextZoom(int percent)574     static int getRawTextZoom(int percent) {
575         return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
576     }
577 
getAdjustedDoubleTapZoom(int rawValue)578     public int getAdjustedDoubleTapZoom(int rawValue) {
579         rawValue = (rawValue - DOUBLE_TAP_ZOOM_START_VAL) * DOUBLE_TAP_ZOOM_STEP;
580         return (int) ((rawValue + 100) * mFontSizeMult);
581     }
582 
getRawDoubleTapZoom(int percent)583     static int getRawDoubleTapZoom(int percent) {
584         return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
585     }
586 
getPreferences()587     public SharedPreferences getPreferences() {
588         return mPrefs;
589     }
590 
591     // update connectivity-dependent options
updateConnectionType()592     public void updateConnectionType() {
593         ConnectivityManager cm = (ConnectivityManager)
594             mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
595         String linkPrefetchPreference = getLinkPrefetchEnabled();
596         boolean linkPrefetchAllowed = linkPrefetchPreference.
597             equals(getLinkPrefetchAlwaysPreferenceString(mContext));
598         NetworkInfo ni = cm.getActiveNetworkInfo();
599         if (ni != null) {
600             switch (ni.getType()) {
601                 case ConnectivityManager.TYPE_WIFI:
602                 case ConnectivityManager.TYPE_ETHERNET:
603                 case ConnectivityManager.TYPE_BLUETOOTH:
604                     linkPrefetchAllowed |= linkPrefetchPreference.
605                         equals(getLinkPrefetchOnWifiOnlyPreferenceString(mContext));
606                     break;
607                 case ConnectivityManager.TYPE_MOBILE:
608                 case ConnectivityManager.TYPE_MOBILE_DUN:
609                 case ConnectivityManager.TYPE_MOBILE_MMS:
610                 case ConnectivityManager.TYPE_MOBILE_SUPL:
611                 case ConnectivityManager.TYPE_WIMAX:
612                 default:
613                     break;
614             }
615         }
616         if (mLinkPrefetchAllowed != linkPrefetchAllowed) {
617             mLinkPrefetchAllowed = linkPrefetchAllowed;
618             syncManagedSettings();
619         }
620     }
621 
622     // -----------------------------
623     // getter/setters for accessibility_preferences.xml
624     // -----------------------------
625 
626     @Deprecated
getTextSize()627     private TextSize getTextSize() {
628         String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
629         return TextSize.valueOf(textSize);
630     }
631 
getMinimumFontSize()632     public int getMinimumFontSize() {
633         int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
634         return getAdjustedMinimumFontSize(minFont);
635     }
636 
forceEnableUserScalable()637     public boolean forceEnableUserScalable() {
638         return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
639     }
640 
getTextZoom()641     public int getTextZoom() {
642         requireInitialization();
643         int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
644         return getAdjustedTextZoom(textZoom);
645     }
646 
setTextZoom(int percent)647     public void setTextZoom(int percent) {
648         mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
649     }
650 
getDoubleTapZoom()651     public int getDoubleTapZoom() {
652         requireInitialization();
653         int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
654         return getAdjustedDoubleTapZoom(doubleTapZoom);
655     }
656 
setDoubleTapZoom(int percent)657     public void setDoubleTapZoom(int percent) {
658         mPrefs.edit().putInt(PREF_DOUBLE_TAP_ZOOM, getRawDoubleTapZoom(percent)).apply();
659     }
660 
661     // -----------------------------
662     // getter/setters for advanced_preferences.xml
663     // -----------------------------
664 
getSearchEngineName()665     public String getSearchEngineName() {
666         return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
667     }
668 
allowAppTabs()669     public boolean allowAppTabs() {
670         return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
671     }
672 
openInBackground()673     public boolean openInBackground() {
674         return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
675     }
676 
enableJavascript()677     public boolean enableJavascript() {
678         return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
679     }
680 
681     // TODO: Cache
getPluginState()682     public PluginState getPluginState() {
683         String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
684         return PluginState.valueOf(state);
685     }
686 
687     // TODO: Cache
getDefaultZoom()688     public ZoomDensity getDefaultZoom() {
689         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
690         return ZoomDensity.valueOf(zoom);
691     }
692 
loadPageInOverviewMode()693     public boolean loadPageInOverviewMode() {
694         return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
695     }
696 
autofitPages()697     public boolean autofitPages() {
698         return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
699     }
700 
blockPopupWindows()701     public boolean blockPopupWindows() {
702         return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
703     }
704 
loadImages()705     public boolean loadImages() {
706         return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
707     }
708 
getDefaultTextEncoding()709     public String getDefaultTextEncoding() {
710         return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
711     }
712 
713     // -----------------------------
714     // getter/setters for general_preferences.xml
715     // -----------------------------
716 
getHomePage()717     public String getHomePage() {
718         return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
719     }
720 
setHomePage(String value)721     public void setHomePage(String value) {
722         mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
723     }
724 
isAutofillEnabled()725     public boolean isAutofillEnabled() {
726         return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
727     }
728 
setAutofillEnabled(boolean value)729     public void setAutofillEnabled(boolean value) {
730         mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
731     }
732 
733     // -----------------------------
734     // getter/setters for debug_preferences.xml
735     // -----------------------------
736 
isHardwareAccelerated()737     public boolean isHardwareAccelerated() {
738         if (!isDebugEnabled()) {
739             return true;
740         }
741         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
742     }
743 
isSkiaHardwareAccelerated()744     public boolean isSkiaHardwareAccelerated() {
745         if (!isDebugEnabled()) {
746             return false;
747         }
748         return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
749     }
750 
getUserAgent()751     public int getUserAgent() {
752         if (!isDebugEnabled()) {
753             return 0;
754         }
755         return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
756     }
757 
758     // -----------------------------
759     // getter/setters for hidden_debug_preferences.xml
760     // -----------------------------
761 
enableVisualIndicator()762     public boolean enableVisualIndicator() {
763         if (!isDebugEnabled()) {
764             return false;
765         }
766         return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
767     }
768 
enableCpuUploadPath()769     public boolean enableCpuUploadPath() {
770         if (!isDebugEnabled()) {
771             return false;
772         }
773         return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
774     }
775 
enableJavascriptConsole()776     public boolean enableJavascriptConsole() {
777         if (!isDebugEnabled()) {
778             return false;
779         }
780         return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
781     }
782 
isSmallScreen()783     public boolean isSmallScreen() {
784         if (!isDebugEnabled()) {
785             return false;
786         }
787         return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
788     }
789 
isWideViewport()790     public boolean isWideViewport() {
791         if (!isDebugEnabled()) {
792             return true;
793         }
794         return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
795     }
796 
isNormalLayout()797     public boolean isNormalLayout() {
798         if (!isDebugEnabled()) {
799             return false;
800         }
801         return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
802     }
803 
isTracing()804     public boolean isTracing() {
805         if (!isDebugEnabled()) {
806             return false;
807         }
808         return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
809     }
810 
enableLightTouch()811     public boolean enableLightTouch() {
812         if (!isDebugEnabled()) {
813             return false;
814         }
815         return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
816     }
817 
enableNavDump()818     public boolean enableNavDump() {
819         if (!isDebugEnabled()) {
820             return false;
821         }
822         return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
823     }
824 
getJsEngineFlags()825     public String getJsEngineFlags() {
826         if (!isDebugEnabled()) {
827             return "";
828         }
829         return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
830     }
831 
832     // -----------------------------
833     // getter/setters for lab_preferences.xml
834     // -----------------------------
835 
useQuickControls()836     public boolean useQuickControls() {
837         return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
838     }
839 
useMostVisitedHomepage()840     public boolean useMostVisitedHomepage() {
841         return HomeProvider.MOST_VISITED.equals(getHomePage());
842     }
843 
useFullscreen()844     public boolean useFullscreen() {
845         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
846     }
847 
useInvertedRendering()848     public boolean useInvertedRendering() {
849         return mPrefs.getBoolean(PREF_INVERTED, false);
850     }
851 
getInvertedContrast()852     public float getInvertedContrast() {
853         return 1 + (mPrefs.getInt(PREF_INVERTED_CONTRAST, 0) / 10f);
854     }
855 
856     // -----------------------------
857     // getter/setters for privacy_security_preferences.xml
858     // -----------------------------
859 
showSecurityWarnings()860     public boolean showSecurityWarnings() {
861         return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
862     }
863 
acceptCookies()864     public boolean acceptCookies() {
865         return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
866     }
867 
saveFormdata()868     public boolean saveFormdata() {
869         return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
870     }
871 
enableGeolocation()872     public boolean enableGeolocation() {
873         return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
874     }
875 
rememberPasswords()876     public boolean rememberPasswords() {
877         return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
878     }
879 
880     // -----------------------------
881     // getter/setters for bandwidth_preferences.xml
882     // -----------------------------
883 
getPreloadOnWifiOnlyPreferenceString(Context context)884     public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
885         return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
886     }
887 
getPreloadAlwaysPreferenceString(Context context)888     public static String getPreloadAlwaysPreferenceString(Context context) {
889         return context.getResources().getString(R.string.pref_data_preload_value_always);
890     }
891 
892     private static final String DEAULT_PRELOAD_SECURE_SETTING_KEY =
893             "browser_default_preload_setting";
894 
getDefaultPreloadSetting()895     public String getDefaultPreloadSetting() {
896         String preload = Settings.Secure.getString(mContext.getContentResolver(),
897                 DEAULT_PRELOAD_SECURE_SETTING_KEY);
898         if (preload == null) {
899             preload = mContext.getResources().getString(R.string.pref_data_preload_default_value);
900         }
901         return preload;
902     }
903 
getPreloadEnabled()904     public String getPreloadEnabled() {
905         return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
906     }
907 
getLinkPrefetchOnWifiOnlyPreferenceString(Context context)908     public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
909         return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
910     }
911 
getLinkPrefetchAlwaysPreferenceString(Context context)912     public static String getLinkPrefetchAlwaysPreferenceString(Context context) {
913         return context.getResources().getString(R.string.pref_link_prefetch_value_always);
914     }
915 
916     private static final String DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY =
917             "browser_default_link_prefetch_setting";
918 
getDefaultLinkPrefetchSetting()919     public String getDefaultLinkPrefetchSetting() {
920         String preload = Settings.Secure.getString(mContext.getContentResolver(),
921             DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY);
922         if (preload == null) {
923             preload = mContext.getResources().getString(R.string.pref_link_prefetch_default_value);
924         }
925         return preload;
926     }
927 
getLinkPrefetchEnabled()928     public String getLinkPrefetchEnabled() {
929         return mPrefs.getString(PREF_LINK_PREFETCH, getDefaultLinkPrefetchSetting());
930     }
931 
932     // -----------------------------
933     // getter/setters for browser recovery
934     // -----------------------------
935     /**
936      * The last time browser was started.
937      * @return The last browser start time as System.currentTimeMillis. This
938      * can be 0 if this is the first time or the last tab was closed.
939      */
getLastRecovered()940     public long getLastRecovered() {
941         return mPrefs.getLong(KEY_LAST_RECOVERED, 0);
942     }
943 
944     /**
945      * Sets the last browser start time.
946      * @param time The last time as System.currentTimeMillis that the browser
947      * was started. This should be set to 0 if the last tab is closed.
948      */
setLastRecovered(long time)949     public void setLastRecovered(long time) {
950         mPrefs.edit()
951             .putLong(KEY_LAST_RECOVERED, time)
952             .apply();
953     }
954 
955     /**
956      * Used to determine whether or not the previous browser run crashed. Once
957      * the previous state has been determined, the value will be set to false
958      * until a pause is received.
959      * @return true if the last browser run was paused or false if it crashed.
960      */
wasLastRunPaused()961     public boolean wasLastRunPaused() {
962         return mPrefs.getBoolean(KEY_LAST_RUN_PAUSED, false);
963     }
964 
965     /**
966      * Sets whether or not the last run was a pause or crash.
967      * @param isPaused Set to true When a pause is received or false after
968      * resuming.
969      */
setLastRunPaused(boolean isPaused)970     public void setLastRunPaused(boolean isPaused) {
971         mPrefs.edit()
972             .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
973             .apply();
974     }
975 }
976