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