<w>orbot</w>
<w>panopticlick</w>
<w>redmine</w>
+ <w>referer</w>
<w>relativelayout</w>
<w>robinlinus</w>
<w>samsung</w>
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:23.4.0'
// Only compile com.google.android.gms:play-services-ads for the free version.
- freeCompile 'com.google.android.gms:play-services-ads:9.0.2'
+ freeCompile 'com.google.android.gms:play-services-ads:9.2.0'
}
the ads is loaded from the third-party broker's server instead of the main server.</p>
<p>Because most of the advertisements on the internet are displayed from only a few brokers, it didn't take long for them to realize
- that they could set a tracking cookie on the user's device and know every place that user goes. Every time an ad loads from a broker,
- the first thing it does it check to see if if the device already has a unique serial number in a tracking cookie. If it does, it looks up
- the profile for that serial number and makes a note of the new site. This is why a user can do a search on one website for a
+ that they could set a tracking cookie on the user's device and know every place that user goes. Every time an ad loads from a broker,
+ the first thing it does it check to see if if the device already has a unique serial number in a tracking cookie. If it does, it looks up
+ the profile for that serial number and makes a note of the new site. This is why a user can do a search on one website for a
product that they typically don't look for, like walnuts, and then suddenly start seeing advertisements for walnuts on every
website they visit.</p>
-<p>In addition to ad brokers, social media sites discovered they could get in on the action. A few years ago, the major social media sites
+<p>In addition to ad brokers, social media sites discovered they could get in on the action. A few years ago, the major social media sites
like Facebook and Twitter convinced a large number of websites that it would be in there best interest to place little social media
- icons on their pages. These are not just images. They contain <a href="https://developers.facebook.com/docs/plugins/like-button/">imbedded code</a> that
+ icons on their pages. These are not just images. They contain <a href="https://developers.facebook.com/docs/plugins/like-button/">imbedded code</a> that
links back to the social media site, and, among other things, loads a third-party cookie on the device. These cookies are placed even if the user does
not have an account with the social media platform. Over time, companies like Facebook (which also run an ad network) have built up quite a large number
of detailed profiles about people who have <a href="http://www.theverge.com/2016/5/27/11795248/facebook-ad-network-non-users-cookies-plug-ins">never even
<h3>DOM Storage</h3>
-<p>Document Object Model storage, also known as web storage, is like cookies on steroids. Whereas the maximum combined storage size for all cookies from
+<p>Document Object Model storage, also known as web storage, is like cookies on steroids. Whereas the maximum combined storage size for all cookies from
a single URL is 4 kilobytes, DOM storage can hold between <a href="https://en.wikipedia.org/wiki/Web_storage#Storage_size">5-25 megabytes per site</a>.
Because DOM storage uses JavaScript to read and write data, enabling it will do nothing unless JavaScript is also enabled.</p>
+
+
+<h3>Form Data</h3>
+
+<p>Form data contains information typed into web forms, like user names, addresses, phone numbers, etc., and lists them in a drop-down box on future visits.
+ Unlike the other forms of local storage, form data is not sent to the web server without specific user interaction.</p>
</body>
</html>
\ No newline at end of file
<h3>WebView Limitations</h3>
-<p>Privacy Browser uses Android's built-in WebView to render websites. There are some limitations in the controls WebView exposes for managing privacy settings.
+<p>Privacy Browser uses Android's built-in WebView to render websites. There are some limitations in the controls WebView exposes for managing privacy settings. For example,
+ it isn't possible to enable some JavaScript commands while disabling others. It also isn't possible to control the
+ <a href="https://blog.fastmail.com/2016/06/20/everything-you-could-ever-want-to-know-and-more-about-controlling-the-referer-header/">referer header</a>.
Once Privacy Browser has matured to take full advantage of all the privacy options WebView does offer, some consideration might be made to imbedding a customized WebView
or using a different rendering engine.</p>
</body>
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
+import android.webkit.WebViewDatabase;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
public static boolean thirdPartyCookiesEnabled;
// domStorageEnabled is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onCreateOptionsMenu(), and onOptionsItemSelected().
public static boolean domStorageEnabled;
+ // saveFormDataEnabled is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onCreateOptionsMenu(), and onOptionsItemSelected().
+ public static boolean saveFormDataEnabled;
// javaScriptDisabledSearchURL is public static so it can be accessed from SettingsFragment. It is also used in onCreate() and loadURLFromTextBox().
public static String javaScriptDisabledSearchURL;
// javaScriptEnabledSearchURL is public static so it can be accessed from SettingsFragment. It is also used in onCreate() and loadURLFromTextBox().
domStorageEnabled = savedPreferences.getBoolean("dom_storage_enabled", false);
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
+ // Set the saved form data initial status. The default is false.
+ saveFormDataEnabled = savedPreferences.getBoolean("save_form_data_enabled", false);
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+
// Set the user agent initial status.
String userAgentString = savedPreferences.getString("user_agent", "Default user agent");
switch (userAgentString) {
MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies);
MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+ MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData);
// Set the initial status of the privacy icon.
updatePrivacyIcon();
toggleFirstPartyCookies.setChecked(firstPartyCookiesEnabled);
toggleThirdPartyCookies.setChecked(thirdPartyCookiesEnabled);
toggleDomStorage.setChecked(domStorageEnabled);
+ toggleSaveFormData.setChecked(saveFormDataEnabled);
return true;
}
toggleThirdPartyCookies.setEnabled(false);
}
+ // Enable DOM Storage if JavaScript is enabled.
+ MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+ toggleDomStorage.setEnabled(javaScriptEnabled);
+
// Enable Clear Cookies if there are any.
MenuItem clearCookies = menu.findItem(R.id.clearCookies);
clearCookies.setEnabled(cookieManager.hasCookies());
- // Enable DOM Storage if JavaScript is enabled.
- MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
- toggleDomStorage.setEnabled(javaScriptEnabled);
+ // Enable Clear Form Data is there is any.
+ MenuItem clearFormData = menu.findItem(R.id.clearFormData);
+ WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
+ clearFormData.setEnabled(mainWebViewDatabase.hasFormData());
// Run all the other default commands.
super.onPrepareOptionsMenu(menu);
mainWebView.reload();
return true;
+ case R.id.toggleSaveFormData:
+ // Switch the status of saveFormDataEnabled.
+ saveFormDataEnabled = !saveFormDataEnabled;
+
+ // Update the menu checkbox.
+ menuItem.setChecked(saveFormDataEnabled);
+
+ // Apply the new form data status.
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+
+ // Reload the WebView.
+ mainWebView.reload();
+ return true;
+
case R.id.clearCookies:
if (Build.VERSION.SDK_INT < 21) {
cookieManager.removeAllCookie();
Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show();
return true;
+ case R.id.clearFormData:
+ WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
+ mainWebViewDatabase.clearFormData();
+ mainWebView.reload();
+ return true;
+
case R.id.share:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
updatePrivacyIcon();
break;
+ case "save_form_data_enabled":
+ // Set saveFormDataEnabled to the new state. The default is false.
+ MainWebViewActivity.saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
+
+ // Update the checkbox in the options menu.
+ MenuItem saveFormDataMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleSaveFormData);
+ saveFormDataMenuItem.setChecked(MainWebViewActivity.saveFormDataEnabled);
+
+ // Update mainWebView and reload the website.
+ MainWebViewActivity.mainWebView.getSettings().setSaveFormData(MainWebViewActivity.saveFormDataEnabled);
+ MainWebViewActivity.mainWebView.reload();
+ break;
+
case "user_agent":
String userAgentString = sharedPreferences.getString("user_agent", "Default user agent");
android:checkable="true"
app:showAsAction="never" />
+ <item
+ android:id="@+id/toggleSaveFormData"
+ android:title="@string/form_data"
+ android:orderInCategory="50"
+ android:checkable="true"
+ app:showAsAction="never" />
+
<item
android:id="@+id/clearCookies"
android:title="@string/clear_cookies"
- android:orderInCategory="50"
+ android:orderInCategory="60"
app:showAsAction="never" />
<item
android:id="@+id/clearDomStorage"
android:title="@string/clear_dom_storage"
- android:orderInCategory="60"
+ android:orderInCategory="70"
+ app:showAsAction="never" />
+
+ <item
+ android:id="@+id/clearFormData"
+ android:title="@string/clear_form_data"
+ android:orderInCategory="80"
app:showAsAction="never" />
<item
android:id="@+id/share"
android:title="@string/share"
- android:orderInCategory="70"
+ android:orderInCategory="90"
app:showAsAction="never" />
<item
android:id="@+id/addToHomescreen"
android:title="@string/add_to_home_screen"
- android:orderInCategory="80"
+ android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="@+id/refresh"
android:title="@string/refresh"
- android:orderInCategory="90"
+ android:orderInCategory="110"
app:showAsAction="never" />
</menu>
<string name="first_party_cookies">First-Party Cookies</string>
<string name="third_party_cookies">Third-Party Cookies</string>
<string name="dom_storage">DOM Storage</string>
+ <string name="form_data">Form Data</string>
<string name="clear_cookies">Clear Cookies</string>
<string name="clear_dom_storage">Clear DOM Storage</string>
+ <string name="clear_form_data">Clear Form Data</string>
<string name="share">Share</string>
<string name="add_to_home_screen">Add to Home Screen</string>
<string name="refresh">Refresh</string>
<string name="third_party_cookies_summary">This setting requires Android Lollipop (version 5.0) or higher. It has no effect if first-party cookies are disabled.</string>
<string name="dom_storage_preference">Enable DOM storage by default</string>
<string name="dom_storage_preference_summary">JavaScript must be enabled for DOM storage to function.</string>
+ <string name="save_form_data_preference">Enable saving of form data by default</string>
+ <string name="save_form_data_preference_summary">Saved form data can auto-populate fields on websites.</string>
<string name="user_agent">User agent</string>
<string-array name="user_agent_entries">
<item>WebView Default</item>
android:summary="@string/dom_storage_preference_summary"
android:defaultValue="false" />
+ <SwitchPreference
+ android:key="save_form_data_enabled"
+ android:title="@string/save_form_data_preference"
+ android:summary="@string/save_form_data_preference_summary"
+ android:defaultValue="false" />
+
<ListPreference
android:key="user_agent"
android:title="@string/user_agent"