OSDN Git Service

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