<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>
</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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
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);
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();
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;
// 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);
}
}
// 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;
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;
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;
// 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.
// 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.
// 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;
}
// 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;
}
// 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.
// 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)) {
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);
easyPrivacyMenuItem.setChecked(easyPrivacyEnabled);
fanboysAnnoyanceListMenuItem.setChecked(fanboysAnnoyanceListEnabled);
fanboysSocialBlockingListMenuItem.setChecked(fanboysSocialBlockingListEnabled);
+ blockAllThirdParyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically());
// 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();
}
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.
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));
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) {
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.
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);
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) {
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);
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);
// 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.
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));
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) {
}
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));
}
// 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));
}
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);
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;
}
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;
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);
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));
}
}
+ // 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);
}
});
+ // 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
// 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");
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");
}
}
+ // 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) {
}
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);
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.
}
// 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) {
}
// 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) {
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";
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";
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, " +
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");
}
}
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);
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);
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();
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);
}
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();
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);
<!-- `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
<!-- `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
<!-- `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
<!-- `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
--- /dev/null
+<!-- `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>
--- /dev/null
+<!-- `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>
--- /dev/null
+<!-- `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>
--- /dev/null
+<!-- `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>
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>
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"
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"
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>
<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>
<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
<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>
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