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