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