+ } else if (url.startsWith("tel:")) { // Load the phone number in the dialer.
+ // Open the dialer and load the phone number, but wait for the user to place the call.
+ Intent dialIntent = new Intent(Intent.ACTION_DIAL);
+
+ // Add the phone number to the intent.
+ dialIntent.setData(Uri.parse(url));
+
+ // Open the dialer in a new task instead of as part of Privacy Browser.
+ dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Make it so.
+ startActivity(dialIntent);
+
+ // Returning true indicates Privacy Browser is handling the URL by creating an intent.
+ return true;
+ } else { // Load a system chooser to select an app that can handle the URL.
+ // Open an app that can handle the URL.
+ Intent genericIntent = new Intent(Intent.ACTION_VIEW);
+
+ // Add the URL to the intent.
+ genericIntent.setData(Uri.parse(url));
+
+ // List all apps that can handle the URL instead of just opening the first one.
+ genericIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+
+ // Open the app in a new task instead of as part of Privacy Browser.
+ genericIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Start the app or display a snackbar if no app is available to handle the URL.
+ try {
+ startActivity(genericIntent);
+ } catch (ActivityNotFoundException exception) {
+ Snackbar.make(mainWebView, getString(R.string.unrecognized_url) + " " + url, Snackbar.LENGTH_SHORT).show();
+ }
+
+ // Returning true indicates Privacy Browser is handling the URL by creating an intent.
+ return true;
+ }
+ }
+
+ // Check requests against the block lists. The deprecated `shouldInterceptRequest()` must be used until minimum API >= 21.
+ @SuppressWarnings("deprecation")
+ @Override
+ public WebResourceResponse shouldInterceptRequest(WebView view, String url){
+ // Create an empty web resource response to be used if the resource request is blocked.
+ WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes()));
+
+ // Reset the whitelist results tracker.
+ whiteListResultStringArray = null;
+
+ // Initialize the third party request tracker.
+ boolean isThirdPartyRequest = false;
+
+ // Initialize the current domain string.
+ 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) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ thirdPartyBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blockAllThirdPartyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
+ });
+
+ // 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 UltraPrivacy if it is enabled.
+ if (ultraPrivacyEnabled) {
+ if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, ultraPrivacy)) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ ultraPrivacyBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy));
+ });
+
+ // The resource request was blocked. Return an empty web resource response.
+ return emptyWebResourceResponse;
+ }
+
+ // If the whitelist result is not null, the request has been allowed by UltraPrivacy.
+ if (whiteListResultStringArray != null) {
+ // Add a whitelist entry to the resource requests array.
+ resourceRequests.add(whiteListResultStringArray);
+
+ // The resource request has been allowed by UltraPrivacy. `return null` loads the requested resource.
+ return null;
+ }
+ }
+
+ // Check EasyList if it is enabled.
+ if (easyListEnabled) {
+ if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyList)) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ easyListBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ easyListMenuItem.setTitle(easyListBlockedRequests + " - " + getString(R.string.easylist));
+ });
+
+ // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition).
+ whiteListResultStringArray = null;
+
+ // The resource request was blocked. Return an empty web resource response.
+ return emptyWebResourceResponse;
+ }
+ }
+
+ // Check EasyPrivacy if it is enabled.
+ if (easyPrivacyEnabled) {
+ if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyPrivacy)) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ easyPrivacyBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ easyPrivacyMenuItem.setTitle(easyPrivacyBlockedRequests + " - " + getString(R.string.easyprivacy));
+ });
+
+ // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition).
+ whiteListResultStringArray = null;
+
+ // 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(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList)) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ fanboysAnnoyanceListBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ fanboysAnnoyanceListMenuItem.setTitle(fanboysAnnoyanceListBlockedRequests + " - " + getString(R.string.fanboys_annoyance_list));
+ });
+
+ // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition).
+ whiteListResultStringArray = null;
+
+ // 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(currentDomain, url, isThirdPartyRequest, fanboysSocialList)) {
+ // Increment the blocked requests counters.
+ blockedRequests++;
+ fanboysSocialBlockingListBlockedRequests++;
+
+ // Update the titles of the blocklist menu items. This must be run from the UI thread.
+ activity.runOnUiThread(() -> {
+ navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
+ fanboysSocialBlockingListMenuItem.setTitle(fanboysSocialBlockingListBlockedRequests + " - " + getString(R.string.fanboys_social_blocking_list));
+ });
+
+ // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition).
+ whiteListResultStringArray = null;
+
+ // The resource request was blocked. Return an empty web resource response.
+ return emptyWebResourceResponse;
+ }
+ }