BrowserSettings.java revision 9ac587d3247a2b6db6eab76359ababb7f60b918c
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 // The Browser always enables Application Caches. 78 private boolean appCacheEnabled = true; 79 private String appCachePath; // default value set in loadFromDb(). 80 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); 188 // Turn on Application Caches. 189 s.setAppCachePath(b.appCachePath); 190 s.setAppCacheEnabled(b.appCacheEnabled); 191 } 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(); 210 // Set the default value for the Application Caches path. 211 appCachePath = ctx.getDir("appcache", 0).getPath(); 212 213 homeUrl = DEFAULT_HOME_URL + 214 Partner.getString(ctx.getContentResolver(), Partner.CLIENT_ID); 215 216 // 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) { 224 225 homeUrl = 226 p.getString(PREF_HOMEPAGE, homeUrl); 227 228 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); 235 appCacheEnabled = p.getBoolean("enable_appcache", 236 appCacheEnabled); 237 appCachePath = p.getString("appcache_path", appCachePath); 238 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); 255 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 } 263 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 459 /*package*/ void resetDefaultPreferences(Context ctx) { 460 SharedPreferences p = 461 PreferenceManager.getDefaultSharedPreferences(ctx); 462 p.edit().clear().commit(); 463 PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences, 464 true); 465 setHomePage(ctx, DEFAULT_HOME_URL + 466 Partner.getString(ctx.getContentResolver(), Partner.CLIENT_ID)); 467 } 468 469 // Private constructor that does nothing. 470 private BrowserSettings() { 471 } 472} 473