summaryrefslogtreecommitdiff
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/browser/BrowserSettings.java169
-rw-r--r--src/com/android/browser/Controller.java22
-rw-r--r--src/com/android/browser/PreferenceKeys.java2
-rw-r--r--src/com/android/browser/UiController.java2
-rw-r--r--src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java26
5 files changed, 221 insertions, 0 deletions
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 24cc0766..fe916564 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -51,6 +51,14 @@ import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.WeakHashMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Arrays;
+
+import android.util.Log;
+import android.net.WebAddress;
+import android.widget.Toast;
/**
* Class for managing settings
@@ -58,6 +66,8 @@ import java.util.WeakHashMap;
public class BrowserSettings implements OnSharedPreferenceChangeListener,
PreferenceKeys {
+ private final static String TAG = "BrowserSettings";
+
// TODO: Do something with this UserAgent stuff
private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
"Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " +
@@ -502,6 +512,151 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener,
}
}
+ private Set<String> getCookieWhitelist() {
+ requireInitialization();
+ return mPrefs.getStringSet("cookies_whitelist", new HashSet<String>());
+ }
+
+ private void setCookieWhitelist(Set<String> wl) {
+ mPrefs.edit().putStringSet("cookies_whitelist", wl).apply();
+ }
+
+ private boolean addToCookieWhitelist(String s) {
+ Set<String> wl = getCookieWhitelist();
+ boolean ok = wl.add(s);
+ setCookieWhitelist(wl);
+ return ok;
+ }
+
+ private boolean removeFromCookieWhitelist(String s) {
+ Set<String> wl = getCookieWhitelist();
+ boolean ok = wl.remove(s);
+ setCookieWhitelist(wl);
+ return ok;
+ }
+
+ public boolean hasCookiesWhitelisted(WebView view) {
+ if (view == null) {
+ return false;
+ }
+ String url = view.getUrl();
+ if (url == null) { // page hasn't finished loading yet
+ return false;
+ }
+ String host = new WebAddress(url).getHost();
+ Set<String> wl = getCookieWhitelist();
+ return wl.contains(host);
+ }
+
+ public void toggleCookiesWhitelisted(WebView view) {
+ if (view == null) {
+ return;
+ }
+ if (!enableDeleteCookies()) {
+ return;
+ }
+
+ String url = view.getUrl();
+ if (url == null) { // page hasn't finished loading yet
+ return;
+ }
+ String host = new WebAddress(url).getHost();
+ if (hasCookiesWhitelisted(view)) {
+ removeFromCookieWhitelist(host);
+ clearCookiesExceptWhitelist();
+ }
+ else {
+ addToCookieWhitelist(host);
+ }
+ }
+
+ public void clearCookiesExceptWhitelist() {
+ if (!enableDeleteCookies()) {
+ return;
+ }
+
+ Set<String> domains = getCookieWhitelist();
+ HashMap cookies = new HashMap();
+
+ // look for both domain and host cookies (domain cookies have a '.' prefix).
+ // query by https as this returns both http and https cookies.
+ String[] prefixes = { "https://.", "https://" };
+
+ // find all cookies in the whitelist
+ int savedCookies = 0;
+ for (String domain : domains) {
+ for (int p = 0; p < 2; p++) {
+ String url = prefixes[p] + domain;
+ String c = CookieManager.getInstance().getCookie(url);
+ if (c != null && !(c.equals("") || c.equals(null))) {
+ String[] cc = c.split(";"); // split into individual cookies
+ for (int i = 0; i < cc.length; i++) // get rid of leading blanks
+ cc[i] = cc[i].trim();
+ Set<String> ccUniq = new HashSet<String>(Arrays.asList(cc));
+ if (p == 1) { // remove domain cookies duplicated to the host
+ String urlDom = prefixes[0] + domain;
+ if (cookies.containsKey(urlDom)) {
+ Set<String> ccDom = (HashSet<String>)cookies.get(urlDom);
+ ccUniq.removeAll(ccDom);
+ }
+ }
+ savedCookies += ccUniq.size();
+ cookies.put(url, ccUniq);
+ }
+ }
+ }
+
+ int cookiesBefore = CookieManager.getInstance().countCookies();
+ if (savedCookies == cookiesBefore) {
+ // all cookies are whitelisted cookies. our job is done.
+ return;
+ }
+
+ // delete all cookies
+ CookieManager.getInstance().removeAllCookie();
+
+ // re-add all the whitelisted cookies
+ for (String domain : domains) {
+ for (String prefix : prefixes) {
+ String url = prefix + domain;
+ if (cookies.containsKey(url)) {
+ Set<String> cc = (HashSet<String>)cookies.get(url);
+ for (String i : cc) {
+ CookieManager.getInstance().setCookie(url, i + ";");
+ }
+ }
+ }
+ }
+
+ int cookiesAfter = CookieManager.getInstance().countCookies();
+ int cookiesDeleted = cookiesBefore - cookiesAfter;
+ boolean munched = cookiesDeleted > 0;
+
+ if (!munched) { // no cookies were deleted
+ return;
+ }
+
+ // optionally clear all localstorage too
+ if (enableDeleteLocaldata()) {
+ clearDatabases();
+ }
+
+ Log.d(TAG, "clearCookiesExceptWhitelist: "
+ + cookiesDeleted + " cookies deleted, "
+ + cookiesAfter + " cookies remain");
+
+ // toast if we have munched cookies
+ if (munchToast()) {
+ String deleted_str = mContext.getResources()
+ .getString(R.string.cookies_deleted_info);
+ String remain_str = mContext.getResources()
+ .getString(R.string.cookies_remain_info);
+ CharSequence text = "" + cookiesDeleted + " " + deleted_str
+ + "\n" + cookiesAfter + " " + remain_str;
+ Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
+ }
+ }
+
public static int getAdjustedMinimumFontSize(int rawValue) {
rawValue++; // Preference starts at 0, min font at 1
if (rawValue > 1) {
@@ -809,6 +964,20 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener,
return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
}
+ public boolean enableDeleteCookies() {
+ int value = Integer.valueOf(mPrefs.getString(PREF_SITE_WHITELIST_COOKIES, "0"));
+ return value != 0;
+ }
+
+ public boolean enableDeleteLocaldata() {
+ int value = Integer.valueOf(mPrefs.getString(PREF_SITE_WHITELIST_COOKIES, "0"));
+ return value == 2;
+ }
+
+ public boolean munchToast() {
+ return mPrefs.getBoolean(PREF_SITE_WHITELIST_COOKIES_VERBOSE, false);
+ }
+
public boolean saveFormdata() {
return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 2d716a8d..f01f58e8 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -688,6 +688,11 @@ public class Controller
return;
}
mSettings.setLastRunPaused(false);
+
+ // delete cookies (and localstorage) early in the resume to
+ // avoid potential races with regular cookie reads and writes.
+ mSettings.clearCookiesExceptWhitelist();
+
mActivityPaused = false;
Tab current = mTabControl.getCurrentTab();
if (current != null) {
@@ -1483,12 +1488,14 @@ public class Controller
boolean canGoForward = false;
boolean isHome = false;
boolean isDesktopUa = false;
+ boolean hasCookiesWhitelisted = false;
boolean isLive = false;
if (tab != null) {
canGoBack = tab.canGoBack();
canGoForward = tab.canGoForward();
isHome = mSettings.getHomePage().equals(tab.getUrl());
isDesktopUa = mSettings.hasDesktopUseragent(tab.getWebView());
+ hasCookiesWhitelisted = mSettings.hasCookiesWhitelisted(tab.getWebView());
isLive = !tab.isSnapshot();
}
final MenuItem back = menu.findItem(R.id.back_menu_id);
@@ -1529,6 +1536,11 @@ public class Controller
menu.setGroupVisible(R.id.SNAPSHOT_MENU, !isLive);
menu.setGroupVisible(R.id.COMBO_MENU, false);
+ // individual Visible needs to be after the group setting
+ final MenuItem cwSwitcher = menu.findItem(R.id.cookies_whitelisted_menu_id);
+ cwSwitcher.setChecked(hasCookiesWhitelisted);
+ cwSwitcher.setVisible(isLive && mSettings.enableDeleteCookies());
+
mUi.updateMenuState(tab, menu);
}
@@ -1656,6 +1668,10 @@ public class Controller
toggleUserAgent();
break;
+ case R.id.cookies_whitelisted_menu_id:
+ toggleCookiesWhitelisted();
+ break;
+
case R.id.window_one_menu_id:
case R.id.window_two_menu_id:
case R.id.window_three_menu_id:
@@ -1693,6 +1709,12 @@ public class Controller
}
@Override
+ public void toggleCookiesWhitelisted() {
+ WebView web = getCurrentWebView();
+ mSettings.toggleCookiesWhitelisted(web);
+ }
+
+ @Override
public void findOnPage() {
getCurrentTopWebView().showFindDialog(null, true);
}
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
index 18280327..8b6d95ca 100644
--- a/src/com/android/browser/PreferenceKeys.java
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -88,6 +88,8 @@ public interface PreferenceKeys {
// Keys for privacy_security_preferences.xml
// ----------------------
static final String PREF_ACCEPT_COOKIES = "accept_cookies";
+ static final String PREF_SITE_WHITELIST_COOKIES = "site_whitelist_cookies";
+ static final String PREF_SITE_WHITELIST_COOKIES_VERBOSE = "site_whitelist_cookies_verbose";
static final String PREF_ENABLE_GEOLOCATION = "enable_geolocation";
static final String PREF_PRIVACY_CLEAR_CACHE = "privacy_clear_cache";
static final String PREF_PRIVACY_CLEAR_COOKIES = "privacy_clear_cookies";
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index f00f1a23..53830d5a 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -105,6 +105,8 @@ public interface UiController {
void toggleUserAgent();
+ void toggleCookiesWhitelisted();
+
BrowserSettings getSettings();
boolean supportsVoice();
diff --git a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
index 35e6e432..24301cb7 100644
--- a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
@@ -23,6 +23,7 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
+import android.preference.ListPreference;
import android.preference.PreferenceFragment;
public class PrivacySecurityPreferencesFragment extends PreferenceFragment
@@ -37,6 +38,24 @@ public class PrivacySecurityPreferencesFragment extends PreferenceFragment
Preference e = findPreference(PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY);
e.setOnPreferenceChangeListener(this);
+
+ ListPreference lp = (ListPreference) findPreference(PreferenceKeys.PREF_SITE_WHITELIST_COOKIES);
+ lp.setOnPreferenceChangeListener(this);
+ updateListPreferenceSummary(lp);
+ cookiesVerboseEnable(lp.getValue());
+ }
+
+ private void cookiesVerboseEnable(String str) {
+ // if never, disable verbose option
+ int value = Integer.valueOf(str);
+ Preference pref = findPreference(PreferenceKeys.PREF_SITE_WHITELIST_COOKIES_VERBOSE);
+ if (pref != null) {
+ pref.setEnabled(value != 0);
+ }
+ }
+
+ void updateListPreferenceSummary(ListPreference e) {
+ e.setSummary(e.getEntry());
}
@Override
@@ -54,6 +73,13 @@ public class PrivacySecurityPreferencesFragment extends PreferenceFragment
pref.getKey()));
return true;
}
+ else if (pref.getKey().equals(PreferenceKeys.PREF_SITE_WHITELIST_COOKIES)) {
+ ListPreference lp = (ListPreference) pref;
+ lp.setValue((String) objValue);
+ updateListPreferenceSummary(lp);
+ cookiesVerboseEnable((String) objValue);
+ return false;
+ }
return false;
}