Add a DNT option and turn it on by default. Fixes https://redmine.stoutner.com/issues/30
authorSoren Stoutner <soren@stoutner.com>
Tue, 6 Sep 2016 02:30:31 +0000 (19:30 -0700)
committerSoren Stoutner <soren@stoutner.com>
Tue, 6 Sep 2016 02:30:31 +0000 (19:30 -0700)
13 files changed:
app/src/main/assets/de/guide_local_storage.html
app/src/main/assets/de/images/cookie_dark_blue.png [new symlink]
app/src/main/assets/de/images/ic_subtitles_dark_blue.png [new symlink]
app/src/main/assets/de/images/ic_web_dark_blue.png [new symlink]
app/src/main/assets/en/guide_local_storage.html
app/src/main/assets/en/guide_tracking_ids.html
app/src/main/assets/en/images/cookie_dark_blue.png [new file with mode: 0644]
app/src/main/assets/en/images/ic_subtitles_dark_blue.png [new file with mode: 0644]
app/src/main/assets/en/images/ic_web_dark_blue.png [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/SettingsFragment.java
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences.xml

index 8aea57346eef6389d4568b5e10c306cc4a55d1a1..d3c2a84b168ddbc4c96fd057ca05c97e19a5062a 100644 (file)
         h3 {
         color: 0D4781;
         }
+
+        img {
+            vertical-align: bottom;
+            height: 32;
+            width: 32;
+        }
     </style>
 </head>
 
 <body>
-<h3>Erstanbieter-Cookies</h3>
+<h3><img src="images/cookie_dark_blue.png">Erstanbieter-Cookies</h3>
 
 <p>Cookies k&ouml;nnen in zwei Typen unterteilt werden. Erstanbieter-Cookies sind Cookies, die von aktuell besuchten Website gesetzt werden.</p>
 
@@ -54,7 +60,7 @@
     als Warnung.</p>
 
 
-<h3>Drittanbieter-Cookies</h3>
+<h3><img src="images/cookie_dark_blue.png">Drittanbieter-Cookies</h3>
 
 <p>Drittanbieter-Cookies werden von Teilen einer Website gesetzt, die von einem anderen Server als dem aktuell besuchten.
     Beispielsweise laden viele Websites Werbungen von einem Drittanbieter-Broker wie Googles
     Deshalb aktiviert das Aktivieren von Erstanbieter-Cookies zugleich auch Drittanbieter-Cookies.</p>
 
 
-<h3>DOM-Speicher</h3>
+<h3><img src="images/ic_web_dark_blue.png">DOM-Speicher</h3>
 
 <p>Der Document Object Model-Speicher, auch bekannt als Web-Speicher, ist wie Cookies auf Steroiden. W&auml;hrend die maximale Gesamtspeichergr&szlig;e f&uuml;r alle Cookies von
     einer einzigen URL 4kb betr&auml;gt, kann der DOM-Speicher zwischen <a href="https://en.wikipedia.org/wiki/Web_storage#Storage_size">5-25 Megabytes pro Seite</a> betragen.
     Da der DOM-Speicher Javascript zum Lesen und Schreiben von Daten nutzt, &Atilde;&curren;ndert das Aktivieren also nichts, solange nicht auch Javascript aktiviert ist.</p>
 
 
-<h3>Formulardaten</h3>
+<h3><img src="images/ic_subtitles_dark_blue.png">Formulardaten</h3>
 
 <p>Formulardaten beinhalten die Informationen, die in Web-Formularen eingegeben werden, wie Benutzernamen, Adressen, Telefonnummern etc. und listet sie als Auswahlmen&uuml; auf k&uuml;nftig besuchten Websites auf.
     Ungleich der anderen Arten der lokalen Datenspeicherung werden Formulardaten nicht ohne die explizite Handlung des Nutzers an den Webserver gesendet.</p>
diff --git a/app/src/main/assets/de/images/cookie_dark_blue.png b/app/src/main/assets/de/images/cookie_dark_blue.png
new file mode 120000 (symlink)
index 0000000..d847369
--- /dev/null
@@ -0,0 +1 @@
+../../en/images/cookie_dark_blue.png
\ No newline at end of file
diff --git a/app/src/main/assets/de/images/ic_subtitles_dark_blue.png b/app/src/main/assets/de/images/ic_subtitles_dark_blue.png
new file mode 120000 (symlink)
index 0000000..6bccc98
--- /dev/null
@@ -0,0 +1 @@
+../../en/images/ic_subtitles_dark_blue.png
\ No newline at end of file
diff --git a/app/src/main/assets/de/images/ic_web_dark_blue.png b/app/src/main/assets/de/images/ic_web_dark_blue.png
new file mode 120000 (symlink)
index 0000000..ddc6eef
--- /dev/null
@@ -0,0 +1 @@
+../../en/images/ic_web_dark_blue.png
\ No newline at end of file
index ae110a6b4a92227a8662a132afb0e2659a3351c5..c0eeaaee4176b2d4521688569cd759054bf8ccd6 100644 (file)
 
 <html>
 <head>
-<style>
-    h3 {
-        color: 0D4781;
-    }
-</style>
+    <style>
+        h3 {
+            color: 0D4781;
+        }
+
+        img {
+            vertical-align: bottom;
+            height: 32;
+            width: 32;
+        }
+    </style>
 </head>
 
 <body>
-<h3>First-Party Cookies</h3>
+<h3><img src="images/cookie_dark_blue.png">First-Party Cookies</h3>
 
 <p>Cookies can be divided into two types.  First-party cookies are cookies set by the website in the URL bar at the top of the page.</p>
 
@@ -49,7 +55,7 @@
     as a warning.</p>
 
 
-<h3>Third-Party Cookies</h3>
+<h3><img src="images/cookie_dark_blue.png">Third-Party Cookies</h3>
 
 <p>Third-party cookies are set by portions of a website that are loaded from servers different from the URL at the top of the page.
     For example, most website that have advertisements load them from a third-party ad broker, like Google's
     between first-party and third-party cookies</a>. Thus, enabling first-party cookies will also enable third-party cookies.</p>
 
 
-<h3>DOM Storage</h3>
+<h3><img src="images/ic_web_dark_blue.png">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
     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>
+<h3><img src="images/ic_subtitles_dark_blue.png">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>
index 14bed944be46678785ca0432ac0cd3a5d43ea704..77813adedf522c1340e2d89ec279d94f0b972199 100644 (file)
 </head>
 
 <body>
+<h3>Do Not Track</h3>
+
+<p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
+    This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.
+    This header is enabled by default in Privacy Browser, although if desired it can be disabled in the settings.</p>
+
+<p>The DNT header doesn't really provide much privacy because most web servers ignore it. Yahoo programmed their servers to ignore the DNT header
+    from Internet Explorer 10 when it was turned on by default because they argued that the user had not made the decision to enable DNT.
+    Google and Microsoft ignore DNT even though they include a DNT feature in the browsers they distribute. Facebook also ignores DNT.</p>
+
+
 <h3>Advertisements</h3>
 
 <p>Privacy Browser Free includes a banner advertisement across the bottom of the screen that is populated by Google's
@@ -53,6 +64,5 @@
 <p>Verizon, one of the major mobile carriers in the United States, adds a unique tracking header to all HTTP traffic on their network.  The Electronic Frontier
     Foundation has written about the <a href="https://www.eff.org/deeplinks/2014/11/verizon-x-uidh">privacy implications of this practice</a>.  Due to public pressure
     Verizon has created a way to <a href="http://www.clark.com/how-opt-out-verizons-super-cookie-tracking">opt out of this tracking</a>.</p>
-
 </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/en/images/cookie_dark_blue.png b/app/src/main/assets/en/images/cookie_dark_blue.png
new file mode 100644 (file)
index 0000000..a4d5d40
Binary files /dev/null and b/app/src/main/assets/en/images/cookie_dark_blue.png differ
diff --git a/app/src/main/assets/en/images/ic_subtitles_dark_blue.png b/app/src/main/assets/en/images/ic_subtitles_dark_blue.png
new file mode 100644 (file)
index 0000000..11c87bd
Binary files /dev/null and b/app/src/main/assets/en/images/ic_subtitles_dark_blue.png differ
diff --git a/app/src/main/assets/en/images/ic_web_dark_blue.png b/app/src/main/assets/en/images/ic_web_dark_blue.png
new file mode 100644 (file)
index 0000000..d3030be
Binary files /dev/null and b/app/src/main/assets/en/images/ic_web_dark_blue.png differ
index d604a2e1f14bec7b4cb39094d8c0ae7203772ee1..2af787eb8788138f75bd0765807b681448096112 100644 (file)
@@ -103,7 +103,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `onOptionsItemSelected()`.
     public static boolean firstPartyCookiesEnabled;
 
-    // `thridPartyCookiesEnables` is public static so it can be accessed from `SettingsFragment`.
+    // `thirdPartyCookiesEnables` is public static so it can be accessed from `SettingsFragment`.
     // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `onOptionsItemSelected()`.
     public static boolean thirdPartyCookiesEnabled;
 
@@ -128,7 +128,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `swipeToRefreshEnabled` is public static so it can be accessed from `SettingsFragment`.  It is also used in `onCreate()`.
     public static boolean swipeToRefreshEnabled;
 
-    // `customHeader` is public static so it can be accessed from `BookmarksActivity`.  It is also used in `onCreate()` and `loadUrlFromTextBox()`.
+    // `customHeader` is public static so it can be accessed from `BookmarksActivity`.  It is also used in `onCreate()`, `onOptionsItemSelected()`, and `loadUrlFromTextBox()`.
     public static Map<String, String> customHeaders = new HashMap<String, String>();
 
 
@@ -222,9 +222,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         // drawerToggle creates the hamburger icon at the start of the AppBar.
         drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation, R.string.close_navigation);
 
-        // Replace the header that `WebView` creates for `X-Requested-With` with a null value.  The default value is the application ID (com.stoutner.privacybrowser.standard).
-        customHeaders.put("X-Requested-With", "");
-
         mainWebView.setWebViewClient(new WebViewClient() {
             // shouldOverrideUrlLoading makes this `WebView` the default handler for URLs inside the app, so that links are not kicked out to other apps.
             @Override
@@ -452,6 +449,15 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         swipeToRefresh.setEnabled(swipeToRefreshEnabled);
 
 
+        // Replace the header that `WebView` creates for `X-Requested-With` with a null value.  The default value is the application ID (com.stoutner.privacybrowser.standard).
+        customHeaders.put("X-Requested-With", "");
+
+        // Set Do Not Track.  The default is true.
+        if (sharedPreferences.getBoolean("do_not_track", true)) {
+            customHeaders.put("DNT", "1");
+        }
+
+
         // Get the intent information that started the app.
         final Intent intent = getIntent();
 
@@ -920,6 +926,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 // Clear `formattedUrlString`.
                 formattedUrlString = null;
 
+                // Clear `customHeaders`.
+                customHeaders.clear();
+
                 // Destroy the internal state of the webview.
                 mainWebView.destroy();
 
index 51952c4f071bb507b9433d56b9b541067677e0d9..4eef49c2fa7a529d087c3b7ff7669837eafe2ff8 100644 (file)
@@ -128,32 +128,30 @@ public class SettingsFragment extends PreferenceFragment {
 
                 switch (key) {
                     case "javascript_enabled":
-                        // Set javaScriptEnabled to the new state.  The default is false.
+                        // Set `javaScriptEnabled` to the new state.  The default is `false`.
                         MainWebViewActivity.javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
 
-                        // Toggle the state of the "dom_storage_enabled" preference.  The default is false.
+                        // Toggle the state of the `dom_storage_enabled` preference.  The default is `false`.
                         final Preference domStorageEnabled = findPreference("dom_storage_enabled");
                         domStorageEnabled.setEnabled(sharedPreferences.getBoolean("javascript_enabled", false));
 
-                        // Update mainWebView and reload the website.
+                        // Update `mainWebView`.
                         MainWebViewActivity.mainWebView.getSettings().setJavaScriptEnabled(MainWebViewActivity.javaScriptEnabled);
-                        MainWebViewActivity.mainWebView.reload();
 
                         // Update the privacy icons.
                         MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
                         break;
 
                     case "first_party_cookies_enabled":
-                        // Set firstPartyCookiesEnabled to the new state.  The default is false.
+                        // Set `firstPartyCookiesEnabled` to the new state.  The default is `false`.
                         MainWebViewActivity.firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
 
-                        // Toggle the state of the "third_party_cookies_enabled" preference.  The default is false.
+                        // Toggle the state of the `third_party_cookies_enabled` preference.  The default is `false`.
                         final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
                         thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false));
 
-                        // Update mainWebView and reload the website.
+                        // Update `mainWebView`.
                         MainWebViewActivity.cookieManager.setAcceptCookie(MainWebViewActivity.firstPartyCookiesEnabled);
-                        MainWebViewActivity.mainWebView.reload();
 
                         // Update the checkbox in the options menu.
                         MenuItem firstPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleFirstPartyCookies);
@@ -164,17 +162,16 @@ public class SettingsFragment extends PreferenceFragment {
                         break;
 
                     case "third_party_cookies_enabled":
-                        // Set thirdPartyCookiesEnabled to the new state.  The default is false.
+                        // Set `thirdPartyCookiesEnabled` to the new state.  The default is `false`.
                         MainWebViewActivity.thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
 
                         // Update the checkbox in the options menu.
                         MenuItem thirdPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleThirdPartyCookies);
                         thirdPartyCookiesMenuItem.setChecked(MainWebViewActivity.thirdPartyCookiesEnabled);
 
-                        // Update mainWebView and reload the website if API >= 21.
+                        // Update `mainWebView` if API >= 21.
                         if (Build.VERSION.SDK_INT >= 21) {
                             MainWebViewActivity.cookieManager.setAcceptThirdPartyCookies(MainWebViewActivity.mainWebView, MainWebViewActivity.thirdPartyCookiesEnabled);
-                            MainWebViewActivity.mainWebView.reload();
                         }
 
                         // Update the privacy icons.
@@ -182,32 +179,30 @@ public class SettingsFragment extends PreferenceFragment {
                         break;
 
                     case "dom_storage_enabled":
-                        // Set domStorageEnabled to the new state.  The default is false.
+                        // Set `domStorageEnabled` to the new state.  The default is `false`.
                         MainWebViewActivity.domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
 
                         // Update the checkbox in the options menu.
                         MenuItem domStorageMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleDomStorage);
                         domStorageMenuItem.setChecked(MainWebViewActivity.domStorageEnabled);
 
-                        // Update mainWebView and reload the website.
+                        // Update `mainWebView`.
                         MainWebViewActivity.mainWebView.getSettings().setDomStorageEnabled(MainWebViewActivity.domStorageEnabled);
-                        MainWebViewActivity.mainWebView.reload();
 
                         // Update the privacy icons.
                         MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
                         break;
 
                     case "save_form_data_enabled":
-                        // Set saveFormDataEnabled to the new state.  The default is false.
+                        // 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.
+                        // Update `mainWebView`.
                         MainWebViewActivity.mainWebView.getSettings().setSaveFormData(MainWebViewActivity.saveFormDataEnabled);
-                        MainWebViewActivity.mainWebView.reload();
 
                         // Update the privacy icons.
                         MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
@@ -218,7 +213,7 @@ public class SettingsFragment extends PreferenceFragment {
 
                         switch (userAgentString) {
                             case "Default user agent":
-                                // Set the default user agent on mainWebView, display the user agent as the summary text for userAgentPreference, and disable customUserAgent.
+                                // Set the default user agent on `mainWebView`, display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`.
                                 // Once API >= 17 we can use getDefaultUserAgent().  For now, setUserAgentString("") sets the WebView's default user agent.
                                 MainWebViewActivity.mainWebView.getSettings().setUserAgentString("");
                                 userAgentPreference.setSummary(MainWebViewActivity.mainWebView.getSettings().getUserAgentString());
@@ -298,18 +293,26 @@ public class SettingsFragment extends PreferenceFragment {
                         break;
 
                     case "javascript_enabled_search_custom_url":
-                        // Set the new custom search URL as the summary text for "javascript_enabled_search_custom_url".  The default is "".
+                        // Set the new custom search URL as the summary text for `javascript_enabled_search_custom_url`.  The default is ``.
                         javaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_enabled_search_custom_url", ""));
 
-                        // Update javaScriptEnabledSearchCustomURL.  The default is "".
+                        // Update javaScriptEnabledSearchCustomURL.  The default is ``.
                         MainWebViewActivity.javaScriptEnabledSearchURL = sharedPreferences.getString("javascript_enabled_search_custom_url", "");
                         break;
 
+                    case "do_not_track":
+                        // Update `customHeaders`.  The default is `true`.
+                        if (sharedPreferences.getBoolean("do_not_track", true)) {
+                            MainWebViewActivity.customHeaders.put("DNT", "1");
+                        } else {  // Remove the Do Not Track header.
+                            MainWebViewActivity.customHeaders.remove("DNT");
+                        }
+
                     case "homepage":
-                        // Set the new homepage URL as the summary text for the Homepage preference.  The default is "https://www.duckduckgo.com".
+                        // Set the new homepage URL as the summary text for the Homepage preference.  The default is `https://www.duckduckgo.com`.
                         homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
 
-                        // Update the homepage variable.  The default is "https://www.duckduckgo.com".
+                        // Update the homepage variable.  The default is `https://www.duckduckgo.com`.
                         MainWebViewActivity.homepage = sharedPreferences.getString("homepage", "https://www.duckduckgo.com");
                         break;
 
index 02ed5ea13b4c48483c43409f6ecc7b8a566d5807..2ede85be1dbd5078d22c0560a7e46b6b7683494a 100644 (file)
         <item>Custom user agent</item>  <!-- This item must not be translated into other languages because it is referenced in code.  It is never displayed on the screen. -->
     </string-array>
     <string name="custom_user_agent">Custom user agent</string>
+    <string name="do_not_track">Do not track</string>
+    <string name="do_not_track_summary">Send the Do Not Track header which politely suggests that web servers not track this browser.</string>
     <string name="search">Search</string>
     <string name="javascript_disabled_search">JavaScript-disabled search</string>
     <string-array name="javascript_disabled_search_entries">
index f6acd2575d2dbebf04e5dac6da15010a06d9ba41..4441ca6a5dfc3aed53ef8f3308be0028d46ca207 100644 (file)
             android:defaultValue="PrivacyBrowser/1.0"
             android:inputType="textVisiblePassword|textMultiLine" />
 
+        <SwitchPreference
+            android:key="do_not_track"
+            android:title="@string/do_not_track"
+            android:summary="@string/do_not_track_summary"
+            android:defaultValue="true" />
+
     </PreferenceCategory>
 
     <PreferenceCategory