From 430b2b303a01cad55c8a8c69faa536f4bb228cc3 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Fri, 27 Jul 2018 14:27:22 -0700 Subject: [PATCH] Add UltraPrivacy. https://redmine.stoutner.com/issues/310 --- .idea/dictionaries/soren.xml | 1 + .../main/assets/blocklists/ultraprivacy.txt | 10 ++++ .../activities/DomainsActivity.java | 16 ++++--- .../activities/MainWebViewActivity.java | 36 +++++++++++++++ .../fragments/AboutTabFragment.java | 5 ++ .../fragments/DomainSettingsFragment.java | 46 +++++++++++++++++++ .../fragments/SettingsFragment.java | 33 +++++++++++++ .../helpers/BlockListHelper.java | 1 - .../helpers/DomainsDatabaseHelper.java | 27 ++++++++--- app/src/main/res/layout/about_tab_version.xml | 5 ++ .../res/layout/domain_settings_fragment.xml | 27 +++++++++++ .../main/res/menu/webview_options_menu.xml | 9 +++- app/src/main/res/values/strings.xml | 3 ++ app/src/main/res/xml/preferences.xml | 6 +++ 14 files changed, 210 insertions(+), 15 deletions(-) create mode 100644 app/src/main/assets/blocklists/ultraprivacy.txt diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index 872ecca6..9a0b75ff 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -145,6 +145,7 @@ torproject uidh uids + ultraprivacy uname uncheck undelete diff --git a/app/src/main/assets/blocklists/ultraprivacy.txt b/app/src/main/assets/blocklists/ultraprivacy.txt new file mode 100644 index 00000000..1afe7e2f --- /dev/null +++ b/app/src/main/assets/blocklists/ultraprivacy.txt @@ -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 diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java index 7f7e995c..80c5d4a1 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java @@ -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); } } diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 61b94c4b..7c8c5432 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -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 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> easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt"); final ArrayList> fanboysAnnoyanceList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-annoyance.txt"); final ArrayList> fanboysSocialList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-social.txt"); + final ArrayList> 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`. diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java index fbc487e9..20045832 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java @@ -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) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java index 51337fb7..bfa6da74 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java @@ -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. diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index 19fa1e3a..c8481c0b 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -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)) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java index 619537a9..f9348f6c 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java @@ -20,7 +20,6 @@ package com.stoutner.privacybrowser.helpers; import android.content.res.AssetManager; -import android.net.Uri; import com.stoutner.privacybrowser.activities.MainWebViewActivity; diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java index 0c853e56..c38730ea 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java @@ -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); diff --git a/app/src/main/res/layout/about_tab_version.xml b/app/src/main/res/layout/about_tab_version.xml index bfaa7f4d..ac900a5d 100644 --- a/app/src/main/res/layout/about_tab_version.xml +++ b/app/src/main/res/layout/about_tab_version.xml @@ -188,6 +188,11 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" /> + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 23efb274..a317123a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -392,6 +392,8 @@ Block annoying popups and links. Includes Fanboy’s social blocking lists. Fanboy’s social blocking list Blocks third-party social media content. + UltraPrivacy + UltraPrivacy blocks trackers that EasyPrivacy doesn’t because doing so can break websites. Block all third-party requests Blocking all third-party requests increases privacy, but it breaks many websites. Tor @@ -546,6 +548,7 @@ EasyPrivacy: Fanboy’s Annoyance List: Fanboy’s Social Blocking List: + UltraPrivacy: Package Signature Issuer DN: Subject DN: diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4549040a..d52f56c7 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -116,6 +116,12 @@ android:summary="@string/fanboys_social_blocking_list_summary" android:defaultValue="true" /> + +