Add UltraPrivacy. https://redmine.stoutner.com/issues/310
authorSoren Stoutner <soren@stoutner.com>
Fri, 27 Jul 2018 21:27:22 +0000 (14:27 -0700)
committerSoren Stoutner <soren@stoutner.com>
Fri, 27 Jul 2018 21:27:22 +0000 (14:27 -0700)
14 files changed:
.idea/dictionaries/soren.xml
app/src/main/assets/blocklists/ultraprivacy.txt [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java
app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java
app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java
app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java
app/src/main/res/layout/about_tab_version.xml
app/src/main/res/layout/domain_settings_fragment.xml
app/src/main/res/menu/webview_options_menu.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences.xml

index 872ecca..9a0b75f 100644 (file)
       <w>torproject</w>
       <w>uidh</w>
       <w>uids</w>
+      <w>ultraprivacy</w>
       <w>uname</w>
       <w>uncheck</w>
       <w>undelete</w>
diff --git a/app/src/main/assets/blocklists/ultraprivacy.txt b/app/src/main/assets/blocklists/ultraprivacy.txt
new file mode 100644 (file)
index 0000000..1afe7e2
--- /dev/null
@@ -0,0 +1,10 @@
+[Adblock Plus 2.0]
+! Version: 1
+! Title: UltraPrivacy
+! Last modified: 25 Jul 2018 20:41 UTC
+! Expires: 90 days (update frequency)
+! Homepage: https://www.stoutner.com/privacy-browser/blocklists/ultraprivacy/
+! Licence: GPLv3+ http://www.gnu.org/licenses/gpl-3.0.html
+!
+! I can't imagine that anything that includes `analytics` is good for your privacy.  https://redmine.stoutner.com/issues/312.
+analytics
index 7f7e995..80c5d4a 100644 (file)
@@ -644,6 +644,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         Switch easyPrivacySwitch = view.findViewById(R.id.domain_settings_easyprivacy_switch);
         Switch fanboysAnnoyanceSwitch = view.findViewById(R.id.domain_settings_fanboys_annoyance_list_switch);
         Switch fanboysSocialBlockingSwitch = view.findViewById(R.id.domain_settings_fanboys_social_blocking_list_switch);
+        Switch ultraPrivacySwitch = view.findViewById(R.id.domain_settings_ultraprivacy_switch);
         Switch blockAllThirdPartyRequestsSwitch = view.findViewById(R.id.domain_settings_block_all_third_party_requests_switch);
         Spinner userAgentSpinner = view.findViewById(R.id.domain_settings_user_agent_spinner);
         EditText customUserAgentEditText = view.findViewById(R.id.domain_settings_custom_user_agent_edittext);
@@ -666,6 +667,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         boolean easyPrivacyEnabled = easyPrivacySwitch.isChecked();
         boolean fanboysAnnoyanceEnabled = fanboysAnnoyanceSwitch.isChecked();
         boolean fanboysSocialBlockingEnabled = fanboysSocialBlockingSwitch.isChecked();
+        boolean ultraPrivacyEnabled = ultraPrivacySwitch.isChecked();
         boolean blockAllThirdPartyRequests = blockAllThirdPartyRequestsSwitch.isChecked();
         int userAgentPosition = userAgentSpinner.getSelectedItemPosition();
         int fontSizePosition = fontSizeSpinner.getSelectedItemPosition();
@@ -704,8 +706,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         if (savedSslCertificateRadioButton.isChecked()) {  // The current certificate is being used.
             // Update the database except for the certificate.
             domainsDatabaseHelper.updateDomainExceptCertificate(DomainsActivity.currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled,
-                    domStorageEnabled, formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,
-                    swipeToRefreshInt, nightModeInt, displayWebpageImagesInt, pinnedSslCertificate);
+                    domStorageEnabled, formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests,
+                    userAgentName, fontSizeInt, swipeToRefreshInt, nightModeInt, displayWebpageImagesInt, pinnedSslCertificate);
         } else if (currentWebsiteCertificateRadioButton.isChecked()) {  // The certificate is being updated with the current website certificate.
             // Get the current website SSL certificate.
             SslCertificate currentWebsiteSslCertificate = MainWebViewActivity.sslCertificate;
@@ -722,15 +724,15 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
             // Update the database.
             domainsDatabaseHelper.updateDomainWithCertificate(currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabled,
-                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt, swipeToRefreshInt,
-                    nightModeInt, displayWebpageImagesInt, pinnedSslCertificate, issuedToCommonName, issuedToOrganization, issuedToOrganizationalUnit, issuedByCommonName, issuedByOrganization,
-                    issuedByOrganizationalUnit, startDateLong, endDateLong);
+                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,
+                    swipeToRefreshInt, nightModeInt, displayWebpageImagesInt, pinnedSslCertificate, issuedToCommonName, issuedToOrganization, issuedToOrganizationalUnit, issuedByCommonName,
+                    issuedByOrganization, issuedByOrganizationalUnit, startDateLong, endDateLong);
 
         } else {  // No certificate is selected.
             // Update the database, with PINNED_SSL_CERTIFICATE set to false.
             domainsDatabaseHelper.updateDomainExceptCertificate(currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabled,
-                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,  swipeToRefreshInt,
-                    nightModeInt, displayWebpageImagesInt,false);
+                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,
+                    swipeToRefreshInt, nightModeInt, displayWebpageImagesInt,false);
         }
     }
 
index 61b94c4..7c8c543 100644 (file)
@@ -196,6 +196,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     public static String easyPrivacyVersion;
     public static String fanboysAnnoyanceVersion;
     public static String fanboysSocialVersion;
+    public static String ultraPrivacyVersion;
 
     // The request items are public static so they can be accessed by `BlockListHelper`, `RequestsArrayAdapter`, and `ViewRequestsDialog`.  They are also used in `onCreate()`.
     public static List<String[]> resourceRequests;
@@ -335,6 +336,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     private boolean easyPrivacyEnabled;
     private boolean fanboysAnnoyanceListEnabled;
     private boolean fanboysSocialBlockingListEnabled;
+    private boolean ultraPrivacyEnabled;
 
     // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
     private Runtime privacyBrowserRuntime;
@@ -1235,12 +1237,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         final ArrayList<List<String[]>> easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt");
         final ArrayList<List<String[]>> fanboysAnnoyanceList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-annoyance.txt");
         final ArrayList<List<String[]>> fanboysSocialList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-social.txt");
+        final ArrayList<List<String[]>> ultraPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/ultraprivacy.txt");
 
         // Store the list versions.
         easyListVersion = easyList.get(0).get(0)[0];
         easyPrivacyVersion = easyPrivacy.get(0).get(0)[0];
         fanboysAnnoyanceVersion = fanboysAnnoyanceList.get(0).get(0)[0];
         fanboysSocialVersion = fanboysSocialList.get(0).get(0)[0];
+        ultraPrivacyVersion = ultraPrivacy.get(0).get(0)[0];
 
         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.
@@ -1369,6 +1373,23 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     return emptyWebResourceResponse;
                 }
 
+                // Check UltraPrivacy if it is enabled.
+                if (ultraPrivacyEnabled) {
+                    if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, ultraPrivacy)) {
+                        // The resource request was blocked.  Return an empty web resource response.
+                        return emptyWebResourceResponse;
+                    }
+
+                    // If the whitelist result is not null, the request has been allowed by UltraPrivacy.
+                    if (whiteListResultStringArray != null) {
+                        // Add a whitelist entry to the resource requests array.
+                        resourceRequests.add(whiteListResultStringArray);
+
+                        // The resource request has been allowed by UltraPrivacy.  `return null` loads the requested resource.
+                        return null;
+                    }
+                }
+
                 // Check EasyList if it is enabled.
                 if (easyListEnabled) {
                     if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyList)) {
@@ -1845,6 +1866,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         MenuItem easyPrivacyMenuItem = menu.findItem(R.id.easyprivacy);
         MenuItem fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list);
         MenuItem fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list);
+        MenuItem ultraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy);
         MenuItem blockAllThirdParyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests);
         MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size);
         MenuItem swipeToRefreshMenuItem = menu.findItem(R.id.swipe_to_refresh);
@@ -1866,6 +1888,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         easyPrivacyMenuItem.setChecked(easyPrivacyEnabled);
         fanboysAnnoyanceListMenuItem.setChecked(fanboysAnnoyanceListEnabled);
         fanboysSocialBlockingListMenuItem.setChecked(fanboysSocialBlockingListEnabled);
+        ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled);
         blockAllThirdParyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
         swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
         displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically());
@@ -2343,6 +2366,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 mainWebView.reload();
                 return true;
 
+            case R.id.ultraprivacy:
+                // Toggle the UltraPrivacy status.
+                ultraPrivacyEnabled = !ultraPrivacyEnabled;
+
+                // Update the menu checkbox.
+                menuItem.setChecked(ultraPrivacyEnabled);
+
+                // Reload the main WebView.
+                mainWebView.reload();
+                return true;
+
             case R.id.block_all_third_party_requests:
                 //Toggle the third-party requests blocker status.
                 blockAllThirdPartyRequests = !blockAllThirdPartyRequests;
@@ -3730,6 +3764,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 easyPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1);
                 fanboysAnnoyanceListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST)) == 1);
                 fanboysSocialBlockingListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST)) == 1);
+                ultraPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY)) == 1);
                 blockAllThirdPartyRequests = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS)) == 1);
                 String userAgentName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
                 int fontSize = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
@@ -3886,6 +3921,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true);
                 fanboysAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true);
                 fanboysSocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true);
+                ultraPrivacyEnabled = sharedPreferences.getBoolean("ultraprivacy", true);
                 blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false);
 
                 // Set `javaScriptEnabled` to be `true` if `night_mode` is `true`.
index fbc487e..2004583 100644 (file)
@@ -107,6 +107,7 @@ public class AboutTabFragment extends Fragment {
             TextView versionEasyPrivacyTextView = tabLayout.findViewById(R.id.about_version_easyprivacy);
             TextView versionFanboyAnnoyanceTextView = tabLayout.findViewById(R.id.about_version_fanboy_annoyance);
             TextView versionFanboySocialTextView = tabLayout.findViewById(R.id.about_version_fanboy_social);
+            TextView versionUltraPrivacyTextView = tabLayout.findViewById(R.id.about_version_ultraprivacy);
             TextView certificateIssuerDNTextView = tabLayout.findViewById(R.id.about_version_certificate_issuer_dn);
             TextView certificateSubjectDNTextView = tabLayout.findViewById(R.id.about_version_certificate_subject_dn);
             TextView certificateStartDateTextView = tabLayout.findViewById(R.id.about_version_certificate_start_date);
@@ -130,6 +131,7 @@ public class AboutTabFragment extends Fragment {
             String easyPrivacyLabel = getString(R.string.easyprivacy_label) + "  ";
             String fanboyAnnoyanceLabel = getString(R.string.fanboy_annoyance_label) + "  ";
             String fanboySocialLabel = getString(R.string.fanboy_social_label) + "  ";
+            String ultraPrivacyLabel = getString(R.string.ultraprivacy_label) + "  ";
             String issuerDNLabel = getString(R.string.issuer_dn) + "  ";
             String subjectDNLabel = getString(R.string.subject_dn) + "  ";
             String startDateLabel = getString(R.string.start_date) + "  ";
@@ -183,6 +185,7 @@ public class AboutTabFragment extends Fragment {
             SpannableStringBuilder easyPrivacyStringBuilder = new SpannableStringBuilder(easyPrivacyLabel + MainWebViewActivity.easyPrivacyVersion);
             SpannableStringBuilder fanboyAnnoyanceStringBuilder = new SpannableStringBuilder(fanboyAnnoyanceLabel + MainWebViewActivity.fanboysAnnoyanceVersion);
             SpannableStringBuilder fanboySocialStringBuilder = new SpannableStringBuilder(fanboySocialLabel + MainWebViewActivity.fanboysSocialVersion);
+            SpannableStringBuilder ultraPrivacyStringBuilder = new SpannableStringBuilder(ultraPrivacyLabel + MainWebViewActivity.ultraPrivacyVersion);
 
             // Create the `blueColorSpan` variable.
             ForegroundColorSpan blueColorSpan;
@@ -210,6 +213,7 @@ public class AboutTabFragment extends Fragment {
             easyPrivacyStringBuilder.setSpan(blueColorSpan, easyPrivacyLabel.length(), easyPrivacyStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
             fanboyAnnoyanceStringBuilder.setSpan(blueColorSpan, fanboyAnnoyanceLabel.length(), fanboyAnnoyanceStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
             fanboySocialStringBuilder.setSpan(blueColorSpan, fanboySocialLabel.length(), fanboySocialStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            ultraPrivacyStringBuilder.setSpan(blueColorSpan, ultraPrivacyLabel.length(), ultraPrivacyStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
 
             // Display the strings in the text boxes.
             versionNumberTextView.setText(version);
@@ -226,6 +230,7 @@ public class AboutTabFragment extends Fragment {
             versionEasyPrivacyTextView.setText(easyPrivacyStringBuilder);
             versionFanboyAnnoyanceTextView.setText(fanboyAnnoyanceStringBuilder);
             versionFanboySocialTextView.setText(fanboySocialStringBuilder);
+            versionUltraPrivacyTextView.setText(ultraPrivacyStringBuilder);
 
             // Build.VERSION.SECURITY_PATCH is only available for SDK_INT >= 23.
             if (Build.VERSION.SDK_INT >= 23) {
index 51337fb..bfa6da7 100644 (file)
@@ -120,6 +120,8 @@ public class DomainSettingsFragment extends Fragment {
         ImageView fanboysAnnoyanceListImageView = domainSettingsView.findViewById(R.id.domain_settings_fanboys_annoyance_list_imageview);
         Switch fanboysSocialBlockingListSwitch = domainSettingsView.findViewById(R.id.domain_settings_fanboys_social_blocking_list_switch);
         ImageView fanboysSocialBlockingListImageView = domainSettingsView.findViewById(R.id.domain_settings_fanboys_social_blocking_list_imageview);
+        Switch ultraPrivacySwitch = domainSettingsView.findViewById(R.id.domain_settings_ultraprivacy_switch);
+        ImageView ultraPrivacyImageView = domainSettingsView.findViewById(R.id.domain_settings_ultraprivacy_imageview);
         Switch blockAllThirdPartyRequestsSwitch = domainSettingsView.findViewById(R.id.domain_settings_block_all_third_party_requests_switch);
         ImageView blockAllThirdPartyRequestsImageView = domainSettingsView.findViewById(R.id.domain_settings_block_all_third_party_requests_imageview);
         final Spinner userAgentSpinner = domainSettingsView.findViewById(R.id.domain_settings_user_agent_spinner);
@@ -188,6 +190,7 @@ public class DomainSettingsFragment extends Fragment {
         int easyPrivacyEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY));
         int fanboysAnnoyanceListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST));
         int fanboysSocialBlockingListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST));
+        int ultraPrivacyEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY));
         int blockAllThirdPartyRequestsInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS));
         final String currentUserAgentName = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
         int fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
@@ -592,6 +595,29 @@ public class DomainSettingsFragment extends Fragment {
             }
         }
 
+        // Set the UltraPrivacy status.  Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+        if (ultraPrivacyEnabledInt == 1) {  // UltraPrivacy is on.
+            // Turn the switch on.
+            ultraPrivacySwitch.setChecked(true);
+
+            // Set the icon according to the theme.
+            if (MainWebViewActivity.darkTheme) {
+                ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_dark));
+            } else {
+                ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_light));
+            }
+        } else {  // EasyPrivacy is off.
+            // Turn the switch off.
+            ultraPrivacySwitch.setChecked(false);
+
+            // Set the icon according to the theme.
+            if (MainWebViewActivity.darkTheme) {
+                ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_dark));
+            } else {
+                ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_light));
+            }
+        }
+
         // Set the third-party resource blocking status.  Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
         if (blockAllThirdPartyRequestsInt == 1) {  // Blocking all third-party requests is on.
             // Turn the switch on.
@@ -1319,6 +1345,26 @@ public class DomainSettingsFragment extends Fragment {
             }
         });
 
+        // Set the UltraPrivacy switch listener.
+        ultraPrivacySwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
+            // Update the icon.
+            if (isChecked) {  // UltraPrivacy is on.
+                // Set the icon according to the theme.
+                if (MainWebViewActivity.darkTheme) {
+                    ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_dark));
+                } else {
+                    ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_light));
+                }
+            } else {  // UltraPrivacy is off.
+                // Set the icon according to the theme.
+                if (MainWebViewActivity.darkTheme) {
+                    ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_dark));
+                } else {
+                    ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_light));
+                }
+            }
+        });
+
         // Set the block all third-party requests switch listener.
         blockAllThirdPartyRequestsSwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
             // Update the icon.
index 19fa1e3..c8481c0 100644 (file)
@@ -66,6 +66,7 @@ public class SettingsFragment extends PreferenceFragment {
         final Preference easyPrivacyPreference = findPreference("easyprivacy");
         final Preference fanboyAnnoyanceListPreference = findPreference("fanboy_annoyance_list");
         final Preference fanboySocialBlockingListPreference = findPreference("fanboy_social_blocking_list");
+        final Preference ultraPrivacyPreference = findPreference("ultraprivacy");
         final Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
         final Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot");
         final Preference torHomepagePreference = findPreference("tor_homepage");
@@ -424,6 +425,21 @@ public class SettingsFragment extends PreferenceFragment {
             }
         }
 
+        // Set the UltraPrivacy icon.
+        if (savedPreferences.getBoolean("ultraprivacy", true)) {
+            if (MainWebViewActivity.darkTheme) {
+                ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
+            } else {
+                ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
+            }
+        } else {
+            if (MainWebViewActivity.darkTheme) {
+                ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
+            } else {
+                ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
+            }
+        }
+
         // Set the block all third-party requests icon.
         if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
             if (MainWebViewActivity.darkTheme) {
@@ -1019,6 +1035,23 @@ public class SettingsFragment extends PreferenceFragment {
                     }
                     break;
 
+                case "ultraprivacy":
+                    // Update the icon.
+                    if (sharedPreferences.getBoolean("ultraprivacy", true)) {
+                        if (MainWebViewActivity.darkTheme) {
+                            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
+                        } else {
+                            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
+                        }
+                    } else {
+                        if (MainWebViewActivity.darkTheme) {
+                            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
+                        } else {
+                            ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
+                        }
+                    }
+                    break;
+
                 case "block_all_third_party_requests":
                     // Update the icon.
                     if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
index 619537a..f9348f6 100644 (file)
@@ -20,7 +20,6 @@
 package com.stoutner.privacybrowser.helpers;
 
 import android.content.res.AssetManager;
-import android.net.Uri;
 
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
index 0c853e5..c38730e 100644 (file)
@@ -28,7 +28,7 @@ import android.database.sqlite.SQLiteOpenHelper;
 import android.preference.PreferenceManager;
 
 public class DomainsDatabaseHelper extends SQLiteOpenHelper {
-    private static final int SCHEMA_VERSION = 7;
+    private static final int SCHEMA_VERSION = 8;
     private static final String DOMAINS_DATABASE = "domains.db";
     private static final String DOMAINS_TABLE = "domains";
 
@@ -42,8 +42,9 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
     public static final String ENABLE_EASYLIST = "enableeasylist";
     public static final String ENABLE_EASYPRIVACY = "enableeasyprivacy";
     public static final String ENABLE_FANBOYS_ANNOYANCE_LIST = "enablefanboysannoyancelist";
-    public static final String BLOCK_ALL_THIRD_PARTY_REQUESTS = "blockallthirdpartyrequests";
     public static final String ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST = "enablefanboyssocialblockinglist";
+    public static final String ENABLE_ULTRAPRIVACY = "enableultraprivacy";
+    public static final String BLOCK_ALL_THIRD_PARTY_REQUESTS = "blockallthirdpartyrequests";
     public static final String USER_AGENT = "useragent";
     public static final String FONT_SIZE = "fontsize";
     public static final String SWIPE_TO_REFRESH = "swipetorefresh";
@@ -99,6 +100,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
                 ENABLE_EASYPRIVACY + " BOOLEAN, " +
                 ENABLE_FANBOYS_ANNOYANCE_LIST + " BOOLEAN, " +
                 ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN, " +
+                ENABLE_ULTRAPRIVACY + " BOOLEAN, " +
                 BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN, " +
                 USER_AGENT + " TEXT, " +
                 FONT_SIZE + " INTEGER, " +
@@ -200,6 +202,14 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
             case 6:
                 // Add the block all third-party requests column.
                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN");
+
+            // Upgrade from schema version 7.
+            case 7:
+                // Add the UltraPrivacy column.
+                domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_ULTRAPRIVACY + " BOOLEAN");
+
+                // Enable it for all existing rows.
+                domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_ULTRAPRIVACY + " = " + 1);
         }
     }
 
@@ -268,6 +278,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
         boolean easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true);
         boolean fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true);
         boolean fanboySocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true);
+        boolean ultraPrivacyEnabled = sharedPreferences.getBoolean("ultraprivacy", true);
         boolean blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false);
 
         // Create entries for the database fields.  The ID is created automatically.  The pinned SSL certificate information is not created unless added by the user.
@@ -281,6 +292,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboyAnnoyanceListEnabled);
         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboySocialBlockingListEnabled);
+        domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
         domainContentValues.put(USER_AGENT, "System default user agent");
         domainContentValues.put(FONT_SIZE, 0);
@@ -303,7 +315,8 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
 
     public void updateDomainExceptCertificate(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled,
                                               boolean formDataEnabled, boolean easyListEnabled, boolean easyPrivacyEnabled, boolean fanboysAnnoyanceEnabled, boolean fanboysSocialBlockingEnabled,
-                                              boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages, boolean pinnedSslCertificate) {
+                                              boolean ultraPrivacyEnabled, boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages,
+                                              boolean pinnedSslCertificate) {
 
         // Store the domain data in a `ContentValues`.
         ContentValues domainContentValues = new ContentValues();
@@ -319,6 +332,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboysAnnoyanceEnabled);
         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboysSocialBlockingEnabled);
+        domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
         domainContentValues.put(USER_AGENT, userAgent);
         domainContentValues.put(FONT_SIZE, fontSize);
@@ -339,9 +353,9 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
 
     public void updateDomainWithCertificate(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled,
                                             boolean formDataEnabled, boolean easyListEnabled, boolean easyPrivacyEnabled, boolean fanboysAnnoyanceEnabled, boolean fanboysSocialBlockingEnabled,
-                                            boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages, boolean pinnedSslCertificate,
-                                            String sslIssuedToCommonName, String sslIssuedToOrganization, String sslIssuedToOrganizationalUnit, String sslIssuedByCommonName, String sslIssuedByOrganization,
-                                            String sslIssuedByOrganizationalUnit, long sslStartDate, long sslEndDate) {
+                                            boolean ultraPrivacyEnabled, boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages,
+                                            boolean pinnedSslCertificate, String sslIssuedToCommonName, String sslIssuedToOrganization, String sslIssuedToOrganizationalUnit, String sslIssuedByCommonName,
+                                            String sslIssuedByOrganization, String sslIssuedByOrganizationalUnit, long sslStartDate, long sslEndDate) {
 
         // Store the domain data in a `ContentValues`.
         ContentValues domainContentValues = new ContentValues();
@@ -357,6 +371,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper {
         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboysAnnoyanceEnabled);
         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboysSocialBlockingEnabled);
+        domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
         domainContentValues.put(USER_AGENT, userAgent);
         domainContentValues.put(FONT_SIZE, fontSize);
index bfaa7f4..ac900a5 100644 (file)
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content" />
 
+            <TextView
+                android:id="@+id/about_version_ultraprivacy"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content" />
+
             <!-- Package Signature. -->
             <TextView
                 android:layout_height="wrap_content"
index da29245..bcf4d03 100644 (file)
                 android:textSize="18sp" />
         </LinearLayout>
 
+        <!-- UltraPrivacy. -->
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:orientation="horizontal" >
+
+            <ImageView
+                android:id="@+id/domain_settings_ultraprivacy_imageview"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_marginTop="1dp"
+                android:layout_marginEnd="10dp"
+                android:layout_gravity="center_vertical"
+                tools:ignore="contentDescription" />
+
+            <Switch
+                android:id="@+id/domain_settings_ultraprivacy_switch"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_marginStart="8dp"
+                android:layout_marginTop="14dp"
+                android:layout_marginBottom="14dp"
+                android:text="@string/ultraprivacy"
+                android:textColor="?android:textColorPrimary"
+                android:textSize="18sp" />
+        </LinearLayout>
+
         <!-- Block All Third Party Requests. -->
         <LinearLayout
             android:layout_height="wrap_content"
index 28e0cfe..8bc8a9a 100644 (file)
                 android:checkable="true"
                 app:showAsAction="never" />
 
+            <item
+                android:id="@+id/ultraprivacy"
+                android:title="@string/ultraprivacy"
+                android:orderInCategory="850"
+                android:checkable="true"
+                app:showAsAction="never" />
+
             <item
                 android:id="@+id/block_all_third_party_requests"
                 android:title="@string/options_block_all_third_party_requests"
-                android:orderInCategory="850"
+                android:orderInCategory="860"
                 android:checkable="true"
                 app:showAsAction="never" />
         </menu>
index 23efb27..a317123 100644 (file)
         <string name="fanboys_annoyance_list_summary">Block annoying popups and links.  Includes Fanboy’s social blocking lists.</string>
         <string name="fanboys_social_blocking_list">Fanboy’s social blocking list</string>
         <string name="fanboys_social_blocking_list_summary">Blocks third-party social media content.</string>
+        <string name="ultraprivacy">UltraPrivacy</string>
+        <string name="ultraprivacy_summary">UltraPrivacy blocks trackers that EasyPrivacy doesn’t because doing so can break websites.</string>
         <string name="block_all_third_party_requests">Block all third-party requests</string>
         <string name="block_all_third_party_requests_summary">Blocking all third-party requests increases privacy, but it breaks many websites.</string>
     <string name="tor">Tor</string>
             <string name="easyprivacy_label">EasyPrivacy:</string>
             <string name="fanboy_annoyance_label">Fanboy’s Annoyance List:</string>
             <string name="fanboy_social_label">Fanboy’s Social Blocking List:</string>
+            <string name="ultraprivacy_label">UltraPrivacy:</string>
         <string name="package_signature">Package Signature</string>
             <string name="issuer_dn">Issuer DN:</string>
             <string name="subject_dn">Subject DN:</string>
index 4549040..d52f56c 100644 (file)
             android:summary="@string/fanboys_social_blocking_list_summary"
             android:defaultValue="true" />
 
+        <SwitchPreference
+            android:key="ultraprivacy"
+            android:title="@string/ultraprivacy"
+            android:summary="@string/ultraprivacy_summary"
+            android:defaultValue="true" />
+
         <SwitchPreference
             android:key="block_all_third_party_requests"
             android:title="@string/block_all_third_party_requests"