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