BrowserSettings.java revision ba6d7b853c32ad6c3be26c443daa61f322bcfdc2
1/*
2 * Copyright (C) 2007 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.Activity;
20import android.content.ContentResolver;
21import android.content.Context;
22import android.content.pm.ActivityInfo;
23import android.content.SharedPreferences;
24import android.content.SharedPreferences.Editor;
25import android.view.WindowManager;
26import android.webkit.CacheManager;
27import android.webkit.CookieManager;
28import android.webkit.WebViewDatabase;
29import android.webkit.WebIconDatabase;
30import android.webkit.WebSettings;
31import android.preference.PreferenceManager;
32import android.provider.Browser;
33
34import java.util.HashMap;
35import java.util.Observable;
36
37/*
38 * Package level class for storing various WebView and Browser settings. To use
39 * this class:
40 * BrowserSettings s = BrowserSettings.getInstance();
41 * s.addObserver(webView.getSettings());
42 * s.loadFromDb(context); // Only needed on app startup
43 * s.javaScriptEnabled = true;
44 * ... // set any other settings
45 * s.update(); // this will update all the observers
46 *
47 * To remove an observer:
48 * s.deleteObserver(webView.getSettings());
49 */
50class BrowserSettings extends Observable {
51
52    // Public variables for settings
53    // NOTE: these defaults need to be kept in sync with the XML
54    // until the performance of PreferenceManager.setDefaultValues()
55    // is improved.
56    private boolean loadsImagesAutomatically = true;
57    private boolean javaScriptEnabled = true;
58    private boolean pluginsEnabled = true;
59    private String pluginsPath;  // default value set in loadFromDb().
60    private boolean javaScriptCanOpenWindowsAutomatically = false;
61    private boolean showSecurityWarnings = true;
62    private boolean rememberPasswords = true;
63    private boolean saveFormData = true;
64    private boolean openInBackground = false;
65    private String defaultTextEncodingName;
66    private String homeUrl = "http://www.google.com/m";
67    private boolean loginInitialized = false;
68    private int orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
69    private boolean autoFitPage = true;
70    private boolean showDebugSettings = false;
71
72    // Development settings
73    public WebSettings.LayoutAlgorithm layoutAlgorithm =
74        WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
75    private boolean useWideViewPort = true;
76    private int userAgent = 0;
77    private boolean tracing = false;
78    private boolean lightTouch = false;
79    private boolean navDump = false;
80    // Browser only settings
81    private boolean doFlick = false;
82
83    // Private preconfigured values
84    private static int minimumFontSize = 8;
85    private static int minimumLogicalFontSize = 8;
86    private static int defaultFontSize = 16;
87    private static int defaultFixedFontSize = 13;
88    private static WebSettings.TextSize textSize =
89        WebSettings.TextSize.NORMAL;
90
91    // Preference keys that are used outside this class
92    public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
93    public final static String PREF_CLEAR_COOKIES = "privacy_clear_cookies";
94    public final static String PREF_CLEAR_HISTORY = "privacy_clear_history";
95    public final static String PREF_HOMEPAGE = "homepage";
96    public final static String PREF_CLEAR_FORM_DATA =
97            "privacy_clear_form_data";
98    public final static String PREF_CLEAR_PASSWORDS =
99            "privacy_clear_passwords";
100    public final static String PREF_EXTRAS_RESET_DEFAULTS =
101            "reset_default_preferences";
102    public final static String PREF_DEBUG_SETTINGS = "debug_menu";
103    public final static String PREF_GEARS_SETTINGS = "gears_settings";
104    public final static String PREF_TEXT_SIZE = "text_size";
105
106    // Value to truncate strings when adding them to a TextView within
107    // a ListView
108    public final static int MAX_TEXTVIEW_LEN = 80;
109
110    private TabControl mTabControl;
111
112    // Single instance of the BrowserSettings for use in the Browser app.
113    private static BrowserSettings sSingleton;
114
115    // Private map of WebSettings to Observer objects used when deleting an
116    // observer.
117    private HashMap<WebSettings,Observer> mWebSettingsToObservers =
118        new HashMap<WebSettings,Observer>();
119
120    /*
121     * An observer wrapper for updating a WebSettings object with the new
122     * settings after a call to BrowserSettings.update().
123     */
124    static class Observer implements java.util.Observer {
125        // Private WebSettings object that will be updated.
126        private WebSettings mSettings;
127
128        Observer(WebSettings w) {
129            mSettings = w;
130        }
131
132        public void update(Observable o, Object arg) {
133            BrowserSettings b = (BrowserSettings)o;
134            WebSettings s = mSettings;
135
136            s.setLayoutAlgorithm(b.layoutAlgorithm);
137            s.setUserAgent(b.userAgent);
138            s.setUseWideViewPort(b.useWideViewPort);
139            s.setLoadsImagesAutomatically(b.loadsImagesAutomatically);
140            s.setJavaScriptEnabled(b.javaScriptEnabled);
141            s.setPluginsEnabled(b.pluginsEnabled);
142            s.setPluginsPath(b.pluginsPath);
143            s.setJavaScriptCanOpenWindowsAutomatically(
144                    b.javaScriptCanOpenWindowsAutomatically);
145            s.setDefaultTextEncodingName(b.defaultTextEncodingName);
146            s.setMinimumFontSize(b.minimumFontSize);
147            s.setMinimumLogicalFontSize(b.minimumLogicalFontSize);
148            s.setDefaultFontSize(b.defaultFontSize);
149            s.setDefaultFixedFontSize(b.defaultFixedFontSize);
150            s.setNavDump(b.navDump);
151            s.setTextSize(b.textSize);
152            s.setLightTouchEnabled(b.lightTouch);
153            s.setSaveFormData(b.saveFormData);
154            s.setSavePassword(b.rememberPasswords);
155
156            // WebView inside Browser doesn't want initial focus to be set.
157            s.setNeedInitialFocus(false);
158            // Browser supports multiple windows
159            s.setSupportMultipleWindows(true);
160        }
161    }
162
163    /**
164     * Load settings from the browser app's database.
165     * NOTE: Strings used for the preferences must match those specified
166     * in the browser_preferences.xml
167     * @param ctx A Context object used to query the browser's settings
168     *            database. If the database exists, the saved settings will be
169     *            stored in this BrowserSettings object. This will update all
170     *            observers of this object.
171     */
172    public void loadFromDb(Context ctx) {
173        SharedPreferences p =
174                PreferenceManager.getDefaultSharedPreferences(ctx);
175
176        // Set the default value for the plugins path to the application's
177        // local directory.
178        pluginsPath = ctx.getDir("plugins", 0).getPath();
179
180        // Load the defaults from the xml
181        // This call is TOO SLOW, need to manually keep the defaults
182        // in sync
183        //PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences);
184        syncSharedPreferences(p);
185    }
186
187    /* package */ void syncSharedPreferences(SharedPreferences p) {
188        homeUrl =
189            p.getString(PREF_HOMEPAGE, homeUrl);
190        loadsImagesAutomatically = p.getBoolean("load_images",
191                loadsImagesAutomatically);
192        javaScriptEnabled = p.getBoolean("enable_javascript",
193                javaScriptEnabled);
194        pluginsEnabled = p.getBoolean("enable_plugins",
195                pluginsEnabled);
196        pluginsPath = p.getString("plugins_path", pluginsPath);
197        javaScriptCanOpenWindowsAutomatically = !p.getBoolean(
198            "block_popup_windows",
199            !javaScriptCanOpenWindowsAutomatically);
200        showSecurityWarnings = p.getBoolean("show_security_warnings",
201                showSecurityWarnings);
202        rememberPasswords = p.getBoolean("remember_passwords",
203                rememberPasswords);
204        saveFormData = p.getBoolean("save_formdata",
205                saveFormData);
206        boolean accept_cookies = p.getBoolean("accept_cookies",
207                CookieManager.getInstance().acceptCookie());
208        CookieManager.getInstance().setAcceptCookie(accept_cookies);
209        openInBackground = p.getBoolean("open_in_background", openInBackground);
210        loginInitialized = p.getBoolean("login_initialized", loginInitialized);
211        textSize = WebSettings.TextSize.valueOf(
212                p.getString(PREF_TEXT_SIZE, textSize.name()));
213        orientation = p.getInt("orientation", orientation);
214        autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
215        useWideViewPort = true; // use wide view port for either setting
216        if (autoFitPage) {
217            layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
218        } else {
219            layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
220        }
221
222        showDebugSettings =
223                p.getBoolean(PREF_DEBUG_SETTINGS, showDebugSettings);
224        // Debug menu items have precidence if the menu is visible
225        if (showDebugSettings) {
226            boolean small_screen = p.getBoolean("small_screen",
227                    layoutAlgorithm ==
228                    WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
229            if (small_screen) {
230                layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN;
231            } else {
232                boolean normal_layout = p.getBoolean("normal_layout",
233                        layoutAlgorithm == WebSettings.LayoutAlgorithm.NORMAL);
234                if (normal_layout) {
235                    layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
236                } else {
237                    layoutAlgorithm =
238                            WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
239                }
240            }
241            useWideViewPort = p.getBoolean("wide_viewport", useWideViewPort);
242            tracing = p.getBoolean("enable_tracing", tracing);
243            lightTouch = p.getBoolean("enable_light_touch", lightTouch);
244            navDump = p.getBoolean("enable_nav_dump", navDump);
245            doFlick = p.getBoolean("enable_flick", doFlick);
246            userAgent = Integer.parseInt(p.getString("user_agent", "0"));
247        }
248        update();
249    }
250
251    public String getPluginsPath() {
252        return pluginsPath;
253    }
254
255    public String getHomePage() {
256        return homeUrl;
257    }
258
259    public void setHomePage(Context context, String url) {
260        Editor ed = PreferenceManager.
261                getDefaultSharedPreferences(context).edit();
262        ed.putString(PREF_HOMEPAGE, url);
263        ed.commit();
264        homeUrl = url;
265    }
266
267    public boolean isLoginInitialized() {
268        return loginInitialized;
269    }
270
271    public void setLoginInitialized(Context context) {
272        loginInitialized = true;
273        Editor ed = PreferenceManager.
274                getDefaultSharedPreferences(context).edit();
275        ed.putBoolean("login_initialized", loginInitialized);
276        ed.commit();
277    }
278
279    public int getOrientation() {
280        return orientation;
281    }
282
283    public void setOrientation(Context context, int o) {
284        if (orientation == o) {
285            return;
286        }
287        orientation = o;
288        Editor ed = PreferenceManager.
289                getDefaultSharedPreferences(context).edit();
290        ed.putInt("orientation", orientation);
291        ed.commit();
292    }
293
294    public WebSettings.TextSize getTextSize() {
295        return textSize;
296    }
297
298    public boolean openInBackground() {
299        return openInBackground;
300    }
301
302    public boolean showSecurityWarnings() {
303        return showSecurityWarnings;
304    }
305
306    public boolean isTracing() {
307        return tracing;
308    }
309
310    public boolean isLightTouch() {
311        return lightTouch;
312    }
313
314    public boolean isNavDump() {
315        return navDump;
316    }
317
318    public boolean doFlick() {
319        return doFlick;
320    }
321
322    public boolean showDebugSettings() {
323        return showDebugSettings;
324    }
325
326    public void toggleDebugSettings() {
327        showDebugSettings = !showDebugSettings;
328    }
329
330    /**
331     * Add a WebSettings object to the list of observers that will be updated
332     * when update() is called.
333     *
334     * @param s A WebSettings object that is strictly tied to the life of a
335     *            WebView.
336     */
337    public Observer addObserver(WebSettings s) {
338        Observer old = mWebSettingsToObservers.get(s);
339        if (old != null) {
340            super.deleteObserver(old);
341        }
342        Observer o = new Observer(s);
343        mWebSettingsToObservers.put(s, o);
344        super.addObserver(o);
345        return o;
346    }
347
348    /**
349     * Delete the given WebSettings observer from the list of observers.
350     * @param s The WebSettings object to be deleted.
351     */
352    public void deleteObserver(WebSettings s) {
353        Observer o = mWebSettingsToObservers.get(s);
354        if (o != null) {
355            mWebSettingsToObservers.remove(s);
356            super.deleteObserver(o);
357        }
358    }
359
360    /*
361     * Package level method for obtaining a single app instance of the
362     * BrowserSettings.
363     */
364    /*package*/ static BrowserSettings getInstance() {
365        if (sSingleton == null ) {
366            sSingleton = new BrowserSettings();
367        }
368        return sSingleton;
369    }
370
371    /*
372     * Package level method for associating the BrowserSettings with TabControl
373     */
374    /* package */void setTabControl(TabControl tabControl) {
375        mTabControl = tabControl;
376    }
377
378    /*
379     * Update all the observers of the object.
380     */
381    /*package*/ void update() {
382        setChanged();
383        notifyObservers();
384    }
385
386    /*package*/ void clearCache(Context context) {
387        WebIconDatabase.getInstance().removeAllIcons();
388        if (mTabControl != null) {
389            mTabControl.getCurrentWebView().clearCache(true);
390        }
391    }
392
393    /*package*/ void clearCookies(Context context) {
394        CookieManager.getInstance().removeAllCookie();
395    }
396
397    /* package */void clearHistory(Context context) {
398        ContentResolver resolver = context.getContentResolver();
399        Browser.clearHistory(resolver);
400        Browser.clearSearches(resolver);
401        // Delete back-forward list
402        if (mTabControl != null) {
403            mTabControl.clearHistory();
404        }
405    }
406
407    /* package */ void clearFormData(Context context) {
408        WebViewDatabase.getInstance(context).clearFormData();
409        if (mTabControl != null) {
410            mTabControl.getCurrentTopWebView().clearFormData();
411        }
412    }
413
414    /*package*/ void clearPasswords(Context context) {
415        WebViewDatabase db = WebViewDatabase.getInstance(context);
416        db.clearUsernamePassword();
417        db.clearHttpAuthUsernamePassword();
418    }
419
420    /*package*/ void resetDefaultPreferences(Context context) {
421        SharedPreferences p =
422            PreferenceManager.getDefaultSharedPreferences(context);
423        p.edit().clear().commit();
424        PreferenceManager.setDefaultValues(context, R.xml.browser_preferences,
425                true);
426    }
427
428    // Private constructor that does nothing.
429    private BrowserSettings() {
430    }
431}
432