X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=e6ec1b71cebebd8dc39c490b79c1ba37d50cb656;hp=041b6d2a1142414bbb0dffd0da37e9f9ee9396d9;hb=3d167d1ec7d0cef1ef032f20859bb0de8ddb01cf;hpb=0cc9b798d6daa99959e33ff94a707516d6db8122 diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 041b6d2a..e6ec1b71 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -102,30 +102,31 @@ import androidx.core.content.ContextCompat; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.viewpager.widget.ViewPager; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.navigation.NavigationView; import com.google.android.material.snackbar.Snackbar; - import com.google.android.material.tabs.TabLayout; + import com.stoutner.privacybrowser.BuildConfig; import com.stoutner.privacybrowser.R; +import com.stoutner.privacybrowser.adapters.WebViewPagerAdapter; import com.stoutner.privacybrowser.asynctasks.GetHostIpAddresses; import com.stoutner.privacybrowser.dialogs.AdConsentDialog; import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog; import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog; import com.stoutner.privacybrowser.dialogs.CreateHomeScreenShortcutDialog; +import com.stoutner.privacybrowser.dialogs.DownloadFileDialog; import com.stoutner.privacybrowser.dialogs.DownloadImageDialog; import com.stoutner.privacybrowser.dialogs.DownloadLocationPermissionDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog; import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog; import com.stoutner.privacybrowser.dialogs.HttpAuthenticationDialog; import com.stoutner.privacybrowser.dialogs.PinnedMismatchDialog; +import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog; import com.stoutner.privacybrowser.dialogs.UrlHistoryDialog; import com.stoutner.privacybrowser.dialogs.ViewSslCertificateDialog; import com.stoutner.privacybrowser.fragments.WebViewTabFragment; @@ -134,8 +135,6 @@ import com.stoutner.privacybrowser.helpers.BlockListHelper; import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; import com.stoutner.privacybrowser.helpers.OrbotProxyHelper; -import com.stoutner.privacybrowser.dialogs.DownloadFileDialog; -import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog; import com.stoutner.privacybrowser.views.NestedScrollWebView; import java.io.ByteArrayInputStream; @@ -151,7 +150,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -168,16 +166,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `allowScreenshots` is public static so it can be accessed from everywhere. It is also used in `onCreate()`. public static boolean allowScreenshots; - // `favoriteIconBitmap` is public static so it can be accessed from `CreateHomeScreenShortcutDialog`, `BookmarksActivity`, `BookmarksDatabaseViewActivity`, `CreateBookmarkDialog`, - // `CreateBookmarkFolderDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `EditBookmarkDatabaseViewDialog`, and `ViewSslCertificateDialog`. It is also used in `onCreate()`, - // `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onCreateHomeScreenShortcut()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `applyDomainSettings()`. + // `favoriteIconBitmap` is public static so it can be accessed from `BookmarksActivity`, `BookmarksDatabaseViewActivity`, `CreateBookmarkFolderDialog`, + // `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `EditBookmarkDatabaseViewDialog`, and `ViewSslCertificateDialog`. It is also used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, + // `onCreateHomeScreenShortcut()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `applyDomainSettings()`. public static Bitmap favoriteIconBitmap; // `favoriteIconDefaultBitmap` public static so it can be accessed from `PinnedMismatchDialog`. It is also used in `onCreate()` and `applyDomainSettings`. public static Bitmap favoriteIconDefaultBitmap; - // `formattedUrlString` is public static so it can be accessed from `AddDomainDialog`, `BookmarksActivity`, `DomainSettingsFragment`, `CreateBookmarkDialog`, - // and `PinnedMismatchDialog`. + // `formattedUrlString` is public static so it can be accessed from `AddDomainDialog`, `BookmarksActivity`, `DomainSettingsFragment`, and `PinnedMismatchDialog`. // It is also used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onCreateHomeScreenShortcutCreate()`, `loadUrlFromTextBox()`, and `applyProxyThroughOrbot()`. public static String formattedUrlString; @@ -199,9 +196,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxyThroughOrbot()`. public static String orbotStatus; - // `webViewTitle` is public static so it can be accessed from `CreateBookmarkDialog`. It is also used in `onCreate()`. - public static String webViewTitle; - // `appliedUserAgentString` is public static so it can be accessed from `ViewSourceActivity`. It is also used in `applyDomainSettings()`. public static String appliedUserAgentString; @@ -214,60 +208,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `restartFromBookmarksActivity` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onRestart()`. public static boolean restartFromBookmarksActivity; - // The block list versions are public static so they can be accessed from `AboutTabFragment`. They are also used in `onCreate()`. + // The blocklist 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 fanboysAnnoyanceVersion; public static String fanboysSocialVersion; public static String ultraPrivacyVersion; - // The request items are public static so they can be accessed by `BlockListHelper`, `RequestsArrayAdapter`, and `ViewRequestsDialog`. They are also used in `onCreate()` and `onPrepareOptionsMenu()`. - public static List resourceRequests; - public static String[] whiteListResultStringArray; - private int blockedRequests; - private int easyListBlockedRequests; - private int easyPrivacyBlockedRequests; - private int fanboysAnnoyanceListBlockedRequests; - private int fanboysSocialBlockingListBlockedRequests; - private int ultraPrivacyBlockedRequests; - private int thirdPartyBlockedRequests; - - public final static int REQUEST_DISPOSITION = 0; - public final static int REQUEST_URL = 1; - public final static int REQUEST_BLOCKLIST = 2; - public final static int REQUEST_SUBLIST = 3; - public final static int REQUEST_BLOCKLIST_ENTRIES = 4; - public final static int REQUEST_BLOCKLIST_ORIGINAL_ENTRY = 5; - - public final static int REQUEST_DEFAULT = 0; - public final static int REQUEST_ALLOWED = 1; - 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 DOMAIN_WHITELIST = 3; - public final static int DOMAIN_INITIAL_WHITELIST = 4; - public final static int DOMAIN_FINAL_WHITELIST = 5; - public final static int THIRD_PARTY_WHITELIST = 6; - public final static int THIRD_PARTY_DOMAIN_WHITELIST = 7; - public final static int THIRD_PARTY_DOMAIN_INITIAL_WHITELIST = 8; - - public final static int MAIN_BLACKLIST = 9; - public final static int INITIAL_BLACKLIST = 10; - public final static int FINAL_BLACKLIST = 11; - public final static int DOMAIN_BLACKLIST = 12; - public final static int DOMAIN_INITIAL_BLACKLIST = 13; - public final static int DOMAIN_FINAL_BLACKLIST = 14; - public final static int DOMAIN_REGULAR_EXPRESSION_BLACKLIST = 15; - public final static int THIRD_PARTY_BLACKLIST = 16; - public final static int THIRD_PARTY_INITIAL_BLACKLIST = 17; - public final static int THIRD_PARTY_DOMAIN_BLACKLIST = 18; - public final static int THIRD_PARTY_DOMAIN_INITIAL_BLACKLIST = 19; - public final static int THIRD_PARTY_REGULAR_EXPRESSION_BLACKLIST = 20; - 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; @@ -557,7 +504,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // This is needed to get rid of the Android Studio warning that the action bar might be null. assert actionBar != null; - // Add the custom `url_app_bar` layout, which shows the favorite icon and the URL text bar. + // Add the custom layout, which shows the URL text bar. actionBar.setCustomView(R.layout.url_app_bar); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); @@ -632,9 +579,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Instantiate the block list helper. blockListHelper = new BlockListHelper(); - // Initialize the list of resource requests. - resourceRequests = new ArrayList<>(); - // Parse the block lists. easyList = blockListHelper.parseBlockList(getAssets(), "blocklists/easylist.txt"); easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt"); @@ -692,15 +636,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onPageSelected(int position) { - // TODO. Consider using an array of the WebViews. - // Get the current WebView fragment. Instantiate item returns the current item if it already exists. - Fragment webViewFragment = (Fragment) webViewPagerAdapter.instantiateItem(webViewPager, position); + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(position); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); - // Remove the lint error below that the WebView fragment might be null. - assert webViewFragment.getView() != null; + // Remove the incorrect lint warning below that the fragment view might be null. + assert fragmentView != null; // Store the current WebView. - currentWebView = webViewFragment.getView().findViewById(R.id.nestedscroll_webview); + currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview); // Store the current formatted URL string. formattedUrlString = currentWebView.getUrl(); @@ -711,7 +657,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the soft keyboard. inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); - // Apply the current URL in the URL text box. + // Display the current URL in the URL text box. urlEditText.setText(formattedUrlString); // Highlight the URL text. @@ -771,8 +717,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }); - // Add the first tab. - webViewPagerAdapter.addPage(); + // Add the first tab. (It doesn't matter what view is passed. That is just required as part of the ImageView `onClick()` syntax). + addTab(webViewPager); // Set the bookmarks drawer resources according to the theme. This can't be done in the layout due to compatibility issues with the `DrawerLayout` support widget. if (darkTheme) { @@ -789,6 +735,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the launch bookmarks activity FAB to launch the bookmarks activity. launchBookmarksActivityFab.setOnClickListener(v -> { + // Store the current WebView url and title in the bookmarks activity. + BookmarksActivity.currentWebViewUrl = currentWebView.getUrl(); + BookmarksActivity.currentWebViewTitle = currentWebView.getTitle(); + // Create an intent to launch the bookmarks activity. Intent bookmarksIntent = new Intent(getApplicationContext(), BookmarksActivity.class); @@ -808,8 +758,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the create new bookmark FAB to display an alert dialog. createBookmarkFab.setOnClickListener(view -> { - // Show the create bookmark dialog and name the instance `@string/create_bookmark`. - DialogFragment createBookmarkDialog = new CreateBookmarkDialog(); + // Instantiate the create bookmark dialog. + DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), favoriteIconBitmap); + + // Display the create bookmark dialog. createBookmarkDialog.show(fragmentManager, resources.getString(R.string.create_bookmark)); }); @@ -972,7 +924,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook navigationBackMenuItem.setEnabled(currentWebView.canGoBack()); navigationForwardMenuItem.setEnabled(currentWebView.canGoForward()); navigationHistoryMenuItem.setEnabled((currentWebView.canGoBack() || currentWebView.canGoForward())); - navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + currentWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); // Hide the keyboard (if displayed). inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); @@ -1014,11 +966,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook saveFormDataEnabled = false; // Form data can be removed once the minimum API >= 26. nightMode = false; + // Inflate a bare WebView to get the default user agent. It is not used to render content on the screen. + @SuppressLint("InflateParams") View webViewLayout = getLayoutInflater().inflate(R.layout.bare_webview, null, false); + + // Get a handle for the WebView. + WebView bareWebView = webViewLayout.findViewById(R.id.bare_webview); + // Store the default user agent. - // TODO webViewDefaultUserAgent = mainWebView.getSettings().getUserAgentString(); + webViewDefaultUserAgent = bareWebView.getSettings().getUserAgentString(); - // Initialize the WebView title. - webViewTitle = getString(R.string.no_title); + // Destroy the bare WebView. + bareWebView.destroy(); // Initialize the favorite icon bitmap. `ContextCompat` must be used until API >= 21. Drawable favoriteIconDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.world); @@ -1135,8 +1093,23 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reload the webpage if displaying of images has been disabled in the Settings activity. if (reloadOnRestart) { // Reload the WebViews. - // TODO - currentWebView.reload(); + for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); + + // Only reload the WebViews if they exist. + if (fragmentView != null) { + // Get the nested scroll WebView from the tab fragment. + NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); + + // TODO this doesn't seem to work if for WebViews that aren't visible. + // Reload the WebView. + nestedScrollWebView.reload(); + } + } // Reset `reloadOnRestartBoolean`. reloadOnRestart = false; @@ -1189,11 +1162,25 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Run the default commands. super.onResume(); - // Resume JavaScript (if enabled). - // TODO mainWebView.resumeTimers(); + for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); + + // Only resume the WebViews if they exist (they won't when the app is first created). + if (fragmentView != null) { + // Get the nested scroll WebView from the tab fragment. + NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); - // Resume `mainWebView`. - // TODO mainWebView.onResume(); + // Resume the nested scroll WebView JavaScript timers. + nestedScrollWebView.resumeTimers(); + + // Resume the nested scroll WebView. + nestedScrollWebView.onResume(); + } + } // Display a message to the user if waiting for Orbot. if (waitingForOrbot && !orbotStatus.equals("ON")) { @@ -1230,13 +1217,25 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Run the default commands. super.onPause(); - // Pause `mainWebView`. - // TODO - currentWebView.onPause(); + for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); + + // Only pause the WebViews if they exist (they won't when the app is first created). + if (fragmentView != null) { + // Get the nested scroll WebView from the tab fragment. + NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); - // Stop all JavaScript. - // TODO - currentWebView.pauseTimers(); + // Pause the nested scroll WebView. + nestedScrollWebView.onPause(); + + // Pause the nested scroll WebView JavaScript timers. + nestedScrollWebView.pauseTimers(); + } + } // Pause the ad or it will continue to consume resources in the background on the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { @@ -1351,11 +1350,37 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook MenuItem nightModeMenuItem = menu.findItem(R.id.night_mode); MenuItem proxyThroughOrbotMenuItem = menu.findItem(R.id.proxy_through_orbot); - // Set the text for the domain menu item. - if (currentWebView.getDomainSettingsApplied()) { - addOrEditDomain.setTitle(R.string.edit_domain_settings); - } else { - addOrEditDomain.setTitle(R.string.add_domain_settings); + // Initialize the current user agent string and the font size. + String currentUserAgent = getString(R.string.user_agent_privacy_browser); + int fontSize = 100; + + // Set items that require the current web view to be populated. It will be null when the program is first opened, as `onPrepareOptionsMenu()` is called before the first WebView is initialized. + if (currentWebView != null) { + // Set the add or edit domain text. + if (currentWebView.getDomainSettingsApplied()) { + addOrEditDomain.setTitle(R.string.edit_domain_settings); + } else { + addOrEditDomain.setTitle(R.string.add_domain_settings); + } + + // Get the current user agent from the WebView. + currentUserAgent = currentWebView.getSettings().getUserAgentString(); + + // Get the current font size from the + fontSize = currentWebView.getSettings().getTextZoom(); + + // Set the status of the display images menu item. + displayImagesMenuItem.setChecked(currentWebView.getSettings().getLoadsImagesAutomatically()); + + // Initialize the display names for the blocklists with the number of blocked requests. + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + currentWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + easyListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.easylist)); + easyPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.easyprivacy)); + fanboysAnnoyanceListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.fanboys_annoyance_list)); + fanboysSocialBlockingListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS) + " - " + + getString(R.string.fanboys_social_blocking_list)); + ultraPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.ultraprivacy)); + blockAllThirdPartyRequestsMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS) + " - " + getString(R.string.block_all_third_party_requests)); } // Set the status of the menu item checkboxes. @@ -1370,7 +1395,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled); blockAllThirdPartyRequestsMenuItem.setChecked(blockAllThirdPartyRequests); swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled()); - // TODO displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically()); nightModeMenuItem.setChecked(nightMode); proxyThroughOrbotMenuItem.setChecked(proxyThroughOrbot); @@ -1415,19 +1439,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Disable Fanboy's Social Blocking List if Fanboy's Annoyance List is checked. fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListEnabled); - // Initialize the display names for the blocklists with the number of blocked requests. - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + blockedRequests); - easyListMenuItem.setTitle(easyListBlockedRequests + " - " + getString(R.string.easylist)); - easyPrivacyMenuItem.setTitle(easyPrivacyBlockedRequests + " - " + getString(R.string.easyprivacy)); - fanboysAnnoyanceListMenuItem.setTitle(fanboysAnnoyanceListBlockedRequests + " - " + getString(R.string.fanboys_annoyance_list)); - fanboysSocialBlockingListMenuItem.setTitle(fanboysSocialBlockingListBlockedRequests + " - " + getString(R.string.fanboys_social_blocking_list)); - ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy)); - blockAllThirdPartyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests)); - - // Get the current user agent. - // TODO String currentUserAgent = mainWebView.getSettings().getUserAgentString(); - String currentUserAgent = ""; - // Select the current user agent menu item. A switch statement cannot be used because the user agents are not compile time constants. if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[0])) { // Privacy Browser. menu.findItem(R.id.user_agent_privacy_browser).setChecked(true); @@ -1457,9 +1468,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook menu.findItem(R.id.user_agent_custom).setChecked(true); } - // Initialize font size variables. - // TODO int fontSize = mainWebView.getSettings().getTextZoom(); - int fontSize = 100; + // Instantiate the font size title and the selected font size menu item. String fontSizeTitle; MenuItem selectedFontSizeMenuItem; @@ -2110,7 +2119,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook case R.id.share_url: // Setup the share string. - String shareString = webViewTitle + " – " + formattedUrlString; + String shareString = currentWebView.getTitle() + " – " + formattedUrlString; // Create the share intent. Intent shareIntent = new Intent(Intent.ACTION_SEND); @@ -2197,7 +2206,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the current tab number. int currentTabNumber = tabLayout.getSelectedTabPosition(); - // Delete the tab and page. + // Delete the current tab. + tabLayout.removeTabAt(currentTabNumber); + + // Delete the current page. webViewPagerAdapter.deletePage(currentTabNumber); break; @@ -2388,8 +2400,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook break; case R.id.requests: - // Launch the requests activity. + // Populate the resource requests. + RequestsActivity.resourceRequests = currentWebView.getResourceRequests(); + + // Create an intent to launch the Requests activity. Intent requestsIntent = new Intent(this, RequestsActivity.class); + + // Make it so. startActivity(requestsIntent); break; @@ -3430,8 +3447,24 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook customHeaders.remove("DNT"); } - // Set the app bar scrolling. - currentWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true)); + // TODO this also needs to be set when creating a new tab. + // Set the app bar scrolling for each WebView. + for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); + + // Only modify the WebViews if they exist. + if (fragmentView != null) { + // Get the nested scroll WebView from the tab fragment. + NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); + + // Set the app bar scrolling. + nestedScrollWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true)); + } + } // Update the full screen browsing mode settings. if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { // Privacy Browser is currently in full screen browsing mode. @@ -4003,9 +4036,25 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reset `waitingForOrbot. waitingForOrbot = false; - // Reload the website if requested. + // Reload the WebViews if requested. if (reloadWebsite) { - currentWebView.reload(); + // Reload the WebViews. + for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { + // Get the WebView tab fragment. + WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i); + + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); + + // Only reload the WebViews if they exist. + if (fragmentView != null) { + // Get the nested scroll WebView from the tab fragment. + NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); + + // Reload the WebView. + nestedScrollWebView.reload(); + } + } } } } @@ -4288,147 +4337,48 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - private class WebViewPagerAdapter extends FragmentPagerAdapter { - // The WebView fragments list contains all the WebViews. - private LinkedList webViewFragmentsList = new LinkedList<>(); - - // Define the constructor. - private WebViewPagerAdapter(FragmentManager fragmentManager){ - // Run the default commands. - super(fragmentManager); - } - - @Override - public int getCount() { - // Return the number of pages. - return webViewFragmentsList.size(); - } - - @Override - public int getItemPosition(@NonNull Object object) { - //noinspection SuspiciousMethodCalls - if (webViewFragmentsList.contains(object)) { - // The tab has not been deleted. - return POSITION_UNCHANGED; - } else { - // The tab has been deleted. - return POSITION_NONE; - } - } - - @Override - public Fragment getItem(int pageNumber) { - // Get a WebView for a particular page. Page numbers are 0 indexed. - return webViewFragmentsList.get(pageNumber); - } - - private void addPage() { - // Add a new page. The pages and tabs are 0 indexed, so the size of the current list equals the number of the next page. - webViewFragmentsList.add(WebViewTabFragment.createTab(webViewFragmentsList.size())); - - // Update the view pager. - notifyDataSetChanged(); - } - - private void deletePage(int pageNumber) { - // Get a handle for the tab layout. - TabLayout tabLayout = findViewById(R.id.tablayout); - - // TODO always move to the next tab if possible. - // Select a tab that is not being deleted. - if (pageNumber == 0) { // The first tab is being deleted. - // Get a handle for the second tab. The tabs are 0 indexed. - TabLayout.Tab secondTab = tabLayout.getTabAt(1); - - // Remove the incorrect lint warning below that the second tab might be null. - assert secondTab != null; - - // Select the second tab. - secondTab.select(); - } else { // The first tab is not being deleted. - // Get a handle for the previous tab. - TabLayout.Tab previousTab = tabLayout.getTabAt(pageNumber - 1); + public void addTab(View view) { + // Get a handle for the tab layout. + TabLayout tabLayout = findViewById(R.id.tablayout); - // Remove the incorrect lint warning below tha the previous tab might be null. - assert previousTab != null; + // Get the new page number. The page numbers are 0 indexed, so the new page number will match the current count. + int newTabNumber = tabLayout.getTabCount(); - // Select the previous tab. - previousTab.select(); - } + // Add a new tab. + tabLayout.addTab(tabLayout.newTab()); - // Delete the page. - webViewFragmentsList.remove(pageNumber); + // Get the new tab. + TabLayout.Tab newTab = tabLayout.getTabAt(newTabNumber); - // Delete the tab. - tabLayout.removeTabAt(pageNumber); + // Remove the lint warning below that the current tab might be null. + assert newTab != null; - // Update the view pager. - notifyDataSetChanged(); - } - } + // Set a custom view on the current tab. + newTab.setCustomView(R.layout.custom_tab_view); - public void addTab(View view) { // Add the new WebView page. - webViewPagerAdapter.addPage(); - - // Get a handle for the tab layout. - TabLayout tabLayout = findViewById(R.id.tablayout); - - // Get a handle for the new tab. The tabs are 0 indexed. - TabLayout.Tab newTab = tabLayout.getTabAt(tabLayout.getTabCount() - 1); + webViewPagerAdapter.addPage(newTabNumber); - // Remove the incorrect warning below that the new tab might be null. - assert newTab != null; - - // Move the tab layout to the new tab. - newTab.select(); + if (newTabNumber > 0) { + // Move to the new tab. + newTab.select(); + } } @Override - public void initializeWebView(int tabNumber, ProgressBar progressBar, NestedScrollWebView nestedScrollWebView) { + public void initializeWebView(long pageId, int pageNumber, ProgressBar progressBar, NestedScrollWebView nestedScrollWebView) { // Get handles for the activity views. - final FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout); - final DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); - final RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout); - final ActionBar actionBar = getSupportActionBar(); + FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout); + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout); + ActionBar actionBar = getSupportActionBar(); EditText urlEditText = findViewById(R.id.url_edittext); - final TabLayout tabLayout = findViewById(R.id.tablayout); - final SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); + TabLayout tabLayout = findViewById(R.id.tablayout); + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); // Remove the incorrect lint warnings below that the some of the views might be null. assert actionBar != null; - // TODO. Still doesn't work right. - // Create the tab if it doesn't already exist. - try { - TabLayout.Tab tab = tabLayout.getTabAt(tabNumber); - - assert tab != null; - - tab.getCustomView(); - } catch (Exception exception) { - tabLayout.addTab(tabLayout.newTab()); - } - - // Get the current tab. - TabLayout.Tab currentTab = tabLayout.getTabAt(tabNumber); - - // Remove the lint warning below that the current tab might be null. - assert currentTab != null; - - // Set a custom view on the current tab. - currentTab.setCustomView(R.layout.custom_tab_view); - - // Get the custom view from the tab. - View currentTabView = currentTab.getCustomView(); - - // Remove the incorrect warning below that the current tab view might be null. - assert currentTabView != null; - - // Get the current views from the tab. - ImageView tabFavoriteIconImageView = currentTabView.findViewById(R.id.favorite_icon_imageview); - TextView tabTitleTextView = currentTabView.findViewById(R.id.title_textview); - // Get a handle for the shared preferences. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -4652,9 +4602,27 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Only update the favorite icon if the website has finished loading. if (progressBar.getVisibility() == View.GONE) { // Save a copy of the favorite icon. - // TODO. We need to save and access the icons for each tab. favoriteIconBitmap = icon; + // Get the current page position. + int currentPosition = webViewPagerAdapter.getPositionForId(pageId); + + // Get the current tab. + TabLayout.Tab tab = tabLayout.getTabAt(currentPosition); + + // Remove the lint warning below that the current tab might be null. + assert tab != null; + + // Get the custom view from the tab. + View tabView = tab.getCustomView(); + + // Remove the incorrect warning below that the current tab view might be null. + assert tabView != null; + + // Get the favorite icon image view from the tab. + ImageView tabFavoriteIconImageView = tabView.findViewById(R.id.favorite_icon_imageview); + + // Display the favorite icon in the tab. tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true)); } } @@ -4662,12 +4630,26 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Save a copy of the title when it changes. @Override public void onReceivedTitle(WebView view, String title) { - // Save a copy of the title. - // TODO. Replace `webViewTitle` with `currentWebView.getTitle()`. - webViewTitle = title; + // Get the current page position. + int currentPosition = webViewPagerAdapter.getPositionForId(pageId); + + // Get the current tab. + TabLayout.Tab tab = tabLayout.getTabAt(currentPosition); + + // Remove the lint warning below that the current tab might be null. + assert tab != null; + + // Get the custom view from the tab. + View tabView = tab.getCustomView(); + + // Remove the incorrect warning below that the current tab view might be null. + assert tabView != null; + + // Get the title text view from the tab. + TextView tabTitleTextView = tabView.findViewById(R.id.title_textview); // Set the title as the tab text. - tabTitleTextView.setText(webViewTitle); + tabTitleTextView.setText(title); } // Enter full screen video. @@ -4874,7 +4856,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes())); // Reset the whitelist results tracker. - whiteListResultStringArray = null; + String[] whitelistResultStringArray = null; // Initialize the third party request tracker. boolean isThirdPartyRequest = false; @@ -4914,21 +4896,32 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } + // Get the current WebView page position. + int webViewPagePosition = webViewPagerAdapter.getPositionForId(pageId); + + // Determine if the WebView is currently displayed. + boolean webViewDisplayed = (webViewPagePosition == tabLayout.getSelectedTabPosition()); + // Block third-party requests if enabled. if (isThirdPartyRequest && blockAllThirdPartyRequests) { + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[]{BlockListHelper.REQUEST_THIRD_PARTY, url}); + // 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)); - }); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS); - // Add the request to the log. - resourceRequests.add(new String[]{String.valueOf(REQUEST_THIRD_PARTY), url}); + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blockAllThirdPartyRequestsMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS) + " - " + + getString(R.string.block_all_third_party_requests)); + }); + } // Return an empty web resource response. return emptyWebResourceResponse; @@ -4936,26 +4929,36 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check UltraPrivacy if it is enabled. if (ultraPrivacyEnabled) { - if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, ultraPrivacy)) { - // Increment the blocked requests counters. - blockedRequests++; - ultraPrivacyBlockedRequests++; + // Check the URL against UltraPrivacy. + String[] ultraPrivacyResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, ultraPrivacy); - // 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)); - }); + // Process the UltraPrivacy results. + if (ultraPrivacyResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched UltraPrivacy's blacklist. + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[] {ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4], + ultraPrivacyResults[5]}); + + // Increment the blocked requests counters. + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS); + + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + ultraPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS) + " - " + 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) { + } else if (ultraPrivacyResults[0].equals(BlockListHelper.REQUEST_ALLOWED)) { // The resource request matched UltraPrivacy's whitelist. // Add a whitelist entry to the resource requests array. - resourceRequests.add(whiteListResultStringArray); + nestedScrollWebView.addResourceRequest(new String[] {ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4], + ultraPrivacyResults[5]}); // The resource request has been allowed by UltraPrivacy. `return null` loads the requested resource. return null; @@ -4964,94 +4967,145 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check EasyList if it is enabled. if (easyListEnabled) { - if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyList)) { - // Increment the blocked requests counters. - blockedRequests++; - easyListBlockedRequests++; + // Check the URL against EasyList. + String[] easyListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyList); - // 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)); - }); + // Process the EasyList results. + if (easyListResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched EasyList's blacklist. + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[] {easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5]}); - // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). - whiteListResultStringArray = null; + // Increment the blocked requests counters. + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS); + + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + easyListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.easylist)); + }); + } // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; + } else if (easyListResults[0].equals(BlockListHelper.REQUEST_ALLOWED)) { // The resource request matched EasyList's whitelist. + // Update the whitelist result string array tracker. + whitelistResultStringArray = new String[] {easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5]}; } } // Check EasyPrivacy if it is enabled. if (easyPrivacyEnabled) { - if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyPrivacy)) { - // Increment the blocked requests counters. - blockedRequests++; - easyPrivacyBlockedRequests++; + // Check the URL against EasyPrivacy. + String[] easyPrivacyResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyPrivacy); - // 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)); - }); + // Process the EasyPrivacy results. + if (easyPrivacyResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched EasyPrivacy's blacklist. + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[5], + easyPrivacyResults[5]}); - // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). - whiteListResultStringArray = null; + // Increment the blocked requests counters. + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS); + + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + easyPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.easyprivacy)); + }); + } // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; + } else if (easyPrivacyResults[0].equals(BlockListHelper.REQUEST_ALLOWED)) { // The resource request matched EasyPrivacy's whitelist. + // Update the whitelist result string array tracker. + whitelistResultStringArray = new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4], easyPrivacyResults[5]}; } } // 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++; + // Check the URL against Fanboy's Annoyance List. + String[] fanboysAnnoyanceListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList); - // 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)); - }); + // Process the Fanboy's Annoyance List results. + if (fanboysAnnoyanceListResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched Fanboy's Annoyance List's blacklist. + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[] {fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3], + fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]}); - // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). - whiteListResultStringArray = null; + // Increment the blocked requests counters. + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS); + + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + fanboysAnnoyanceListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS) + " - " + + getString(R.string.fanboys_annoyance_list)); + }); + } // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; + } else if (fanboysAnnoyanceListResults[0].equals(BlockListHelper.REQUEST_ALLOWED)){ // The resource request matched Fanboy's Annoyance List's whitelist. + // Update the whitelist result string array tracker. + whitelistResultStringArray = new String[] {fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3], + fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]}; } } 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++; + // Check the URL against Fanboy's Annoyance List. + String[] fanboysSocialListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysSocialList); - // 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)); - }); + // Process the Fanboy's Social Blocking List results. + if (fanboysSocialListResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched Fanboy's Social Blocking List's blacklist. + // Add the result to the resource requests. + nestedScrollWebView.addResourceRequest(new String[] {fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3], + fanboysSocialListResults[4], fanboysSocialListResults[5]}); - // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). - whiteListResultStringArray = null; + // Increment the blocked requests counters. + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS); + + // Update the titles of the blocklist menu items if the WebView is currently displayed. + if (webViewDisplayed) { + // Updating the UI must be run from the UI thread. + activity.runOnUiThread(() -> { + // Update the menu item titles. + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + fanboysSocialBlockingListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS) + " - " + + getString(R.string.fanboys_social_blocking_list)); + }); + } // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; + } else if (fanboysSocialListResults[0].equals(BlockListHelper.REQUEST_ALLOWED)) { // The resource request matched Fanboy's Social Blocking List's whitelist. + // Update the whitelist result string array tracker. + whitelistResultStringArray = new String[] {fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3], + fanboysSocialListResults[4], fanboysSocialListResults[5]}; } } // 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); + if (whitelistResultStringArray != null) { // The request was processed by a whitelist. + nestedScrollWebView.addResourceRequest(whitelistResultStringArray); } else { // The request didn't match any blocklist entry. Log it as a default request. - resourceRequests.add(new String[]{String.valueOf(REQUEST_DEFAULT), url}); + nestedScrollWebView.addResourceRequest(new String[]{BlockListHelper.REQUEST_DEFAULT, url}); } // The resource request has not been blocked. `return null` loads the requested resource. @@ -5080,16 +5134,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook currentHostIpAddresses = ""; // Reset the list of resource requests. - resourceRequests.clear(); + nestedScrollWebView.clearResourceRequests(); // Initialize the counters for requests blocked by each blocklist. - blockedRequests = 0; - easyListBlockedRequests = 0; - easyPrivacyBlockedRequests = 0; - fanboysAnnoyanceListBlockedRequests = 0; - fanboysSocialBlockingListBlockedRequests = 0; - ultraPrivacyBlockedRequests = 0; - thirdPartyBlockedRequests = 0; + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS); + nestedScrollWebView.resetRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS); // If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied. if (nightMode) { @@ -5278,8 +5332,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }); - // Check to see if this is the first tab. - if (tabNumber == 0) { + // Check to see if this is the first page. + if (pageNumber == 0) { // Set this nested scroll WebView as the current WebView. currentWebView = nestedScrollWebView;