From: Soren Stoutner Date: Wed, 18 Jul 2018 23:05:23 +0000 (-0700) Subject: Add an option to block all third-party requests. https://redmine.stoutner.com/issues/209 X-Git-Tag: v2.12~13 X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=commitdiff_plain;h=69b0fea4c49422f5e3c377994c4cf249bdc5a434 Add an option to block all third-party requests. https://redmine.stoutner.com/issues/209 --- diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml index 02141c9f..6e3671ed 100644 --- a/.idea/assetWizardSettings.xml +++ b/.idea/assetWizardSettings.xml @@ -68,7 +68,7 @@ @@ -78,7 +78,7 @@ diff --git a/app/src/main/assets/de/about_licenses_dark.html b/app/src/main/assets/de/about_licenses_dark.html index 165f8f98..c83a1368 100644 --- a/app/src/main/assets/de/about_licenses_dark.html +++ b/app/src/main/assets/de/about_licenses_dark.html @@ -117,6 +117,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/de/about_licenses_light.html b/app/src/main/assets/de/about_licenses_light.html index f242dc07..7b5b0cb4 100644 --- a/app/src/main/assets/de/about_licenses_light.html +++ b/app/src/main/assets/de/about_licenses_light.html @@ -117,6 +117,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/en/about_licenses_dark.html b/app/src/main/assets/en/about_licenses_dark.html index 3bddeab5..56d6b1c1 100644 --- a/app/src/main/assets/en/about_licenses_dark.html +++ b/app/src/main/assets/en/about_licenses_dark.html @@ -115,6 +115,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/en/about_licenses_light.html b/app/src/main/assets/en/about_licenses_light.html index 49397f98..e4be1e11 100644 --- a/app/src/main/assets/en/about_licenses_light.html +++ b/app/src/main/assets/en/about_licenses_light.html @@ -116,6 +116,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/es/about_licenses_dark.html b/app/src/main/assets/es/about_licenses_dark.html index c7ae7228..db1fdcef 100644 --- a/app/src/main/assets/es/about_licenses_dark.html +++ b/app/src/main/assets/es/about_licenses_dark.html @@ -120,6 +120,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/es/about_licenses_light.html b/app/src/main/assets/es/about_licenses_light.html index 6d1fb8ba..e21b26f0 100644 --- a/app/src/main/assets/es/about_licenses_light.html +++ b/app/src/main/assets/es/about_licenses_light.html @@ -121,6 +121,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/it/about_licenses_dark.html b/app/src/main/assets/it/about_licenses_dark.html index f0fd34f4..8b51ffea 100644 --- a/app/src/main/assets/it/about_licenses_dark.html +++ b/app/src/main/assets/it/about_licenses_dark.html @@ -124,6 +124,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/it/about_licenses_light.html b/app/src/main/assets/it/about_licenses_light.html index 82dea778..5e085388 100644 --- a/app/src/main/assets/it/about_licenses_light.html +++ b/app/src/main/assets/it/about_licenses_light.html @@ -124,6 +124,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/ru/about_licenses_dark.html b/app/src/main/assets/ru/about_licenses_dark.html index e18c1e1f..9a0806f8 100644 --- a/app/src/main/assets/ru/about_licenses_dark.html +++ b/app/src/main/assets/ru/about_licenses_dark.html @@ -117,6 +117,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/ru/about_licenses_light.html b/app/src/main/assets/ru/about_licenses_light.html index b337dfdd..4b5ed099 100644 --- a/app/src/main/assets/ru/about_licenses_light.html +++ b/app/src/main/assets/ru/about_licenses_light.html @@ -117,6 +117,7 @@

lock.

map.

more.

+

new releases.

question_answer.

refresh.

search.

diff --git a/app/src/main/assets/shared_images/new_releases_dark.png b/app/src/main/assets/shared_images/new_releases_dark.png new file mode 100644 index 00000000..b918a631 Binary files /dev/null and b/app/src/main/assets/shared_images/new_releases_dark.png differ diff --git a/app/src/main/assets/shared_images/new_releases_light.png b/app/src/main/assets/shared_images/new_releases_light.png new file mode 100644 index 00000000..56570d6a Binary files /dev/null and b/app/src/main/assets/shared_images/new_releases_light.png differ 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 f0a3a0a1..7f7e995c 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 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); Spinner fontSizeSpinner = view.findViewById(R.id.domain_settings_font_size_spinner); @@ -665,6 +666,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo boolean easyPrivacyEnabled = easyPrivacySwitch.isChecked(); boolean fanboysAnnoyanceEnabled = fanboysAnnoyanceSwitch.isChecked(); boolean fanboysSocialBlockingEnabled = fanboysSocialBlockingSwitch.isChecked(); + boolean blockAllThirdPartyRequests = blockAllThirdPartyRequestsSwitch.isChecked(); int userAgentPosition = userAgentSpinner.getSelectedItemPosition(); int fontSizePosition = fontSizeSpinner.getSelectedItemPosition(); int swipeToRefreshInt = swipeToRefreshSpinner.getSelectedItemPosition(); @@ -702,8 +704,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, userAgentName, fontSizeInt, swipeToRefreshInt, nightModeInt, - displayWebpageImagesInt, pinnedSslCertificate); + domStorageEnabled, formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, 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; @@ -720,15 +722,15 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Update the database. domainsDatabaseHelper.updateDomainWithCertificate(currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabled, - formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, userAgentName, fontSizeInt, swipeToRefreshInt, nightModeInt, - displayWebpageImagesInt, pinnedSslCertificate, issuedToCommonName, issuedToOrganization, issuedToOrganizationalUnit, issuedByCommonName, issuedByOrganization, issuedByOrganizationalUnit, - startDateLong, endDateLong); + formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, 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, userAgentName, fontSizeInt, swipeToRefreshInt, nightModeInt, - displayWebpageImagesInt,false); + formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, 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 07126c98..49176378 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -194,8 +194,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // The block list versions are public static so they can be accessed from `AboutTabFragment`. They are also used in `onCreate()`. public static String easyListVersion; public static String easyPrivacyVersion; - public static String fanboyAnnoyanceVersion; - public static String fanboySocialVersion; + public static String fanboysAnnoyanceVersion; + public static String fanboysSocialVersion; // 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; @@ -209,7 +209,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook public final static int REQUEST_DEFAULT = 0; public final static int REQUEST_ALLOWED = 1; - public final static int REQUEST_BLOCKED = 2; + public final static int REQUEST_THIRD_PARTY = 2; + public final static int REQUEST_BLOCKED = 3; public final static int MAIN_WHITELIST = 1; public final static int FINAL_WHITELIST = 2; @@ -235,6 +236,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook public final static int THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLACKLIST = 21; public final static int REGULAR_EXPRESSION_BLACKLIST = 22; + // `blockAllThirdPartyRequests` is public static so it can be accessed from `RequestsActivity`. + // It is also used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()` + public static boolean blockAllThirdPartyRequests; + // `currentBookmarksFolder` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onCreate()`, `onBackPressed()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, // `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`. public static String currentBookmarksFolder; @@ -874,9 +879,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Count the number of blocked requests. for (int i = 0; i < resourceRequests.size(); i++) { + // Add the blocked requests. if (Integer.valueOf(resourceRequests.get(i)[REQUEST_DISPOSITION]) == REQUEST_BLOCKED) { blockedRequests++; } + + // Add the third-party requests if they are blocked. + if (blockAllThirdPartyRequests && (Integer.valueOf(resourceRequests.get(i)[REQUEST_DISPOSITION]) == REQUEST_THIRD_PARTY)) { + blockedRequests++; + } } // Update the back, forward, history, and requests menu items. @@ -1162,14 +1173,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Parse the block lists. final ArrayList> easyList = blockListHelper.parseBlockList(getAssets(), "blocklists/easylist.txt"); final ArrayList> easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt"); - final ArrayList> fanboyAnnoyance = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-annoyance.txt"); - final ArrayList> fanboySocial = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-social.txt"); + final ArrayList> fanboysAnnoyanceList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-annoyance.txt"); + final ArrayList> fanboysSocialList = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-social.txt"); // Store the list versions. easyListVersion = easyList.get(0).get(0)[0]; easyPrivacyVersion = easyPrivacy.get(0).get(0)[0]; - fanboyAnnoyanceVersion = fanboyAnnoyance.get(0).get(0)[0]; - fanboySocialVersion = fanboySocial.get(0).get(0)[0]; + fanboysAnnoyanceVersion = fanboysAnnoyanceList.get(0).get(0)[0]; + fanboysSocialVersion = fanboysSocialList.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. @@ -1248,9 +1259,56 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reset `whiteListResultStringArray`. whiteListResultStringArray = null; + // Initialize the third party request tracker. + boolean isThirdPartyRequest = false; + + // + String currentDomain = ""; + + // Nobody is happy when comparing null strings. + if (!(formattedUrlString == null) && !(url == null)) { + // Get the domain strings to URIs. + Uri currentDomainUri = Uri.parse(formattedUrlString); + Uri requestDomainUri = Uri.parse(url); + + // Get the domain host names. + String currentBaseDomain = currentDomainUri.getHost(); + String requestBaseDomain = requestDomainUri.getHost(); + + // Update the current domain variable. + currentDomain = currentBaseDomain; + + // Only compare the current base domain and the request base domain if neither is null. + if (!(currentBaseDomain == null) && !(requestBaseDomain == null)) { + // Determine the current base domain. + while (currentBaseDomain.indexOf(".", currentBaseDomain.indexOf(".") + 1) > 0) { // There is at least one subdomain. + // Remove the first subdomain. + currentBaseDomain = currentBaseDomain.substring(currentBaseDomain.indexOf(".") + 1); + } + + // Determine the request base domain. + while (requestBaseDomain.indexOf(".", requestBaseDomain.indexOf(".") + 1) > 0) { // There is at least one subdomain. + // Remove the first subdomain. + requestBaseDomain = requestBaseDomain.substring(requestBaseDomain.indexOf(".") + 1); + } + + // Update the third party request tracker. + isThirdPartyRequest = !currentBaseDomain.equals(requestBaseDomain); + } + } + + // Block third-party requests if enabled. + if (isThirdPartyRequest && blockAllThirdPartyRequests) { + // Add the request to the log. + resourceRequests.add(new String[]{String.valueOf(REQUEST_THIRD_PARTY), url}); + + // Return an empty web resource response. + return emptyWebResourceResponse; + } + // Check EasyList if it is enabled. if (easyListEnabled) { - if (blockListHelper.isBlocked(formattedUrlString, url, easyList)) { + if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyList)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } @@ -1258,7 +1316,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check EasyPrivacy if it is enabled. if (easyPrivacyEnabled) { - if (blockListHelper.isBlocked(formattedUrlString, url, easyPrivacy)) { + if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyPrivacy)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } @@ -1266,18 +1324,18 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check Fanboy’s Annoyance List if it is enabled. if (fanboysAnnoyanceListEnabled) { - if (blockListHelper.isBlocked(formattedUrlString, url, fanboyAnnoyance)) { + if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } } else if (fanboysSocialBlockingListEnabled){ // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled. - if (blockListHelper.isBlocked(formattedUrlString, url, fanboySocial)) { + if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, fanboysSocialList)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } } - // Add the request to the log. + // Add the request to the log because it hasn't been processed by any of the previous checks. if (whiteListResultStringArray != null ) { // The request was processed by a whitelist. resourceRequests.add(whiteListResultStringArray); } else { // The request didn't match any blocklist entry. Log it as a defult request. @@ -1511,12 +1569,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check to see if the intent contains a new URL. if (intent.getData() != null) { - // Get the intent data and convert it to a string. + // Get the intent data. final Uri intentUriData = intent.getData(); - formattedUrlString = intentUriData.toString(); // Load the website. - loadUrl(formattedUrlString); + loadUrl(intentUriData.toString()); // Close the navigation drawer if it is open. if (drawerLayout.isDrawerVisible(GravityCompat.START)) { @@ -1701,6 +1758,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 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); MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images); @@ -1721,6 +1779,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook easyPrivacyMenuItem.setChecked(easyPrivacyEnabled); fanboysAnnoyanceListMenuItem.setChecked(fanboysAnnoyanceListEnabled); fanboysSocialBlockingListMenuItem.setChecked(fanboysSocialBlockingListEnabled); + blockAllThirdParyRequestsMenuItem.setChecked(blockAllThirdPartyRequests); swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled()); displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically()); @@ -2190,13 +2249,24 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Toggle Fanboy's Social Blocking List status. fanboysSocialBlockingListEnabled = !fanboysSocialBlockingListEnabled; - // Update teh menu checkbox. + // Update the menu checkbox. menuItem.setChecked(fanboysSocialBlockingListEnabled); // 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; + + // Update the menu checkbox. + menuItem.setChecked(blockAllThirdPartyRequests); + + // Reload the main WebView. + mainWebView.reload(); + return true; + case R.id.share: // Setup the share string. String shareString = webViewTitle + " – " + urlTextBox.getText().toString(); @@ -3248,6 +3318,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } private void loadUrl(String url) {// Apply any custom domain settings. + // Set the URL as the formatted URL string so that checking third-party requests works correctly. + formattedUrlString = url; + + // Apply the domain settings. applyDomainSettings(url, true, false); // Set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website. @@ -3554,6 +3628,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); + 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)); int swipeToRefreshInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH)); @@ -3709,6 +3784,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); + blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false); // Set `javaScriptEnabled` to be `true` if `night_mode` is `true`. if (nightMode) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java index dcf64129..4b58053a 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java @@ -86,6 +86,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi List allResourceRequests = new ArrayList<>(); List defaultResourceRequests = new ArrayList<>(); List allowedResourceRequests = new ArrayList<>(); + List thirdPartyResourceRequests = new ArrayList<>(); List blockedResourceRequests = new ArrayList<>(); // Populate the resource array lists. @@ -107,6 +108,14 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi allowedResourceRequests.add(request); break; + case MainWebViewActivity.REQUEST_THIRD_PARTY: + // Add the request to the list of all requests. + allResourceRequests.add(request); + + // Add the request to the list of third-party requests. + thirdPartyResourceRequests.add(request); + break; + case MainWebViewActivity.REQUEST_BLOCKED: // Add the request to the list of all requests. allResourceRequests.add(request); @@ -122,7 +131,10 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi spinnerCursor.addRow(new Object[]{0, getString(R.string.all) + " - " + allResourceRequests.size()}); spinnerCursor.addRow(new Object[]{1, getString(R.string.default_label) + " - " + defaultResourceRequests.size()}); spinnerCursor.addRow(new Object[]{2, getString(R.string.allowed_plural) + " - " + allowedResourceRequests.size()}); - spinnerCursor.addRow(new Object[]{3, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size()}); + if (MainWebViewActivity.blockAllThirdPartyRequests) { + spinnerCursor.addRow(new Object[]{3, getString(R.string.third_party_plural) + " - " + thirdPartyResourceRequests.size()}); + } + spinnerCursor.addRow(new Object[]{4, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size()}); // Create a resource cursor adapter for the spinner. ResourceCursorAdapter spinnerCursorAdapter = new ResourceCursorAdapter(this, R.layout.requests_spinner_item, spinnerCursor, 0) { @@ -147,7 +159,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi appBarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - switch (position) { + switch ((int) id) { case 0: // All requests. // Get an adapter for all the request. ArrayAdapter allResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allResourceRequests); @@ -172,7 +184,15 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi resourceRequestsListView.setAdapter(allowedResourceRequestsArrayAdapter); break; - case 3: // Blocked requests. + case 3: // Third-party requests. + // Get an adapter for the third-party requests. + ArrayAdapter thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), thirdPartyResourceRequests); + + //Display the adapter in the list view. + resourceRequestsListView.setAdapter(thirdPartyResourceRequestsArrayAdapter); + break; + + case 4: // Blocked requests. // Get an adapter fo the blocked requests. ArrayAdapter blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), blockedResourceRequests); diff --git a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java index e0c58cea..62dec5d8 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java +++ b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java @@ -52,7 +52,7 @@ public class RequestsArrayAdapter extends ArrayAdapter { // Get handles for the views. LinearLayout linearLayout = view.findViewById(R.id.request_item_linearlayout); - TextView actionTextView = view.findViewById(R.id.request_item_action); + TextView dispositionTextView = view.findViewById(R.id.request_item_disposition); TextView urlTextView = view.findViewById(R.id.request_item_url); // Get the string array for this entry. @@ -71,7 +71,7 @@ public class RequestsArrayAdapter extends ArrayAdapter { String requestDefault = id + ". " + context.getResources().getString(R.string.allowed); // Set the disposition text. - actionTextView.setText(requestDefault); + dispositionTextView.setText(requestDefault); // Set the background color. linearLayout.setBackgroundColor(context.getResources().getColor(R.color.transparent)); @@ -82,7 +82,7 @@ public class RequestsArrayAdapter extends ArrayAdapter { String requestAllowed = id + ". " + context.getResources().getString(R.string.allowed); // Set the disposition text. - actionTextView.setText(requestAllowed); + dispositionTextView.setText(requestAllowed); // Set the background color. if (MainWebViewActivity.darkTheme) { @@ -92,17 +92,32 @@ public class RequestsArrayAdapter extends ArrayAdapter { } break; + case MainWebViewActivity.REQUEST_THIRD_PARTY: + // Create the disposition string. + String requestThirdParty = id + ". " + context.getResources().getString(R.string.blocked); + + // Set the disposition text. + dispositionTextView.setText(requestThirdParty); + + // Set the background color. + if (MainWebViewActivity.darkTheme) { + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.yellow_700_50)); + } else { + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.yellow_100)); + } + break; + case MainWebViewActivity.REQUEST_BLOCKED: // Create the disposition string. String requestBlocked = id + ". " + context.getResources().getString(R.string.blocked); // Set the disposition text. - actionTextView.setText(requestBlocked); + dispositionTextView.setText(requestBlocked); // Set the background color. if (MainWebViewActivity.darkTheme) { - linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_700_50)); + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_700_40)); } else { linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_100)); } @@ -114,10 +129,10 @@ public class RequestsArrayAdapter extends ArrayAdapter { // Set the text color. For some unexplained reason, `android:textColor="?android:textColorPrimary"` doesn't work in the layout file. Probably some bug relating to array adapters. if (MainWebViewActivity.darkTheme) { - actionTextView.setTextColor(context.getResources().getColor(R.color.gray_200)); + dispositionTextView.setTextColor(context.getResources().getColor(R.color.gray_200)); urlTextView.setTextColor(context.getResources().getColor(R.color.gray_200)); } else { - actionTextView.setTextColor(context.getResources().getColor(R.color.black)); + dispositionTextView.setTextColor(context.getResources().getColor(R.color.black)); urlTextView.setTextColor(context.getResources().getColor(R.color.black)); } diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java index 6969b32c..86b4f953 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java @@ -142,7 +142,7 @@ public class ViewRequestDialog extends AppCompatDialogFragment { alertDialog.show(); // Get handles for the dialog views. - TextView requestAction = alertDialog.findViewById(R.id.request_action); + TextView requestDisposition = alertDialog.findViewById(R.id.request_disposition); TextView requestUrl = alertDialog.findViewById(R.id.request_url); TextView requestBlockListLabel = alertDialog.findViewById(R.id.request_blocklist_label); TextView requestBlockList = alertDialog.findViewById(R.id.request_blocklist); @@ -165,33 +165,45 @@ public class ViewRequestDialog extends AppCompatDialogFragment { switch (Integer.valueOf(requestDetails[MainWebViewActivity.REQUEST_DISPOSITION])) { case MainWebViewActivity.REQUEST_DEFAULT: // Set the text. - requestAction.setText(R.string.default_allowed); + requestDisposition.setText(R.string.default_allowed); // Set the background color. - requestAction.setBackgroundColor(getResources().getColor(R.color.transparent)); + requestDisposition.setBackgroundColor(getResources().getColor(R.color.transparent)); break; case MainWebViewActivity.REQUEST_ALLOWED: // Set the text. - requestAction.setText(R.string.allowed); + requestDisposition.setText(R.string.allowed); // Set the background color. if (MainWebViewActivity.darkTheme) { - requestAction.setBackgroundColor(getResources().getColor(R.color.blue_700_50)); + requestDisposition.setBackgroundColor(getResources().getColor(R.color.blue_700_50)); } else { - requestAction.setBackgroundColor(getResources().getColor(R.color.blue_100)); + requestDisposition.setBackgroundColor(getResources().getColor(R.color.blue_100)); + } + break; + + case MainWebViewActivity.REQUEST_THIRD_PARTY: + // Set the text. + requestDisposition.setText(R.string.third_party_blocked); + + // Set the background color. + if (MainWebViewActivity.darkTheme) { + requestDisposition.setBackgroundColor(getResources().getColor(R.color.yellow_700_50)); + } else { + requestDisposition.setBackgroundColor(getResources().getColor(R.color.yellow_100)); } break; case MainWebViewActivity.REQUEST_BLOCKED: // Set the text. - requestAction.setText(R.string.blocked); + requestDisposition.setText(R.string.blocked); // Set the background color. if (MainWebViewActivity.darkTheme) { - requestAction.setBackgroundColor(getResources().getColor(R.color.red_700_50)); + requestDisposition.setBackgroundColor(getResources().getColor(R.color.red_700_40)); } else { - requestAction.setBackgroundColor(getResources().getColor(R.color.red_100)); + requestDisposition.setBackgroundColor(getResources().getColor(R.color.red_100)); } break; } 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 57048f70..fbc487e9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java @@ -181,8 +181,8 @@ public class AboutTabFragment extends Fragment { SpannableStringBuilder chromeStringBuilder = new SpannableStringBuilder(chromeLabel + chrome); SpannableStringBuilder easyListStringBuilder = new SpannableStringBuilder(easyListLabel + MainWebViewActivity.easyListVersion); SpannableStringBuilder easyPrivacyStringBuilder = new SpannableStringBuilder(easyPrivacyLabel + MainWebViewActivity.easyPrivacyVersion); - SpannableStringBuilder fanboyAnnoyanceStringBuilder = new SpannableStringBuilder(fanboyAnnoyanceLabel + MainWebViewActivity.fanboyAnnoyanceVersion); - SpannableStringBuilder fanboySocialStringBuilder = new SpannableStringBuilder(fanboySocialLabel + MainWebViewActivity.fanboySocialVersion); + SpannableStringBuilder fanboyAnnoyanceStringBuilder = new SpannableStringBuilder(fanboyAnnoyanceLabel + MainWebViewActivity.fanboysAnnoyanceVersion); + SpannableStringBuilder fanboySocialStringBuilder = new SpannableStringBuilder(fanboySocialLabel + MainWebViewActivity.fanboysSocialVersion); // Create the `blueColorSpan` variable. ForegroundColorSpan blueColorSpan; 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 90b999ce..51337fb7 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 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); final TextView userAgentTextView = domainSettingsView.findViewById(R.id.domain_settings_user_agent_textview); final EditText customUserAgentEditText = domainSettingsView.findViewById(R.id.domain_settings_custom_user_agent_edittext); @@ -186,6 +188,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 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)); int swipeToRefreshInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH)); @@ -589,6 +592,29 @@ public class DomainSettingsFragment extends Fragment { } } + // 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. + blockAllThirdPartyRequestsSwitch.setChecked(true); + + // Set the icon according to the theme. + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_dark)); + } else { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_light)); + } + } else { // Blocking all third-party requests is off. + // Turn the switch off. + blockAllThirdPartyRequestsSwitch.setChecked(false); + + // Set the icon according to the theme. + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_dark)); + } else { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_light)); + } + } + // Inflated a WebView to get the default user agent. // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because the bare WebView should not be displayed on the screen. @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false); @@ -1293,6 +1319,26 @@ public class DomainSettingsFragment extends Fragment { } }); + // Set the block all third-party requests switch listener. + blockAllThirdPartyRequestsSwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> { + // Update the icon. + if (isChecked) { // Blocking all third-party requests is on. + // Set the icon according to the theme. + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_dark)); + } else { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_light)); + } + } else { // Blocking all third-party requests is off. + // Set the icon according to the theme. + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_dark)); + } else { + blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_light)); + } + } + }); + // Set the user agent spinner listener. userAgentSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override 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 aac9b0d3..19fa1e3a 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -51,7 +51,7 @@ public class SettingsFragment extends PreferenceFragment { // Initialize savedPreferences. savedPreferences = getPreferenceScreen().getSharedPreferences(); - // Get handles for the preferences we need to modify. + // Get handles for the preferences. final Preference javaScriptPreference = findPreference("javascript_enabled"); final Preference firstPartyCookiesPreference = findPreference("first_party_cookies_enabled"); final Preference thirdPartyCookiesPreference = findPreference("third_party_cookies_enabled"); @@ -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 blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests"); final Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot"); final Preference torHomepagePreference = findPreference("tor_homepage"); final Preference torSearchPreference = findPreference("tor_search"); @@ -423,6 +424,21 @@ public class SettingsFragment extends PreferenceFragment { } } + // Set the block all third-party requests icon. + if (savedPreferences.getBoolean("block_all_third_party_requests", false)) { + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark); + } else { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light); + } + } else { + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark); + } else { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light); + } + } + // Set the Tor icons according to the theme. if (proxyThroughOrbot) { // Proxying is enabled. if (MainWebViewActivity.darkTheme) { @@ -1003,6 +1019,23 @@ public class SettingsFragment extends PreferenceFragment { } break; + case "block_all_third_party_requests": + // Update the icon. + if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) { + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark); + } else { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light); + } + } else { + if (MainWebViewActivity.darkTheme) { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark); + } else { + blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light); + } + } + break; + case "proxy_through_orbot": // Get current settings. boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", 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 2adfb6f7..619537a9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/BlockListHelper.java @@ -1580,24 +1580,14 @@ public class BlockListHelper { return combinedLists; } - public boolean isBlocked(String currentUrl, String resourceUrl, ArrayList> blockList) { + public boolean isBlocked(String currentDomain, String resourceUrl, boolean isThirdPartyRequest, ArrayList> blockList) { // Get the block list name. String BLOCK_LIST_NAME_STRING = blockList.get(0).get(1)[0]; - // Get the current domain. - Uri currentUri = Uri.parse(currentUrl); - String currentDomain = currentUri.getHost(); - - // Get the resource domain. - Uri resourceUri = Uri.parse(resourceUrl); - String resourceDomain = resourceUri.getHost(); - - // Initialize the third-party request tracker. - boolean thirdPartyRequest = false; - - // If one of the domains is `about:blank` it will throw a null object reference on the string comparison. - if ((currentDomain != null) && (resourceDomain != null)) { - thirdPartyRequest = !resourceDomain.equals(currentDomain); + // Assert that currentDomain != null only if this is a third party request. Apparently, lint can't tell that this isn't redundant. + //noinspection RedundantIfStatement + if (isThirdPartyRequest) { + assert currentDomain != null; } // Process the white lists. @@ -1786,7 +1776,7 @@ public class BlockListHelper { } // Only check the third-party white lists if this is a third-party request. - if (thirdPartyRequest) { + if (isThirdPartyRequest) { // Third-party white list. for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_WHITELIST)) { switch (whiteListEntry.length) { @@ -2115,7 +2105,7 @@ public class BlockListHelper { } // Only check the third-party black lists if this is a third-party request. - if (thirdPartyRequest) { + if (isThirdPartyRequest) { // Third-party black list. for (String[] blackListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_BLACKLIST)) { switch (blackListEntry.length) { 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 c495e73e..0c853e56 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 = 6; + private static final int SCHEMA_VERSION = 7; private static final String DOMAINS_DATABASE = "domains.db"; private static final String DOMAINS_TABLE = "domains"; @@ -42,6 +42,7 @@ 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 USER_AGENT = "useragent"; public static final String FONT_SIZE = "fontsize"; @@ -98,6 +99,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { ENABLE_EASYPRIVACY + " BOOLEAN, " + ENABLE_FANBOYS_ANNOYANCE_LIST + " BOOLEAN, " + ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN, " + + BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN, " + USER_AGENT + " TEXT, " + FONT_SIZE + " INTEGER, " + SWIPE_TO_REFRESH + " INTEGER, " + @@ -193,6 +195,11 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { case 5: // Add the swipe to refresh column. domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SWIPE_TO_REFRESH + " INTEGER"); + + // Upgrade from schema version 6. + case 6: + // Add the block all third-party requests column. + domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN"); } } @@ -261,6 +268,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 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. domainContentValues.put(DOMAIN_NAME, domainName); @@ -273,6 +281,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(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests); domainContentValues.put(USER_AGENT, "System default user agent"); domainContentValues.put(FONT_SIZE, 0); domainContentValues.put(SWIPE_TO_REFRESH, 0); @@ -294,7 +303,7 @@ 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, - String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages, boolean pinnedSslCertificate) { + 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(); @@ -310,6 +319,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(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests); domainContentValues.put(USER_AGENT, userAgent); domainContentValues.put(FONT_SIZE, fontSize); domainContentValues.put(SWIPE_TO_REFRESH, swipeToRefresh); @@ -328,10 +338,10 @@ 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, 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 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) { // Store the domain data in a `ContentValues`. ContentValues domainContentValues = new ContentValues(); @@ -347,6 +357,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(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests); domainContentValues.put(USER_AGENT, userAgent); domainContentValues.put(FONT_SIZE, fontSize); domainContentValues.put(SWIPE_TO_REFRESH, swipeToRefresh); diff --git a/app/src/main/res/drawable/allow_screenshots_disabled_dark.xml b/app/src/main/res/drawable/allow_screenshots_disabled_dark.xml index 33234b98..b320afb2 100644 --- a/app/src/main/res/drawable/allow_screenshots_disabled_dark.xml +++ b/app/src/main/res/drawable/allow_screenshots_disabled_dark.xml @@ -1,9 +1,10 @@ - + - + - + - + + + + + + diff --git a/app/src/main/res/drawable/block_all_third_party_requests_disabled_light.xml b/app/src/main/res/drawable/block_all_third_party_requests_disabled_light.xml new file mode 100644 index 00000000..21db2f97 --- /dev/null +++ b/app/src/main/res/drawable/block_all_third_party_requests_disabled_light.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/drawable/block_all_third_party_requests_enabled_dark.xml b/app/src/main/res/drawable/block_all_third_party_requests_enabled_dark.xml new file mode 100644 index 00000000..c5b66784 --- /dev/null +++ b/app/src/main/res/drawable/block_all_third_party_requests_enabled_dark.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/drawable/block_all_third_party_requests_enabled_light.xml b/app/src/main/res/drawable/block_all_third_party_requests_enabled_light.xml new file mode 100644 index 00000000..2dda9112 --- /dev/null +++ b/app/src/main/res/drawable/block_all_third_party_requests_enabled_light.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/layout/domain_settings_fragment.xml b/app/src/main/res/layout/domain_settings_fragment.xml index 64d3747f..da292457 100644 --- a/app/src/main/res/layout/domain_settings_fragment.xml +++ b/app/src/main/res/layout/domain_settings_fragment.xml @@ -294,7 +294,7 @@ android:layout_marginStart="8dp" android:layout_marginTop="14dp" android:layout_marginBottom="14dp" - android:text="@string/fanboy_annoyance_list" + android:text="@string/fanboys_annoyance_list" android:textColor="?android:textColorPrimary" android:textSize="18sp" /> @@ -321,7 +321,34 @@ android:layout_marginStart="8dp" android:layout_marginTop="14dp" android:layout_marginBottom="14dp" - android:text="@string/fanboy_social_blocking_list" + android:text="@string/fanboys_social_blocking_list" + android:textColor="?android:textColorPrimary" + android:textSize="18sp" /> + + + + + + + + diff --git a/app/src/main/res/layout/requests_item_linearlayout.xml b/app/src/main/res/layout/requests_item_linearlayout.xml index 33d48cbf..b0489d74 100644 --- a/app/src/main/res/layout/requests_item_linearlayout.xml +++ b/app/src/main/res/layout/requests_item_linearlayout.xml @@ -26,7 +26,7 @@ android:orientation="horizontal"> + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 8c17b837..d2ce68b7 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -72,7 +72,7 @@ #FFEF9A9A #FFE53935 #FFD32F2F - #55D32F2F + #55D32F2F #FFC62828 #FFB71C1C #FFD50000 @@ -81,6 +81,8 @@ #FFFFFFFF + #FFFFF9C4 + #88FBC02D #FFF57F17 #FFFFD600 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5bbcecbc..23efb274 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -133,6 +133,7 @@ Clear Form Data Fanboy’s Annoyance List Fanboy’s Social Blocking List + Block All Third-Party Requests Layout Font Size 25% @@ -233,6 +234,8 @@ Default - Allowed Allowed Allowed + Third-party + Third-party - Blocked Blocked Blocked Blocklist @@ -389,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. + Block all third-party requests + Blocking all third-party requests increases privacy, but it breaks many websites. Tor Proxy through Orbot Proxy all web traffic through Orbot on localhost:8118. diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index c3687d0c..4549040a 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -115,6 +115,12 @@ android:title="@string/fanboys_social_blocking_list" android:summary="@string/fanboys_social_blocking_list_summary" android:defaultValue="true" /> + +