/WebVox/src/com/marvin/webvox/BrowserSettings.java

http://eyes-free.googlecode.com/ · Java · 587 lines · 372 code · 70 blank · 145 comment · 32 complexity · effdbc0b2dd2213ca1e7a5a2f6b7cb8b MD5 · raw file

  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. package com.marvin.webvox;
  17. import com.marvin.webvox.R;
  18. //import com.google.android.providers.GoogleSettings.Partner;
  19. import android.content.ContentResolver;
  20. import android.content.Context;
  21. import android.content.pm.ActivityInfo;
  22. import android.content.SharedPreferences;
  23. import android.content.SharedPreferences.Editor;
  24. import android.preference.PreferenceActivity;
  25. import android.preference.PreferenceScreen;
  26. import android.webkit.CookieManager;
  27. import android.webkit.GeolocationPermissions;
  28. //import android.webkit.ValueCallback;
  29. import android.webkit.WebView;
  30. import android.webkit.WebViewDatabase;
  31. import android.webkit.WebIconDatabase;
  32. import android.webkit.WebSettings;
  33. import android.webkit.WebStorage;
  34. import android.preference.PreferenceManager;
  35. import android.provider.Browser;
  36. import java.util.HashMap;
  37. import java.util.Map;
  38. import java.util.Set;
  39. import java.util.Observable;
  40. /*
  41. * Package level class for storing various WebView and Browser settings. To use
  42. * this class:
  43. * BrowserSettings s = BrowserSettings.getInstance();
  44. * s.addObserver(webView.getSettings());
  45. * s.loadFromDb(context); // Only needed on app startup
  46. * s.javaScriptEnabled = true;
  47. * ... // set any other settings
  48. * s.update(); // this will update all the observers
  49. *
  50. * To remove an observer:
  51. * s.deleteObserver(webView.getSettings());
  52. */
  53. class BrowserSettings extends Observable {
  54. // Private variables for settings
  55. // NOTE: these defaults need to be kept in sync with the XML
  56. // until the performance of PreferenceManager.setDefaultValues()
  57. // is improved.
  58. private boolean loadsImagesAutomatically = true;
  59. private boolean javaScriptEnabled = true;
  60. private boolean pluginsEnabled = true;
  61. private boolean javaScriptCanOpenWindowsAutomatically = false;
  62. private boolean showSecurityWarnings = true;
  63. private boolean rememberPasswords = true;
  64. private boolean saveFormData = true;
  65. private boolean openInBackground = false;
  66. private String defaultTextEncodingName;
  67. private String homeUrl = "";
  68. private boolean loginInitialized = false;
  69. private boolean autoFitPage = true;
  70. private boolean landscapeOnly = false;
  71. private boolean loadsPageInOverviewMode = true;
  72. private boolean showDebugSettings = false;
  73. // HTML5 API flags
  74. private boolean appCacheEnabled = true;
  75. private boolean databaseEnabled = true;
  76. private boolean domStorageEnabled = true;
  77. private boolean geolocationEnabled = true;
  78. private boolean workersEnabled = true; // only affects V8. JSC does not have a similar setting
  79. // HTML5 API configuration params
  80. private long appCacheMaxSize = Long.MAX_VALUE;
  81. private String appCachePath; // default value set in loadFromDb().
  82. private String databasePath; // default value set in loadFromDb()
  83. private String geolocationDatabasePath; // default value set in loadFromDb()
  84. private WebStorageSizeManager webStorageSizeManager;
  85. private String jsFlags = "";
  86. private final static String TAG = "BrowserSettings";
  87. // Development settings
  88. public WebSettings.LayoutAlgorithm layoutAlgorithm =
  89. WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
  90. private boolean useWideViewPort = true;
  91. private int userAgent = 0;
  92. private boolean tracing = false;
  93. private boolean lightTouch = false;
  94. private boolean navDump = false;
  95. // By default the error console is shown once the user navigates to about:debug.
  96. // The setting can be then toggled from the settings menu.
  97. private boolean showConsole = true;
  98. // Browser only settings
  99. private boolean doFlick = false;
  100. // Private preconfigured values
  101. private static int minimumFontSize = 8;
  102. private static int minimumLogicalFontSize = 8;
  103. private static int defaultFontSize = 16;
  104. private static int defaultFixedFontSize = 13;
  105. private static WebSettings.TextSize textSize =
  106. WebSettings.TextSize.NORMAL;
  107. // private static WebSettings.ZoomDensity zoomDensity =
  108. // WebSettings.ZoomDensity.MEDIUM;
  109. // Preference keys that are used outside this class
  110. public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
  111. public final static String PREF_CLEAR_COOKIES = "privacy_clear_cookies";
  112. public final static String PREF_CLEAR_HISTORY = "privacy_clear_history";
  113. public final static String PREF_HOMEPAGE = "homepage";
  114. public final static String PREF_CLEAR_FORM_DATA =
  115. "privacy_clear_form_data";
  116. public final static String PREF_CLEAR_PASSWORDS =
  117. "privacy_clear_passwords";
  118. public final static String PREF_EXTRAS_RESET_DEFAULTS =
  119. "reset_default_preferences";
  120. public final static String PREF_DEBUG_SETTINGS = "debug_menu";
  121. public final static String PREF_WEBSITE_SETTINGS = "website_settings";
  122. public final static String PREF_TEXT_SIZE = "text_size";
  123. public final static String PREF_DEFAULT_ZOOM = "default_zoom";
  124. public final static String PREF_DEFAULT_TEXT_ENCODING =
  125. "default_text_encoding";
  126. public final static String PREF_CLEAR_GEOLOCATION_ACCESS =
  127. "privacy_clear_geolocation_access";
  128. private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; " +
  129. "U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.17 (KHTML, " +
  130. "like Gecko) Version/4.0 Safari/530.17";
  131. private static final String IPHONE_USERAGENT = "Mozilla/5.0 (iPhone; U; " +
  132. "CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 " +
  133. "(KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16";
  134. // Value to truncate strings when adding them to a TextView within
  135. // a ListView
  136. public final static int MAX_TEXTVIEW_LEN = 80;
  137. private TabControl mTabControl;
  138. // Single instance of the BrowserSettings for use in the Browser app.
  139. private static BrowserSettings sSingleton;
  140. // Private map of WebSettings to Observer objects used when deleting an
  141. // observer.
  142. private HashMap<WebSettings,Observer> mWebSettingsToObservers =
  143. new HashMap<WebSettings,Observer>();
  144. /*
  145. * An observer wrapper for updating a WebSettings object with the new
  146. * settings after a call to BrowserSettings.update().
  147. */
  148. static class Observer implements java.util.Observer {
  149. // Private WebSettings object that will be updated.
  150. private WebSettings mSettings;
  151. Observer(WebSettings w) {
  152. mSettings = w;
  153. }
  154. public void update(Observable o, Object arg) {
  155. BrowserSettings b = (BrowserSettings)o;
  156. WebSettings s = mSettings;
  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.setJavaScriptCanOpenWindowsAutomatically(
  171. b.javaScriptCanOpenWindowsAutomatically);
  172. s.setDefaultTextEncodingName(b.defaultTextEncodingName);
  173. s.setMinimumFontSize(b.minimumFontSize);
  174. s.setMinimumLogicalFontSize(b.minimumLogicalFontSize);
  175. s.setDefaultFontSize(b.defaultFontSize);
  176. s.setDefaultFixedFontSize(b.defaultFixedFontSize);
  177. s.setNavDump(b.navDump);
  178. s.setTextSize(b.textSize);
  179. // s.setDefaultZoom(b.zoomDensity);
  180. s.setLightTouchEnabled(b.lightTouch);
  181. s.setSaveFormData(b.saveFormData);
  182. s.setSavePassword(b.rememberPasswords);
  183. // s.setLoadWithOverviewMode(b.loadsPageInOverviewMode);
  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. // HTML5 API flags
  189. // s.setAppCacheEnabled(b.appCacheEnabled);
  190. s.setDatabaseEnabled(b.databaseEnabled);
  191. // s.setDomStorageEnabled(b.domStorageEnabled);
  192. // s.setWorkersEnabled(b.workersEnabled); // This only affects V8.
  193. s.setGeolocationEnabled(b.geolocationEnabled);
  194. // HTML5 configuration parameters.
  195. // s.setAppCacheMaxSize(b.appCacheMaxSize);
  196. // s.setAppCachePath(b.appCachePath);
  197. s.setDatabasePath(b.databasePath);
  198. s.setGeolocationDatabasePath(b.geolocationDatabasePath);
  199. // Enable/Disable the error console.
  200. b.mTabControl.getBrowserActivity().setShouldShowErrorConsole(
  201. b.showDebugSettings && b.showConsole);
  202. }
  203. }
  204. /**
  205. * Load settings from the browser app's database.
  206. * NOTE: Strings used for the preferences must match those specified
  207. * in the browser_preferences.xml
  208. * @param ctx A Context object used to query the browser's settings
  209. * database. If the database exists, the saved settings will be
  210. * stored in this BrowserSettings object. This will update all
  211. * observers of this object.
  212. */
  213. public void loadFromDb(Context ctx) {
  214. SharedPreferences p =
  215. PreferenceManager.getDefaultSharedPreferences(ctx);
  216. // Set the default value for the Application Caches path.
  217. appCachePath = ctx.getDir("appcache", 0).getPath();
  218. // Determine the maximum size of the application cache.
  219. webStorageSizeManager = new WebStorageSizeManager(
  220. ctx,
  221. new WebStorageSizeManager.StatFsDiskInfo(appCachePath),
  222. new WebStorageSizeManager.WebKitAppCacheInfo(appCachePath));
  223. appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
  224. // Set the default value for the Database path.
  225. databasePath = ctx.getDir("databases", 0).getPath();
  226. // Set the default value for the Geolocation database path.
  227. geolocationDatabasePath = ctx.getDir("geolocation", 0).getPath();
  228. homeUrl = getFactoryResetHomeUrl(ctx);
  229. // Load the defaults from the xml
  230. // This call is TOO SLOW, need to manually keep the defaults
  231. // in sync
  232. //PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences);
  233. syncSharedPreferences(p);
  234. }
  235. /* package */ void syncSharedPreferences(SharedPreferences p) {
  236. homeUrl =
  237. p.getString(PREF_HOMEPAGE, homeUrl);
  238. loadsImagesAutomatically = p.getBoolean("load_images",
  239. loadsImagesAutomatically);
  240. javaScriptEnabled = p.getBoolean("enable_javascript",
  241. javaScriptEnabled);
  242. pluginsEnabled = p.getBoolean("enable_plugins",
  243. pluginsEnabled);
  244. javaScriptCanOpenWindowsAutomatically = !p.getBoolean(
  245. "block_popup_windows",
  246. !javaScriptCanOpenWindowsAutomatically);
  247. showSecurityWarnings = p.getBoolean("show_security_warnings",
  248. showSecurityWarnings);
  249. rememberPasswords = p.getBoolean("remember_passwords",
  250. rememberPasswords);
  251. saveFormData = p.getBoolean("save_formdata",
  252. saveFormData);
  253. boolean accept_cookies = p.getBoolean("accept_cookies",
  254. CookieManager.getInstance().acceptCookie());
  255. CookieManager.getInstance().setAcceptCookie(accept_cookies);
  256. openInBackground = p.getBoolean("open_in_background", openInBackground);
  257. loginInitialized = p.getBoolean("login_initialized", loginInitialized);
  258. textSize = WebSettings.TextSize.valueOf(
  259. p.getString(PREF_TEXT_SIZE, textSize.name()));
  260. // zoomDensity = WebSettings.ZoomDensity.valueOf(
  261. // p.getString(PREF_DEFAULT_ZOOM, zoomDensity.name()));
  262. autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
  263. loadsPageInOverviewMode = p.getBoolean("load_page",
  264. loadsPageInOverviewMode);
  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. showDebugSettings =
  283. p.getBoolean(PREF_DEBUG_SETTINGS, showDebugSettings);
  284. // Debug menu items have precidence if the menu is visible
  285. if (showDebugSettings) {
  286. boolean small_screen = p.getBoolean("small_screen",
  287. layoutAlgorithm ==
  288. WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
  289. if (small_screen) {
  290. layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN;
  291. } else {
  292. boolean normal_layout = p.getBoolean("normal_layout",
  293. layoutAlgorithm == WebSettings.LayoutAlgorithm.NORMAL);
  294. if (normal_layout) {
  295. layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
  296. } else {
  297. layoutAlgorithm =
  298. WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
  299. }
  300. }
  301. useWideViewPort = p.getBoolean("wide_viewport", useWideViewPort);
  302. tracing = p.getBoolean("enable_tracing", tracing);
  303. lightTouch = p.getBoolean("enable_light_touch", lightTouch);
  304. navDump = p.getBoolean("enable_nav_dump", navDump);
  305. doFlick = p.getBoolean("enable_flick", doFlick);
  306. userAgent = Integer.parseInt(p.getString("user_agent", "0"));
  307. }
  308. // JS flags is loaded from DB even if showDebugSettings is false,
  309. // so that it can be set once and be effective all the time.
  310. jsFlags = p.getString("js_engine_flags", "");
  311. // Read the setting for showing/hiding the JS Console always so that should the
  312. // user enable debug settings, we already know if we should show the console.
  313. // The user will never see the console unless they navigate to about:debug,
  314. // regardless of the setting we read here. This setting is only used after debug
  315. // is enabled.
  316. showConsole = p.getBoolean("javascript_console", showConsole);
  317. mTabControl.getBrowserActivity().setShouldShowErrorConsole(
  318. showDebugSettings && showConsole);
  319. // HTML5 API flags
  320. appCacheEnabled = p.getBoolean("enable_appcache", appCacheEnabled);
  321. databaseEnabled = p.getBoolean("enable_database", databaseEnabled);
  322. domStorageEnabled = p.getBoolean("enable_domstorage", domStorageEnabled);
  323. geolocationEnabled = p.getBoolean("enable_geolocation", geolocationEnabled);
  324. workersEnabled = p.getBoolean("enable_workers", workersEnabled);
  325. update();
  326. }
  327. public String getHomePage() {
  328. return homeUrl;
  329. }
  330. public String getJsFlags() {
  331. return jsFlags;
  332. }
  333. public WebStorageSizeManager getWebStorageSizeManager() {
  334. return webStorageSizeManager;
  335. }
  336. public void setHomePage(Context context, String url) {
  337. Editor ed = PreferenceManager.
  338. getDefaultSharedPreferences(context).edit();
  339. ed.putString(PREF_HOMEPAGE, url);
  340. ed.commit();
  341. homeUrl = url;
  342. }
  343. public boolean isLoginInitialized() {
  344. return loginInitialized;
  345. }
  346. public void setLoginInitialized(Context context) {
  347. loginInitialized = true;
  348. Editor ed = PreferenceManager.
  349. getDefaultSharedPreferences(context).edit();
  350. ed.putBoolean("login_initialized", loginInitialized);
  351. ed.commit();
  352. }
  353. public WebSettings.TextSize getTextSize() {
  354. return textSize;
  355. }
  356. // public WebSettings.ZoomDensity getDefaultZoom() {
  357. // return zoomDensity;
  358. // }
  359. public boolean openInBackground() {
  360. return openInBackground;
  361. }
  362. public boolean showSecurityWarnings() {
  363. return showSecurityWarnings;
  364. }
  365. public boolean isTracing() {
  366. return tracing;
  367. }
  368. public boolean isLightTouch() {
  369. return lightTouch;
  370. }
  371. public boolean isNavDump() {
  372. return navDump;
  373. }
  374. public boolean doFlick() {
  375. return doFlick;
  376. }
  377. public boolean showDebugSettings() {
  378. return showDebugSettings;
  379. }
  380. public void toggleDebugSettings() {
  381. showDebugSettings = !showDebugSettings;
  382. navDump = showDebugSettings;
  383. update();
  384. }
  385. /**
  386. * Add a WebSettings object to the list of observers that will be updated
  387. * when update() is called.
  388. *
  389. * @param s A WebSettings object that is strictly tied to the life of a
  390. * WebView.
  391. */
  392. public Observer addObserver(WebSettings s) {
  393. Observer old = mWebSettingsToObservers.get(s);
  394. if (old != null) {
  395. super.deleteObserver(old);
  396. }
  397. Observer o = new Observer(s);
  398. mWebSettingsToObservers.put(s, o);
  399. super.addObserver(o);
  400. return o;
  401. }
  402. /**
  403. * Delete the given WebSettings observer from the list of observers.
  404. * @param s The WebSettings object to be deleted.
  405. */
  406. public void deleteObserver(WebSettings s) {
  407. Observer o = mWebSettingsToObservers.get(s);
  408. if (o != null) {
  409. mWebSettingsToObservers.remove(s);
  410. super.deleteObserver(o);
  411. }
  412. }
  413. /*
  414. * Package level method for obtaining a single app instance of the
  415. * BrowserSettings.
  416. */
  417. /*package*/ static BrowserSettings getInstance() {
  418. if (sSingleton == null ) {
  419. sSingleton = new BrowserSettings();
  420. }
  421. return sSingleton;
  422. }
  423. /*
  424. * Package level method for associating the BrowserSettings with TabControl
  425. */
  426. /* package */void setTabControl(TabControl tabControl) {
  427. mTabControl = tabControl;
  428. }
  429. /*
  430. * Update all the observers of the object.
  431. */
  432. /*package*/ void update() {
  433. setChanged();
  434. notifyObservers();
  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. /*package*/ void clearCookies(Context context) {
  446. CookieManager.getInstance().removeAllCookie();
  447. }
  448. /* package */void clearHistory(Context context) {
  449. ContentResolver resolver = context.getContentResolver();
  450. Browser.clearHistory(resolver);
  451. Browser.clearSearches(resolver);
  452. }
  453. /* package */ void clearFormData(Context context) {
  454. WebViewDatabase.getInstance(context).clearFormData();
  455. if (mTabControl != null) {
  456. mTabControl.getCurrentTopWebView().clearFormData();
  457. }
  458. }
  459. /*package*/ void clearPasswords(Context context) {
  460. WebViewDatabase db = WebViewDatabase.getInstance(context);
  461. db.clearUsernamePassword();
  462. db.clearHttpAuthUsernamePassword();
  463. }
  464. private void maybeDisableWebsiteSettings(Context context) {
  465. PreferenceActivity activity = (PreferenceActivity) context;
  466. final PreferenceScreen screen = (PreferenceScreen)
  467. activity.findPreference(BrowserSettings.PREF_WEBSITE_SETTINGS);
  468. screen.setEnabled(false);
  469. /*
  470. WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
  471. public void onReceiveValue(Map webStorageOrigins) {
  472. if ((webStorageOrigins != null) && !webStorageOrigins.isEmpty()) {
  473. screen.setEnabled(true);
  474. }
  475. }
  476. });
  477. GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set>() {
  478. public void onReceiveValue(Set geolocationOrigins) {
  479. if ((geolocationOrigins != null) && !geolocationOrigins.isEmpty()) {
  480. screen.setEnabled(true);
  481. }
  482. }
  483. });
  484. */
  485. }
  486. /*package*/ void clearDatabases(Context context) {
  487. // WebStorage.getInstance().deleteAllData();
  488. maybeDisableWebsiteSettings(context);
  489. }
  490. /*package*/ void clearLocationAccess(Context context) {
  491. // GeolocationPermissions.getInstance().clearAll();
  492. maybeDisableWebsiteSettings(context);
  493. }
  494. /*package*/ void resetDefaultPreferences(Context ctx) {
  495. SharedPreferences p =
  496. PreferenceManager.getDefaultSharedPreferences(ctx);
  497. p.edit().clear().commit();
  498. PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences,
  499. true);
  500. // reset homeUrl
  501. setHomePage(ctx, getFactoryResetHomeUrl(ctx));
  502. // reset appcache max size
  503. appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
  504. }
  505. private String getFactoryResetHomeUrl(Context context) {
  506. String url = context.getResources().getString(R.string.homepage_base);
  507. // if (url.indexOf("{CID}") != -1) {
  508. // url = url.replace("{CID}", Partner.getString(context
  509. // .getContentResolver(), Partner.CLIENT_ID, "android-google"));
  510. // }
  511. return url;
  512. }
  513. // Private constructor that does nothing.
  514. private BrowserSettings() {
  515. }
  516. }