BrowserSettings.java revision 934dfe5246cd151ffd60eb6277088f58f657b81c
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
17package com.android.browser;
18
19import android.app.ActivityManager;
20import android.content.ContentResolver;
21import android.content.Context;
22import android.content.SharedPreferences;
23import android.content.SharedPreferences.Editor;
24import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
25import android.net.ConnectivityManager;
26import android.net.NetworkInfo;
27import android.os.Build;
28import android.os.Message;
29import android.preference.PreferenceManager;
30import android.provider.Browser;
31import android.provider.Settings;
32import android.util.DisplayMetrics;
33import android.webkit.CookieManager;
34import android.webkit.GeolocationPermissions;
35import android.webkit.WebIconDatabase;
36import android.webkit.WebSettings;
37import android.webkit.WebSettings.LayoutAlgorithm;
38import android.webkit.WebSettings.PluginState;
39import android.webkit.WebSettings.TextSize;
40import android.webkit.WebSettings.ZoomDensity;
41import android.webkit.WebStorage;
42import android.webkit.WebView;
43import android.webkit.WebViewDatabase;
44
45import com.android.browser.homepages.HomeProvider;
46import com.android.browser.provider.BrowserProvider;
47import com.android.browser.search.SearchEngine;
48import com.android.browser.search.SearchEngines;
49
50import java.lang.ref.WeakReference;
51import java.util.Iterator;
52import java.util.LinkedList;
53import java.util.WeakHashMap;
54
55/**
56 * Class for managing settings
57 */
58public 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
129    public static void initialize(final Context context) {
130        sInstance = new BrowserSettings(context);
131    }
132
133    public static BrowserSettings getInstance() {
134        return sInstance;
135    }
136
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
145    public void setController(Controller controller) {
146        mController = controller;
147        if (sInitialized) {
148            syncSharedSettings();
149        }
150    }
151
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
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
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     */
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     */
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
310    private void syncSharedSettings() {
311        mNeedsSharedSync = false;
312        CookieManager.getInstance().setAcceptCookie(acceptCookies());
313        if (mController != null) {
314            for (Tab tab : mController.getTabs()) {
315                tab.setAcceptThirdPartyCookies(acceptCookies());
316            }
317            mController.setShouldShowErrorConsole(enableJavascriptConsole());
318        }
319    }
320
321    private void syncManagedSettings() {
322        syncSharedSettings();
323        synchronized (mManagedSettings) {
324            Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
325            while (iter.hasNext()) {
326                WeakReference<WebSettings> ref = iter.next();
327                WebSettings settings = ref.get();
328                if (settings == null) {
329                    iter.remove();
330                    continue;
331                }
332                syncSetting(settings);
333            }
334        }
335    }
336
337    @Override
338    public void onSharedPreferenceChanged(
339            SharedPreferences sharedPreferences, String key) {
340        syncManagedSettings();
341        if (PREF_SEARCH_ENGINE.equals(key)) {
342            updateSearchEngine(false);
343        } else if (PREF_FULLSCREEN.equals(key)) {
344            if (mController != null && mController.getUi() != null) {
345                mController.getUi().setFullscreen(useFullscreen());
346            }
347        } else if (PREF_ENABLE_QUICK_CONTROLS.equals(key)) {
348            if (mController != null && mController.getUi() != null) {
349                mController.getUi().setUseQuickControls(sharedPreferences.getBoolean(key, false));
350            }
351        } else if (PREF_LINK_PREFETCH.equals(key)) {
352            updateConnectionType();
353        }
354    }
355
356    public static String getFactoryResetHomeUrl(Context context) {
357        requireInitialization();
358        return sFactoryResetUrl;
359    }
360
361    public LayoutAlgorithm getLayoutAlgorithm() {
362        LayoutAlgorithm layoutAlgorithm = LayoutAlgorithm.NORMAL;
363        final LayoutAlgorithm autosize = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ?
364                LayoutAlgorithm.TEXT_AUTOSIZING : LayoutAlgorithm.NARROW_COLUMNS;
365
366        if (autofitPages()) {
367            layoutAlgorithm = autosize;
368        }
369        if (isDebugEnabled()) {
370            if (isNormalLayout()) {
371                layoutAlgorithm = LayoutAlgorithm.NORMAL;
372            } else {
373                layoutAlgorithm = autosize;
374            }
375        }
376        return layoutAlgorithm;
377    }
378
379    public int getPageCacheCapacity() {
380        requireInitialization();
381        return mPageCacheCapacity;
382    }
383
384    public WebStorageSizeManager getWebStorageSizeManager() {
385        requireInitialization();
386        return mWebStorageSizeManager;
387    }
388
389    private String getAppCachePath() {
390        if (mAppCachePath == null) {
391            mAppCachePath = mContext.getDir("appcache", 0).getPath();
392        }
393        return mAppCachePath;
394    }
395
396    private void updateSearchEngine(boolean force) {
397        String searchEngineName = getSearchEngineName();
398        if (force || mSearchEngine == null ||
399                !mSearchEngine.getName().equals(searchEngineName)) {
400            mSearchEngine = SearchEngines.get(mContext, searchEngineName);
401         }
402    }
403
404    public SearchEngine getSearchEngine() {
405        if (mSearchEngine == null) {
406            updateSearchEngine(false);
407        }
408        return mSearchEngine;
409    }
410
411    public boolean isDebugEnabled() {
412        requireInitialization();
413        return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
414    }
415
416    public void setDebugEnabled(boolean value) {
417        Editor edit = mPrefs.edit();
418        edit.putBoolean(PREF_DEBUG_MENU, value);
419        if (!value) {
420            // Reset to "safe" value
421            edit.putBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
422        }
423        edit.apply();
424    }
425
426    public void clearCache() {
427        WebIconDatabase.getInstance().removeAllIcons();
428        if (mController != null) {
429            WebView current = mController.getCurrentWebView();
430            if (current != null) {
431                current.clearCache(true);
432            }
433        }
434    }
435
436    public void clearCookies() {
437        CookieManager.getInstance().removeAllCookie();
438    }
439
440    public void clearHistory() {
441        ContentResolver resolver = mContext.getContentResolver();
442        Browser.clearHistory(resolver);
443        Browser.clearSearches(resolver);
444    }
445
446    public void clearFormData() {
447        WebViewDatabase.getInstance(mContext).clearFormData();
448        if (mController!= null) {
449            WebView currentTopView = mController.getCurrentTopWebView();
450            if (currentTopView != null) {
451                currentTopView.clearFormData();
452            }
453        }
454    }
455
456    public void clearPasswords() {
457        WebViewDatabase db = WebViewDatabase.getInstance(mContext);
458        db.clearUsernamePassword();
459        db.clearHttpAuthUsernamePassword();
460    }
461
462    public void clearDatabases() {
463        WebStorage.getInstance().deleteAllData();
464    }
465
466    public void clearLocationAccess() {
467        GeolocationPermissions.getInstance().clearAll();
468    }
469
470    public void resetDefaultPreferences() {
471        // Preserve autologin setting
472        long gal = mPrefs.getLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, -1);
473        mPrefs.edit()
474                .clear()
475                .putLong(GoogleAccountLogin.PREF_AUTOLOGIN_TIME, gal)
476                .apply();
477        resetCachedValues();
478        syncManagedSettings();
479    }
480
481    private void resetCachedValues() {
482        updateSearchEngine(false);
483    }
484
485    public void toggleDebugSettings() {
486        setDebugEnabled(!isDebugEnabled());
487    }
488
489    public boolean hasDesktopUseragent(WebView view) {
490        return view != null && mCustomUserAgents.get(view.getSettings()) != null;
491    }
492
493    public void toggleDesktopUseragent(WebView view) {
494        if (view == null) {
495            return;
496        }
497        WebSettings settings = view.getSettings();
498        if (mCustomUserAgents.get(settings) != null) {
499            mCustomUserAgents.remove(settings);
500            settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
501        } else {
502            mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
503            settings.setUserAgentString(DESKTOP_USERAGENT);
504        }
505    }
506
507    public static int getAdjustedMinimumFontSize(int rawValue) {
508        rawValue++; // Preference starts at 0, min font at 1
509        if (rawValue > 1) {
510            rawValue += (MIN_FONT_SIZE_OFFSET - 2);
511        }
512        return rawValue;
513    }
514
515    public int getAdjustedTextZoom(int rawValue) {
516        rawValue = (rawValue - TEXT_ZOOM_START_VAL) * TEXT_ZOOM_STEP;
517        return (int) ((rawValue + 100) * mFontSizeMult);
518    }
519
520    static int getRawTextZoom(int percent) {
521        return (percent - 100) / TEXT_ZOOM_STEP + TEXT_ZOOM_START_VAL;
522    }
523
524    public int getAdjustedDoubleTapZoom(int rawValue) {
525        rawValue = (rawValue - DOUBLE_TAP_ZOOM_START_VAL) * DOUBLE_TAP_ZOOM_STEP;
526        return (int) ((rawValue + 100) * mFontSizeMult);
527    }
528
529    static int getRawDoubleTapZoom(int percent) {
530        return (percent - 100) / DOUBLE_TAP_ZOOM_STEP + DOUBLE_TAP_ZOOM_START_VAL;
531    }
532
533    public SharedPreferences getPreferences() {
534        return mPrefs;
535    }
536
537    // update connectivity-dependent options
538    public void updateConnectionType() {
539        ConnectivityManager cm = (ConnectivityManager)
540            mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
541        String linkPrefetchPreference = getLinkPrefetchEnabled();
542        boolean linkPrefetchAllowed = linkPrefetchPreference.
543            equals(getLinkPrefetchAlwaysPreferenceString(mContext));
544        NetworkInfo ni = cm.getActiveNetworkInfo();
545        if (ni != null) {
546            switch (ni.getType()) {
547                case ConnectivityManager.TYPE_WIFI:
548                case ConnectivityManager.TYPE_ETHERNET:
549                case ConnectivityManager.TYPE_BLUETOOTH:
550                    linkPrefetchAllowed |= linkPrefetchPreference.
551                        equals(getLinkPrefetchOnWifiOnlyPreferenceString(mContext));
552                    break;
553                case ConnectivityManager.TYPE_MOBILE:
554                case ConnectivityManager.TYPE_MOBILE_DUN:
555                case ConnectivityManager.TYPE_MOBILE_MMS:
556                case ConnectivityManager.TYPE_MOBILE_SUPL:
557                case ConnectivityManager.TYPE_WIMAX:
558                default:
559                    break;
560            }
561        }
562        if (mLinkPrefetchAllowed != linkPrefetchAllowed) {
563            mLinkPrefetchAllowed = linkPrefetchAllowed;
564            syncManagedSettings();
565        }
566    }
567
568    // -----------------------------
569    // getter/setters for accessibility_preferences.xml
570    // -----------------------------
571
572    @Deprecated
573    private TextSize getTextSize() {
574        String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
575        return TextSize.valueOf(textSize);
576    }
577
578    public int getMinimumFontSize() {
579        int minFont = mPrefs.getInt(PREF_MIN_FONT_SIZE, 0);
580        return getAdjustedMinimumFontSize(minFont);
581    }
582
583    public boolean forceEnableUserScalable() {
584        return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
585    }
586
587    public int getTextZoom() {
588        requireInitialization();
589        int textZoom = mPrefs.getInt(PREF_TEXT_ZOOM, 10);
590        return getAdjustedTextZoom(textZoom);
591    }
592
593    public void setTextZoom(int percent) {
594        mPrefs.edit().putInt(PREF_TEXT_ZOOM, getRawTextZoom(percent)).apply();
595    }
596
597    public int getDoubleTapZoom() {
598        requireInitialization();
599        int doubleTapZoom = mPrefs.getInt(PREF_DOUBLE_TAP_ZOOM, 5);
600        return getAdjustedDoubleTapZoom(doubleTapZoom);
601    }
602
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
611    public String getSearchEngineName() {
612        return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
613    }
614
615    public boolean allowAppTabs() {
616        return mPrefs.getBoolean(PREF_ALLOW_APP_TABS, false);
617    }
618
619    public boolean openInBackground() {
620        return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
621    }
622
623    public boolean enableJavascript() {
624        return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
625    }
626
627    // TODO: Cache
628    public PluginState getPluginState() {
629        String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
630        return PluginState.valueOf(state);
631    }
632
633    // TODO: Cache
634    public ZoomDensity getDefaultZoom() {
635        String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
636        return ZoomDensity.valueOf(zoom);
637    }
638
639    public boolean loadPageInOverviewMode() {
640        return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
641    }
642
643    public boolean autofitPages() {
644        return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
645    }
646
647    public boolean blockPopupWindows() {
648        return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
649    }
650
651    public boolean loadImages() {
652        return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
653    }
654
655    public String getDefaultTextEncoding() {
656        return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
657    }
658
659    // -----------------------------
660    // getter/setters for general_preferences.xml
661    // -----------------------------
662
663    public String getHomePage() {
664        return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
665    }
666
667    public void setHomePage(String value) {
668        mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
669    }
670
671    public boolean isAutofillEnabled() {
672        return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
673    }
674
675    public void setAutofillEnabled(boolean value) {
676        mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
677    }
678
679    // -----------------------------
680    // getter/setters for debug_preferences.xml
681    // -----------------------------
682
683    public boolean isHardwareAccelerated() {
684        if (!isDebugEnabled()) {
685            return true;
686        }
687        return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
688    }
689
690    public boolean isSkiaHardwareAccelerated() {
691        if (!isDebugEnabled()) {
692            return false;
693        }
694        return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL_SKIA, false);
695    }
696
697    public int getUserAgent() {
698        if (!isDebugEnabled()) {
699            return 0;
700        }
701        return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
702    }
703
704    // -----------------------------
705    // getter/setters for hidden_debug_preferences.xml
706    // -----------------------------
707
708    public boolean enableVisualIndicator() {
709        if (!isDebugEnabled()) {
710            return false;
711        }
712        return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
713    }
714
715    public boolean enableCpuUploadPath() {
716        if (!isDebugEnabled()) {
717            return false;
718        }
719        return mPrefs.getBoolean(PREF_ENABLE_CPU_UPLOAD_PATH, false);
720    }
721
722    public boolean enableJavascriptConsole() {
723        if (!isDebugEnabled()) {
724            return false;
725        }
726        return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
727    }
728
729    public boolean isWideViewport() {
730        if (!isDebugEnabled()) {
731            return true;
732        }
733        return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
734    }
735
736    public boolean isNormalLayout() {
737        if (!isDebugEnabled()) {
738            return false;
739        }
740        return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
741    }
742
743    public boolean isTracing() {
744        if (!isDebugEnabled()) {
745            return false;
746        }
747        return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
748    }
749
750    public boolean enableLightTouch() {
751        if (!isDebugEnabled()) {
752            return false;
753        }
754        return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
755    }
756
757    public boolean enableNavDump() {
758        if (!isDebugEnabled()) {
759            return false;
760        }
761        return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
762    }
763
764    public String getJsEngineFlags() {
765        if (!isDebugEnabled()) {
766            return "";
767        }
768        return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
769    }
770
771    // -----------------------------
772    // getter/setters for lab_preferences.xml
773    // -----------------------------
774
775    public boolean useQuickControls() {
776        return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
777    }
778
779    public boolean useMostVisitedHomepage() {
780        return HomeProvider.MOST_VISITED.equals(getHomePage());
781    }
782
783    public boolean useFullscreen() {
784        return mPrefs.getBoolean(PREF_FULLSCREEN, false);
785    }
786
787    public boolean useInvertedRendering() {
788        return mPrefs.getBoolean(PREF_INVERTED, false);
789    }
790
791    public float getInvertedContrast() {
792        return 1 + (mPrefs.getInt(PREF_INVERTED_CONTRAST, 0) / 10f);
793    }
794
795    // -----------------------------
796    // getter/setters for privacy_security_preferences.xml
797    // -----------------------------
798
799    public boolean showSecurityWarnings() {
800        return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
801    }
802
803    public boolean acceptCookies() {
804        return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
805    }
806
807    public boolean saveFormdata() {
808        return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
809    }
810
811    public boolean enableGeolocation() {
812        return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
813    }
814
815    public boolean rememberPasswords() {
816        return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
817    }
818
819    // -----------------------------
820    // getter/setters for bandwidth_preferences.xml
821    // -----------------------------
822
823    public static String getPreloadOnWifiOnlyPreferenceString(Context context) {
824        return context.getResources().getString(R.string.pref_data_preload_value_wifi_only);
825    }
826
827    public static String getPreloadAlwaysPreferenceString(Context context) {
828        return context.getResources().getString(R.string.pref_data_preload_value_always);
829    }
830
831    private static final String DEAULT_PRELOAD_SECURE_SETTING_KEY =
832            "browser_default_preload_setting";
833
834    public String getDefaultPreloadSetting() {
835        String preload = Settings.Secure.getString(mContext.getContentResolver(),
836                DEAULT_PRELOAD_SECURE_SETTING_KEY);
837        if (preload == null) {
838            preload = mContext.getResources().getString(R.string.pref_data_preload_default_value);
839        }
840        return preload;
841    }
842
843    public String getPreloadEnabled() {
844        return mPrefs.getString(PREF_DATA_PRELOAD, getDefaultPreloadSetting());
845    }
846
847    public static String getLinkPrefetchOnWifiOnlyPreferenceString(Context context) {
848        return context.getResources().getString(R.string.pref_link_prefetch_value_wifi_only);
849    }
850
851    public static String getLinkPrefetchAlwaysPreferenceString(Context context) {
852        return context.getResources().getString(R.string.pref_link_prefetch_value_always);
853    }
854
855    private static final String DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY =
856            "browser_default_link_prefetch_setting";
857
858    public String getDefaultLinkPrefetchSetting() {
859        String preload = Settings.Secure.getString(mContext.getContentResolver(),
860            DEFAULT_LINK_PREFETCH_SECURE_SETTING_KEY);
861        if (preload == null) {
862            preload = mContext.getResources().getString(R.string.pref_link_prefetch_default_value);
863        }
864        return preload;
865    }
866
867    public String getLinkPrefetchEnabled() {
868        return mPrefs.getString(PREF_LINK_PREFETCH, getDefaultLinkPrefetchSetting());
869    }
870
871    // -----------------------------
872    // getter/setters for browser recovery
873    // -----------------------------
874    /**
875     * The last time browser was started.
876     * @return The last browser start time as System.currentTimeMillis. This
877     * can be 0 if this is the first time or the last tab was closed.
878     */
879    public long getLastRecovered() {
880        return mPrefs.getLong(KEY_LAST_RECOVERED, 0);
881    }
882
883    /**
884     * Sets the last browser start time.
885     * @param time The last time as System.currentTimeMillis that the browser
886     * was started. This should be set to 0 if the last tab is closed.
887     */
888    public void setLastRecovered(long time) {
889        mPrefs.edit()
890            .putLong(KEY_LAST_RECOVERED, time)
891            .apply();
892    }
893
894    /**
895     * Used to determine whether or not the previous browser run crashed. Once
896     * the previous state has been determined, the value will be set to false
897     * until a pause is received.
898     * @return true if the last browser run was paused or false if it crashed.
899     */
900    public boolean wasLastRunPaused() {
901        return mPrefs.getBoolean(KEY_LAST_RUN_PAUSED, false);
902    }
903
904    /**
905     * Sets whether or not the last run was a pause or crash.
906     * @param isPaused Set to true When a pause is received or false after
907     * resuming.
908     */
909    public void setLastRunPaused(boolean isPaused) {
910        mPrefs.edit()
911            .putBoolean(KEY_LAST_RUN_PAUSED, isPaused)
912            .apply();
913    }
914}
915