Add an option to block all third-party requests. https://redmine.stoutner.com/issues/209
authorSoren Stoutner <soren@stoutner.com>
Wed, 18 Jul 2018 23:05:23 +0000 (16:05 -0700)
committerSoren Stoutner <soren@stoutner.com>
Wed, 18 Jul 2018 23:05:23 +0000 (16:05 -0700)
38 files changed:
.idea/assetWizardSettings.xml
app/src/main/assets/de/about_licenses_dark.html
app/src/main/assets/de/about_licenses_light.html
app/src/main/assets/en/about_licenses_dark.html
app/src/main/assets/en/about_licenses_light.html
app/src/main/assets/es/about_licenses_dark.html
app/src/main/assets/es/about_licenses_light.html
app/src/main/assets/it/about_licenses_dark.html
app/src/main/assets/it/about_licenses_light.html
app/src/main/assets/ru/about_licenses_dark.html
app/src/main/assets/ru/about_licenses_light.html
app/src/main/assets/shared_images/new_releases_dark.png [new file with mode: 0644]
app/src/main/assets/shared_images/new_releases_light.png [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/activities/RequestsActivity.java
app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.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/drawable/allow_screenshots_disabled_dark.xml
app/src/main/res/drawable/allow_screenshots_disabled_light.xml
app/src/main/res/drawable/allow_screenshots_enabled_dark.xml
app/src/main/res/drawable/allow_screenshots_enabled_light.xml
app/src/main/res/drawable/block_all_third_party_requests_disabled_dark.xml [new file with mode: 0644]
app/src/main/res/drawable/block_all_third_party_requests_disabled_light.xml [new file with mode: 0644]
app/src/main/res/drawable/block_all_third_party_requests_enabled_dark.xml [new file with mode: 0644]
app/src/main/res/drawable/block_all_third_party_requests_enabled_light.xml [new file with mode: 0644]
app/src/main/res/layout/domain_settings_fragment.xml
app/src/main/res/layout/requests_item_linearlayout.xml
app/src/main/res/layout/view_request_dialog.xml
app/src/main/res/menu/webview_options_menu.xml
app/src/main/res/values/colors.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences.xml

index 02141c9f6d3a096f3a68d81d925d867f86a760f5..6e3671ed2cefed64d6580f0167242e6d45daf7f5 100644 (file)
@@ -68,7 +68,7 @@
                                 <PersistentState>
                                   <option name="values">
                                     <map>
-                                      <entry key="url" value="jar:file:/home/soren/Android/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_camera_enhance_black_24dp.xml" />
+                                      <entry key="url" value="jar:file:/home/soren/Android/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/av/ic_new_releases_black_24dp.xml" />
                                     </map>
                                   </option>
                                 </PersistentState>
@@ -78,7 +78,7 @@
                         </option>
                         <option name="values">
                           <map>
-                            <entry key="outputName" value="allow_screenshots_enabled_dark" />
+                            <entry key="outputName" value="block_all_third_party_requests_enabled_light" />
                             <entry key="sourceFile" value="$USER_HOME$" />
                           </map>
                         </option>
index 165f8f98c417bc34321f5f814489e5f3f656f870..c83a136841d6c2730a6725c9a4ae4a75b49d1992 100644 (file)
         <p><img class="icon" src="../shared_images/lock_dark.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_dark.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_dark.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_dark.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_dark.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_dark.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_dark.png"> search.</p>
index f242dc07aa9e90ff44db32a61f45ac9d7648d490..7b5b0cb42858a6e131fd33780c4744da2e695a32 100644 (file)
         <p><img class="icon" src="../shared_images/lock_light.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_light.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_light.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_light.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_light.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_light.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_light.png"> search.</p>
index 3bddeab5c361d8b20659f8aca06885bea50264e4..56d6b1c18bdd9fed604e639d3de4bd8b8404d494 100644 (file)
         <p><img class="icon" src="../shared_images/lock_dark.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_dark.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_dark.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_dark.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_dark.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_dark.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_dark.png"> search.</p>
index 49397f98ebc56e5481bb38ce89f24eb5be9eb273..e4be1e11fda94eb66be44d13e30acfef6255d9c6 100644 (file)
         <p><img class="icon" src="../shared_images/lock_light.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_light.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_light.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_light.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_light.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_light.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_light.png"> search.</p>
index c7ae72283a0e780b4d74368adba13e15e64c3bb3..db1fdcefe82aeb0a733b60a75ec6557addc0510f 100644 (file)
         <p><img class="icon" src="../shared_images/lock_dark.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_dark.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_dark.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_dark.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_dark.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_dark.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_dark.png"> search.</p>
index 6d1fb8ba242a12667e29544a1bed1c73dd51a419..e21b26f0a52ef6dbf333dde4e0cb8e4f6e4ea7f5 100644 (file)
         <p><img class="icon" src="../shared_images/lock_light.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_light.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_light.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_light.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_light.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_light.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_light.png"> search.</p>
index f0fd34f476eebe52774c573c6031d3d84f852a99..8b51ffeaebc1a148ee51719e762b776a712fcb8b 100644 (file)
         <p><img class="icon" src="../shared_images/lock_dark.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_dark.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_dark.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_dark.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_dark.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_dark.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_dark.png"> search.</p>
index 82dea778960cfc57847426cf4d00d10cf4e3c55d..5e08538838ddb34509645aa93391abc72d221b44 100644 (file)
         <p><img class="icon" src="../shared_images/lock_light.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_light.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_light.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_light.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_light.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_light.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_light.png"> search.</p>
index e18c1e1fa38f7ab43d0eecfc80e8d25884ffb2ac..9a0806f8c0fd9359ebe3c1142d449b651f8eede7 100644 (file)
         <p><img class="icon" src="../shared_images/lock_dark.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_dark.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_dark.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_dark.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_dark.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_dark.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_dark.png"> search.</p>
index b337dfdd7354fcf902c40899ec26c8e6530ebd84..4b5ed099e4bcbe3837d1a2ec5e0c7ca90875ac40 100644 (file)
         <p><img class="icon" src="../shared_images/lock_light.png"> lock.</p>
         <p><img class="icon" src="../shared_images/map_light.png"> map.</p>
         <p><img class="icon" src="../shared_images/more_light.png"> more.</p>
+        <p><img class="icon" src="../shared_images/new_releases_light.png"> new releases.</p>
         <p><img class="icon" src="../shared_images/question_answer_light.png"> question_answer.</p>
         <p><img class="icon" src="../shared_images/refresh_light.png"> refresh.</p>
         <p><img class="icon" src="../shared_images/search_light.png"> search.</p>
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 (file)
index 0000000..b918a63
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 (file)
index 0000000..56570d6
Binary files /dev/null and b/app/src/main/assets/shared_images/new_releases_light.png differ
index f0a3a0a1d64ace6ed68c627ebff8f6b001d1c1b7..7f7e995cff6798349f9054c82da686fb4cd85194 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 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);
         }
     }
 
index 07126c9881fd045ea0aedc4fd826231b8a3c521d..491763787976d5bb006d17563341745d5c0a50a3 100644 (file)
@@ -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<String[]> 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<List<String[]>> easyList = blockListHelper.parseBlockList(getAssets(), "blocklists/easylist.txt");
         final ArrayList<List<String[]>> easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt");
-        final ArrayList<List<String[]>> fanboyAnnoyance = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-annoyance.txt");
-        final ArrayList<List<String[]>> fanboySocial = blockListHelper.parseBlockList(getAssets(), "blocklists/fanboy-social.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");
 
         // 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) {
index dcf641298e1204bfddafbd5b70864229edbc1fbc..4b58053ac823fc94298e2957c44693ffeeb3ce99 100644 (file)
@@ -86,6 +86,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi
         List<String[]> allResourceRequests = new ArrayList<>();
         List<String[]> defaultResourceRequests = new ArrayList<>();
         List<String[]> allowedResourceRequests = new ArrayList<>();
+        List<String[]> thirdPartyResourceRequests = new ArrayList<>();
         List<String[]> 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<String[]> 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<String[]> 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<String[]> blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), blockedResourceRequests);
 
index e0c58cea85e79b8870fd5297e01b6a767b793011..62dec5d884505146c5beff8b0ba785dc4e4d3748 100644 (file)
@@ -52,7 +52,7 @@ public class RequestsArrayAdapter extends ArrayAdapter<String[]> {
 
         // 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[]> {
                 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[]> {
                 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<String[]> {
                 }
                 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<String[]> {
 
         // 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));
         }
 
index 6969b32c4e6cb02ec562b0193008479247678ca9..86b4f95349c099eaf1e5c5e3a84210119bea1214 100644 (file)
@@ -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;
         }
index 57048f7017d066c76aaa18d4dd578407ef31b063..fbc487e9176c8ff75daaca08376398bfbe4f2ef9 100644 (file)
@@ -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;
index 90b999ceddc0c9b77c4be964daacc589acb8682a..51337fb79ed7e378e13b1b502e216d674b83339c 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 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
index aac9b0d357a73f5ea5f1a473b3a8df1b23971926..19fa1e3a9190a9fdff4a581537ca1a1c20df8bd6 100644 (file)
@@ -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);
index 2adfb6f7bd5f7e771c2828387205573288d43d84..619537a989e3c71afd71ebeb90bf70e9e90f833c 100644 (file)
@@ -1580,24 +1580,14 @@ public class BlockListHelper {
         return combinedLists;
     }
 
-    public boolean isBlocked(String currentUrl, String resourceUrl, ArrayList<List<String[]>> blockList) {
+    public boolean isBlocked(String currentDomain, String resourceUrl, boolean isThirdPartyRequest, ArrayList<List<String[]>> 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) {
index c495e73ed79a06ce700792ec213a2c9243464307..0c853e56ab3e390fed40f784a70dc7970a4f1830 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 = 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);
index 33234b9804a4a7c5f13dee110410a7c6d7a7d230..b320afb23995d6f6446a6d680936e00566986029 100644 (file)
@@ -1,9 +1,10 @@
 <!-- `allow_screenshots_enabled_dark.xml` comes from the Android Material icon set, where it is called `camera_enhance`.  It is released under the Apache License 2.0. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="24dp"
-        android:width="24dp"
-        android:viewportHeight="24.0"
-        android:viewportWidth="24.0" >
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
 
     <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
     <path
index 5999604bfe093955c1f195d8acfda0f7612aac95..67ff615fab0df4ecb8cb53856e4c3b7cc6a1bd8e 100644 (file)
@@ -1,9 +1,10 @@
 <!-- `allow_screenshots_enabled_dark.xml` comes from the Android Material icon set, where it is called `camera_enhance`.  It is released under the Apache License 2.0. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="24dp"
-        android:width="24dp"
-        android:viewportHeight="24.0"
-        android:viewportWidth="24.0" >
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
 
     <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
     <path
index 61556c09874758750f9141fa8c96c94727c95a7b..d4310c66f9eb1c12bfb6e465de58c98b3841dcad 100644 (file)
@@ -1,9 +1,10 @@
 <!-- `allow_screenshots_enabled_dark.xml` comes from the Android Material icon set, where it is called `camera_enhance`.  It is released under the Apache License 2.0. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="24dp"
-        android:width="24dp"
-        android:viewportHeight="24.0"
-        android:viewportWidth="24.0" >
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
 
     <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
     <path
index ee605af550fd892b0dc7c8389ed3962bc42a7987..4e481be337175de7875a85db0d17525108a31fc5 100644 (file)
@@ -1,9 +1,10 @@
 <!-- `allow_screenshots_enabled_dark.xml` comes from the Android Material icon set, where it is called `camera_enhance`.  It is released under the Apache License 2.0. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="24dp"
-        android:width="24dp"
-        android:viewportHeight="24.0"
-        android:viewportWidth="24.0" >
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
 
     <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
     <path
diff --git a/app/src/main/res/drawable/block_all_third_party_requests_disabled_dark.xml b/app/src/main/res/drawable/block_all_third_party_requests_disabled_dark.xml
new file mode 100644 (file)
index 0000000..7112e75
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- `block_all_third_party_requests_disabled_dark.xml` comes from the Android Material icon set, where it is called `new_releases`.  It is released under the Apache License 2.0. -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
+
+    <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
+    <path
+        android:fillColor="#FF9E9E9E"
+        android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
+</vector>
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 (file)
index 0000000..21db2f9
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- `block_all_third_party_requests_disabled_light.xml` comes from the Android Material icon set, where it is called `new_releases`.  It is released under the Apache License 2.0. -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
+
+    <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
+    <path
+        android:fillColor="#FF757575"
+        android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
+</vector>
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 (file)
index 0000000..c5b6678
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- `block_all_third_party_requests_enabled_dark.xml` comes from the Android Material icon set, where it is called `new_releases`.  It is released under the Apache License 2.0. -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
+
+    <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
+    <path
+        android:fillColor="#FF1E88E5"
+        android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
+</vector>
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 (file)
index 0000000..2dda911
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- `block_all_third_party_requests_enabled_light.xml` comes from the Android Material icon set, where it is called `new_releases`.  It is released under the Apache License 2.0. -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0" >
+
+    <!-- A hard coded color must be used until API >= 21.  Then `@color` may be used. -->
+    <path
+        android:fillColor="#FF1565C0"
+        android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
+</vector>
index 64d3747f009c5ae759b7c2a8bd9c067a3e5a78ff..da29245722e70e174f0a3b177617a14774b54aae 100644 (file)
                 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" />
         </LinearLayout>
                 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" />
+        </LinearLayout>
+
+        <!-- Block All Third Party Requests. -->
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:orientation="horizontal" >
+
+            <ImageView
+                android:id="@+id/domain_settings_block_all_third_party_requests_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_block_all_third_party_requests_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/block_all_third_party_requests"
                 android:textColor="?android:textColorPrimary"
                 android:textSize="18sp" />
         </LinearLayout>
index 33d48cbf5d5cf881add5e784b84e89df889e835f..b0489d74ea6b7ba65bf978b29db9a58ada0a2f23 100644 (file)
@@ -26,7 +26,7 @@
     android:orientation="horizontal">
 
     <TextView
-        android:id="@+id/request_item_action"
+        android:id="@+id/request_item_disposition"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_margin="10dp"
index c42b88349ec44407bc3cce12307ccade8af976e8..e530007c5688a15851311ec5c35827ae182253f4 100644 (file)
@@ -40,7 +40,7 @@
             android:layout_marginTop="5dp" />
 
         <TextView
-            android:id="@+id/request_action"
+            android:id="@+id/request_disposition"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:textSize="16sp"
index 862539e0565850f2f760bcd6108052f89baf56f5..28e0cfe3917e6caf066f6d780f33cbd27d4d37ba 100644 (file)
                 android:orderInCategory="840"
                 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:checkable="true"
+                app:showAsAction="never" />
         </menu>
     </item>
 
index 8c17b8378d0aa0d5259e85f521e8018e530e5f6c..d2ce68b7ceef94597bdfcc28bf53f0fec7ba252b 100644 (file)
@@ -72,7 +72,7 @@
     <color name="red_200">#FFEF9A9A</color>
     <color name="red_600">#FFE53935</color>
     <color name="red_700">#FFD32F2F</color>
-    <color name="red_700_50">#55D32F2F</color>
+    <color name="red_700_40">#55D32F2F</color>
     <color name="red_800">#FFC62828</color>
     <color name="red_900">#FFB71C1C</color>
     <color name="red_a700">#FFD50000</color>
@@ -81,6 +81,8 @@
 
     <color name="white">#FFFFFFFF</color>
 
+    <color name="yellow_100">#FFFFF9C4</color>
+    <color name="yellow_700_50">#88FBC02D</color>
     <color name="yellow_900">#FFF57F17</color>
     <color name="yellow_a700">#FFFFD600</color>
 </resources>
\ No newline at end of file
index 5bbcecbc7c633538ff3a28f44ee8ea575e3bdc53..23efb2740e7203a1b01ecb043fb10c283b014061 100644 (file)
         <string name="clear_form_data">Clear Form Data</string>
     <string name="options_fanboys_annoyance_list">Fanboy’s Annoyance List</string>
     <string name="options_fanboys_social_blocking_list">Fanboy’s Social Blocking List</string>
+    <string name="options_block_all_third_party_requests">Block All Third-Party Requests</string>
     <string name="layout">Layout</string>
         <string name="font_size">Font Size</string>
             <string name="twenty_five_percent">25%</string>
         <string name="default_allowed">Default - Allowed</string>
         <string name="allowed">Allowed</string>
         <string name="allowed_plural">Allowed</string>
+        <string name="third_party_plural">Third-party</string>
+        <string name="third_party_blocked">Third-party - Blocked</string>
         <string name="blocked">Blocked</string>
         <string name="blocked_plural">Blocked</string>
     <string name="blocklist">Blocklist</string>
         <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="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="proxy_through_orbot">Proxy through Orbot</string>
         <string name="proxy_through_orbot_summary">Proxy all web traffic through Orbot on localhost:8118.</string>
index c3687d0c1555e4c686d68976e878b5316f6d2f4b..4549040a27a32f1bd34a79ec3c87ad36d627e797 100644 (file)
             android:title="@string/fanboys_social_blocking_list"
             android:summary="@string/fanboys_social_blocking_list_summary"
             android:defaultValue="true" />
+
+        <SwitchPreference
+            android:key="block_all_third_party_requests"
+            android:title="@string/block_all_third_party_requests"
+            android:summary="@string/block_all_third_party_requests_summary"
+            android:defaultValue="false" />
     </PreferenceCategory>
 
     <PreferenceCategory