import android.net.Uri;
import android.net.http.SslCertificate;
import android.net.http.SslError;
-import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
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;
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;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.lang.ref.WeakReference;
-import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
-import java.net.UnknownHostException;
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;
// `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;
// It is also used in `onCreate()` and `checkPinnedMismatch()`.
public static SslCertificate sslCertificate;
- // `currentHostIpAddresses` is public static so it can be accessed from `DomainSettingsFragment` and `ViewSslCertificateDialog`.
+ // `currentHostIpAddresses` is public static so it can be accessed from `DomainSettingsFragment`, `GetHostIpAddresses()`, and `ViewSslCertificateDialog`.
// It is also used in `onCreate()` and `GetHostIpAddresses()`.
public static String currentHostIpAddresses;
+ // The getting IP addresses tracker is used in `onCreate() and `GetHostIpAddresses`.
+ public static boolean gettingIpAddresses;
+
+ // The URL loading tracker is public static so it can be accessed from `GetHostIpAddresses`.
+ // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `loadUrl()`, `applyDomainSettings()`, and `GetHostIpAddresses`.
+ public static boolean urlIsLoading;
+
// `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;
// `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<String[]> 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;
// `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
public static String currentBookmarksFolder;
- // `domainSettingsDatabaseId` is public static so it can be accessed from `PinnedMismatchDialog`. It is also used in `onCreate()`, `onOptionsItemSelected()`, and `applyDomainSettings()`.
- public static int domainSettingsDatabaseId;
-
// The pinned variables are public static so they can be accessed from `PinnedMismatchDialog`. They are also used in `onCreate()`, `applyDomainSettings()`, and `checkPinnedMismatch()`.
public static String pinnedSslIssuedToCName;
public static String pinnedSslIssuedToOName;
- // `urlIsLoading` is used in `onCreate()`, `onCreateOptionsMenu()`, `loadUrl()`, `applyDomainSettings()`, and `GetHostIpAddresses`.
- private static boolean urlIsLoading;
-
- // `gettingIpAddresses` is used in `onCreate() and `GetHostIpAddresses`.
- private static boolean gettingIpAddresses;
-
// `pinnedDomainSslCertificate` is used in `onCreate()`, `applyDomainSettings()`, and `checkPinnedMismatch()`.
private static boolean pinnedSslCertificate;
private boolean navigatingHistory;
// The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
- // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, and `applyProxyThroughOrbot()`.
+ // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxyThroughOrbot()`, and `applyDomainSettings()`.
private NestedScrollWebView currentWebView;
// `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`.
// `waitingForOrbot` is used in `onCreate()`, `onResume()`, and `applyProxyThroughOrbot()`.
private boolean waitingForOrbot;
- // `domainSettingsApplied` is used in `prepareOptionsMenu()` and `applyDomainSettings()`.
- private boolean domainSettingsApplied;
-
// `domainSettingsJavaScriptEnabled` is used in `onOptionsItemSelected()` and `applyDomainSettings()`.
private Boolean domainSettingsJavaScriptEnabled;
// The action bar drawer toggle is initialized in `onCreate()` and used in `onResume()`.
private ActionBarDrawerToggle actionBarDrawerToggle;
- // `urlTextBox` is used in `onCreate()`, `onOptionsItemSelected()`, `loadUrlFromTextBox()`, `loadUrl()`, and `highlightUrlText()`.
- private EditText urlTextBox;
-
// The color spans are used in `onCreate()` and `highlightUrlText()`.
private ForegroundColorSpan redColorSpan;
private ForegroundColorSpan initialGrayColorSpan;
// 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);
finalGrayColorSpan = new ForegroundColorSpan(resources.getColor(R.color.gray_500));
// Get a handle for `urlTextBox`.
- urlTextBox = findViewById(R.id.url_edittext);
+ EditText urlEditText = findViewById(R.id.url_edittext);
// Remove the formatting from `urlTextBar` when the user is editing the text.
- urlTextBox.setOnFocusChangeListener((View v, boolean hasFocus) -> {
+ urlEditText.setOnFocusChangeListener((View v, boolean hasFocus) -> {
if (hasFocus) { // The user is editing the URL text box.
// Remove the highlighting.
- urlTextBox.getText().removeSpan(redColorSpan);
- urlTextBox.getText().removeSpan(initialGrayColorSpan);
- urlTextBox.getText().removeSpan(finalGrayColorSpan);
+ urlEditText.getText().removeSpan(redColorSpan);
+ urlEditText.getText().removeSpan(initialGrayColorSpan);
+ urlEditText.getText().removeSpan(finalGrayColorSpan);
} else { // The user has stopped editing the URL text box.
// Move to the beginning of the string.
- urlTextBox.setSelection(0);
+ urlEditText.setSelection(0);
// Reapply the highlighting.
highlightUrlText();
});
// Set the go button on the keyboard to load the URL in `urlTextBox`.
- urlTextBox.setOnKeyListener((View v, int keyCode, KeyEvent event) -> {
+ urlEditText.setOnKeyListener((View v, int keyCode, KeyEvent event) -> {
// If the event is a key-down event on the `enter` button, load the URL.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Load the URL into the mainWebView and consume the event.
// 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");
@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 incorrect lint warning below that the fragment view might be null.
+ assert fragmentView != null;
// Store the current WebView.
- currentWebView = (NestedScrollWebView) webViewFragment.getView();
+ currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+
+ // Store the current formatted URL string.
+ formattedUrlString = currentWebView.getUrl();
+
+ // Clear the focus from the URL text box.
+ urlEditText.clearFocus();
+
+ // Hide the soft keyboard.
+ inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
+
+ // Display the current URL in the URL text box.
+ urlEditText.setText(formattedUrlString);
+
+ // Highlight the URL text.
+ highlightUrlText();
+
+ // Set the background to indicate the domain settings status.
+ if (currentWebView.getDomainSettingsApplied()) {
+ // Set a green background on `urlTextBox` to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
+ if (darkTheme) {
+ urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
+ } else {
+ urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
+ }
+ } else {
+ urlEditText.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
+ }
// Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled via swiping in the view pager.
if (tabLayout.getSelectedTabPosition() != position) {
}
});
- // 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) {
// 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);
// 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));
});
// Set the `check mark` button for the `findOnPageEditText` keyboard to close the soft keyboard.
findOnPageEditText.setOnKeyListener((v, keyCode, event) -> {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // The `enter` key was pressed.
- // Hide the soft keyboard. `0` indicates no additional flags.
+ // Hide the soft keyboard.
inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
// Consume the event.
// Set the swipe to refresh color according to the theme.
if (darkTheme) {
- swipeRefreshLayout.setColorSchemeResources(R.color.blue_600);
+ swipeRefreshLayout.setColorSchemeResources(R.color.blue_800);
swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.gray_850);
} else {
- swipeRefreshLayout.setColorSchemeResources(R.color.blue_700);
+ swipeRefreshLayout.setColorSchemeResources(R.color.blue_500);
}
// `DrawerTitle` identifies the `DrawerLayouts` in accessibility mode.
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);
// Clear the focus from from the URL text box and the WebView. This removes any text selection markers and context menus, which otherwise draw above the open drawers.
- urlTextBox.clearFocus();
+ urlEditText.clearFocus();
currentWebView.clearFocus();
}
}
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);
// 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;
// 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);
- // Resume `mainWebView`.
- // TODO mainWebView.onResume();
+ // 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 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")) {
// 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")) {
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 (domainSettingsApplied) {
- 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.
ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled);
blockAllThirdPartyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
- // TODO displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically());
nightModeMenuItem.setChecked(nightMode);
proxyThroughOrbotMenuItem.setChecked(proxyThroughOrbot);
// 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);
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;
return true;
case R.id.add_or_edit_domain:
- if (domainSettingsApplied) { // Edit the current domain settings.
+ if (currentWebView.getDomainSettingsApplied()) { // Edit the current domain settings.
// Reapply the domain settings on returning to `MainWebViewActivity`.
reapplyDomainSettingsOnRestart = true;
currentDomainName = "";
Intent domainsIntent = new Intent(this, DomainsActivity.class);
// Put extra information instructing the domains activity to directly load the current domain and close on back instead of returning to the domains list.
- domainsIntent.putExtra("loadDomain", domainSettingsDatabaseId);
+ domainsIntent.putExtra("loadDomain", currentWebView.getDomainSettingsDatabaseId());
domainsIntent.putExtra("closeOnBack", true);
// Make it so.
if (nightMode) { // Night mode is enabled. Enable JavaScript.
// Update the global variable.
javaScriptEnabled = true;
- } else if (domainSettingsApplied) { // Night mode is disabled and domain settings are applied. Set JavaScript according to the domain settings.
+ } else if (currentWebView.getDomainSettingsApplied()) { // Night mode is disabled and domain settings are applied. Set JavaScript according to the domain settings.
// Get the JavaScript preference that was stored the last time domain settings were loaded.
javaScriptEnabled = domainSettingsJavaScriptEnabled;
} else { // Night mode is disabled and domain settings are not applied. Set JavaScript according to the global preference.
case R.id.share_url:
// Setup the share string.
- String shareString = webViewTitle + " – " + urlTextBox.getText().toString();
+ String shareString = currentWebView.getTitle() + " – " + formattedUrlString;
// Create the share intent.
Intent shareIntent = new Intent(Intent.ACTION_SEND);
// 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;
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;
}
private void loadUrlFromTextBox() {
+ // Get a handle for the URL edit text.
+ EditText urlEditText = findViewById(R.id.url_edittext);
+
// Get the text from urlTextBox and convert it to a string. trim() removes white spaces from the beginning and end of the string.
- String unformattedUrlString = urlTextBox.getText().toString().trim();
+ String unformattedUrlString = urlEditText.getText().toString().trim();
// Check to see if `unformattedUrlString` is a valid URL. Otherwise, convert it into a search.
if (unformattedUrlString.startsWith("content://")) {
formattedUrlString = searchURL + encodedUrlString;
}
- // Clear the focus from the URL text box. Otherwise, proximate typing in the box will retain the colorized formatting instead of being reset during refocus.
- urlTextBox.clearFocus();
+ // Clear the focus from the URL edit text. Otherwise, proximate typing in the box will retain the colorized formatting instead of being reset during refocus.
+ urlEditText.clearFocus();
// Make it so.
loadUrl(formattedUrlString);
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.
// Close `domainNameCursor.
domainNameCursor.close();
- // Initialize variables to track if domain settings will be applied and, if so, under which name.
- domainSettingsApplied = false;
+ // Initialize the domain name in database variable.
String domainNameInDatabase = null;
- // Check the hostname.
- if (domainSettingsSet.contains(hostName)) {
- domainSettingsApplied = true;
+ // Check the hostname against the domain settings set.
+ if (domainSettingsSet.contains(hostName)) { // The hostname is contained in the domain settings set.
+ // Record the domain name in the database.
domainNameInDatabase = hostName;
+
+ // Set the domain settings applied tracker to true.
+ currentWebView.setDomainSettingsApplied(true);
+ } else { // The hostname is not contained in the domain settings set.
+ // Set the domain settings applied tracker to false.
+ currentWebView.setDomainSettingsApplied(false);
}
// Check all the subdomains of the host name against wildcard domains in the domain cursor.
- while (!domainSettingsApplied && hostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the host name.
+ while (!currentWebView.getDomainSettingsApplied() && hostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the host name.
if (domainSettingsSet.contains("*." + hostName)) { // Check the host name prepended by `*.`.
- // Apply the domain settings.
- domainSettingsApplied = true;
+ // Set the domain settings applied tracker to true.
+ currentWebView.setDomainSettingsApplied(true);
// Store the applied domain names as it appears in the database.
domainNameInDatabase = "*." + hostName;
nightMode = sharedPreferences.getBoolean("night_mode", false);
boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true);
- if (domainSettingsApplied) { // The url has custom domain settings.
+ if (currentWebView.getDomainSettingsApplied()) { // The url has custom domain settings.
// Get a cursor for the current host and move it to the first position.
Cursor currentHostDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
currentHostDomainSettingsCursor.moveToFirst();
// Get the settings from the cursor.
- domainSettingsDatabaseId = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
+ currentWebView.setDomainSettingsDatabaseId(currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
javaScriptEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1);
firstPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1);
thirdPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1);
break;
}
- // Set a green background on `urlTextBox` to indicate that custom domain settings are being used. We have to use the deprecated `.getDrawable()` until the minimum API >= 21.
+ // Set a green background on URL edit text to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
if (darkTheme) {
urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
} else {
}
// Reset the pinned variables.
- domainSettingsDatabaseId = -1;
+ currentWebView.setDomainSettingsDatabaseId(-1);
pinnedSslCertificate = false;
pinnedSslIssuedToCName = "";
pinnedSslIssuedToOName = "";
// Set the loading of webpage images.
currentWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImages);
- // Set a transparent background on `urlTextBox`. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
+ // Set a transparent background on URL edit text. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
urlEditText.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
}
// 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();
+ }
+ }
}
}
}
}
private void highlightUrlText() {
+ // Get a handle for the URL edit text.
+ EditText urlEditText = findViewById(R.id.url_edittext);
+
// Only highlight the URL text if the box is not currently selected.
- if (!urlTextBox.hasFocus()) {
+ if (!urlEditText.hasFocus()) {
// Get the URL string.
- String urlString = urlTextBox.getText().toString();
+ String urlString = urlEditText.getText().toString();
// Highlight the URL according to the protocol.
if (urlString.startsWith("file://")) { // This is a file URL.
// De-emphasize only the protocol.
- urlTextBox.getText().setSpan(initialGrayColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(initialGrayColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
} else if (urlString.startsWith("content://")) {
// De-emphasize only the protocol.
- urlTextBox.getText().setSpan(initialGrayColorSpan, 0, 10, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(initialGrayColorSpan, 0, 10, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
} else { // This is a web URL.
// Get the index of the `/` immediately after the domain name.
int endOfDomainName = urlString.indexOf("/", (urlString.indexOf("//") + 2));
// Markup the beginning of the URL.
if (urlString.startsWith("http://")) { // Highlight the protocol of connections that are not encrypted.
- urlTextBox.getText().setSpan(redColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(redColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
// De-emphasize subdomains.
if (penultimateDotIndex > 0) { // There is more than one subdomain in the domain name.
- urlTextBox.getText().setSpan(initialGrayColorSpan, 7, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(initialGrayColorSpan, 7, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
} else if (urlString.startsWith("https://")) { // De-emphasize the protocol of connections that are encrypted.
if (penultimateDotIndex > 0) { // There is more than one subdomain in the domain name.
// De-emphasize the protocol and the additional subdomains.
- urlTextBox.getText().setSpan(initialGrayColorSpan, 0, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(initialGrayColorSpan, 0, penultimateDotIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
} else { // There is only one subdomain in the domain name.
// De-emphasize only the protocol.
- urlTextBox.getText().setSpan(initialGrayColorSpan, 0, 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(initialGrayColorSpan, 0, 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
}
// De-emphasize the text after the domain name.
if (endOfDomainName > 0) {
- urlTextBox.getText().setSpan(finalGrayColorSpan, endOfDomainName, urlString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ urlEditText.getText().setSpan(finalGrayColorSpan, endOfDomainName, urlString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
}
}
startActivity(openWithBrowserIntent);
}
- private static void checkPinnedMismatch() {
+ public static void checkPinnedMismatch(int domainSettingsDatabaseId) {
if ((pinnedSslCertificate || pinnedIpAddresses) && !ignorePinnedDomainInformation) {
// Initialize the current SSL certificate variables.
String currentWebsiteIssuedToCName = "";
!currentWebsiteSslEndDateString.equals(pinnedSslEndDateString)))) {
// Get a handle for the pinned mismatch alert dialog.
- DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(pinnedSslCertificate, pinnedIpAddresses);
+ DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(domainSettingsDatabaseId, pinnedSslCertificate, pinnedIpAddresses);
// Show the pinned mismatch alert dialog.
pinnedMismatchDialogFragment.show(fragmentManager, "Pinned Mismatch");
}
}
- // This must run asynchronously because it involves a network request. `String` declares the parameters. `Void` does not declare progress units. `String` contains the results.
- private static class GetHostIpAddresses extends AsyncTask<String, Void, String> {
- // The weak references are used to determine if the activity have disappeared while the AsyncTask is running.
- private final WeakReference<Activity> activityWeakReference;
-
- GetHostIpAddresses(Activity activity) {
- // Populate the weak references.
- activityWeakReference = new WeakReference<>(activity);
- }
-
- // `onPreExecute()` operates on the UI thread.
- @Override
- protected void onPreExecute() {
- // Get a handle for the activity.
- Activity activity = activityWeakReference.get();
-
- // Abort if the activity is gone.
- if ((activity == null) || activity.isFinishing()) {
- return;
- }
-
- // Set the getting IP addresses tracker.
- gettingIpAddresses = true;
- }
-
-
- @Override
- protected String doInBackground(String... domainName) {
- // Get a handle for the activity.
- Activity activity = activityWeakReference.get();
-
- // Abort if the activity is gone.
- if ((activity == null) || activity.isFinishing()) {
- // Return an empty spannable string builder.
- return "";
- }
-
- // Initialize an IP address string builder.
- StringBuilder ipAddresses = new StringBuilder();
-
- // Get an array with the IP addresses for the host.
- try {
- // Get an array with all the IP addresses for the domain.
- InetAddress[] inetAddressesArray = InetAddress.getAllByName(domainName[0]);
-
- // Add each IP address to the string builder.
- for (InetAddress inetAddress : inetAddressesArray) {
- if (ipAddresses.length() == 0) { // This is the first IP address.
- // Add the IP address to the string builder.
- ipAddresses.append(inetAddress.getHostAddress());
- } else { // This is not the first IP address.
- // Add a line break to the string builder first.
- ipAddresses.append("\n");
-
- // Add the IP address to the string builder.
- ipAddresses.append(inetAddress.getHostAddress());
- }
- }
- } catch (UnknownHostException exception) {
- // Do nothing.
- }
-
- // Return the string.
- return ipAddresses.toString();
- }
-
- // `onPostExecute()` operates on the UI thread.
- @Override
- protected void onPostExecute(String ipAddresses) {
- // Get a handle for the activity.
- Activity activity = activityWeakReference.get();
-
- // Abort if the activity is gone.
- if ((activity == null) || activity.isFinishing()) {
- return;
- }
-
- // Store the IP addresses.
- currentHostIpAddresses = ipAddresses;
-
- if (!urlIsLoading) {
- checkPinnedMismatch();
- }
-
- // Reset the getting IP addresses tracker.
- gettingIpAddresses = false;
- }
- }
-
- private class WebViewPagerAdapter extends FragmentPagerAdapter {
- // The WebView fragments list contains all the WebViews.
- private LinkedList<WebViewTabFragment> 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;
+ public void addTab(View view) {
+ // Get a handle for the tab layout.
+ TabLayout tabLayout = findViewById(R.id.tablayout);
- // 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);
+ // 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();
- // Remove the incorrect lint warning below tha the previous tab might be null.
- assert previousTab != null;
+ // Add a new tab.
+ tabLayout.addTab(tabLayout.newTab());
- // Select the previous tab.
- previousTab.select();
- }
+ // Get the new tab.
+ TabLayout.Tab newTab = tabLayout.getTabAt(newTabNumber);
- // Delete the page.
- webViewFragmentsList.remove(pageNumber);
-
- // 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();
+ webViewPagerAdapter.addPage(newTabNumber);
- // 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);
-
- // 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(NestedScrollWebView nestedScrollWebView, int tabNumber) {
+ 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();
- final TabLayout tabLayout = findViewById(R.id.tablayout);
- final SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
+ 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);
+ 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);
-
-
- //TODO
- final ProgressBar progressBar = findViewById(R.id.progress_bar);
-
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// 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));
}
}
// 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.
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;
}
}
+ // 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;
// 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;
// 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.
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) {
formattedUrlString = url;
// Display the formatted URL text.
- urlTextBox.setText(formattedUrlString);
+ urlEditText.setText(formattedUrlString);
// Apply text highlighting to `urlTextBox`.
highlightUrlText();
Uri currentUri = Uri.parse(formattedUrlString);
// Get the IP addresses for the host.
- new GetHostIpAddresses(activity).execute(currentUri.getHost());
+ new GetHostIpAddresses(activity, currentWebView.getDomainSettingsDatabaseId()).execute(currentUri.getHost());
// Apply any custom domain settings if the URL was loaded by navigating history.
if (navigatingHistory) {
// Set `formattedUrlString` to `""`.
formattedUrlString = "";
- urlTextBox.setText(formattedUrlString);
+ urlEditText.setText(formattedUrlString);
// Request focus for `urlTextBox`.
- urlTextBox.requestFocus();
+ urlEditText.requestFocus();
// Display the keyboard.
- inputMethodManager.showSoftInput(urlTextBox, 0);
+ inputMethodManager.showSoftInput(urlEditText, 0);
// Apply the domain settings. This clears any settings from the previous domain.
applyDomainSettings(formattedUrlString, true, false);
formattedUrlString = nestedScrollWebView.getUrl();
// Only update the URL text box if the user is not typing in it.
- if (!urlTextBox.hasFocus()) {
+ if (!urlEditText.hasFocus()) {
// Display the formatted URL text.
- urlTextBox.setText(formattedUrlString);
+ urlEditText.setText(formattedUrlString);
// Apply text highlighting to `urlTextBox`.
highlightUrlText();
// Check the current website information against any pinned domain information if the current IP addresses have been loaded.
if (!gettingIpAddresses) {
- checkPinnedMismatch();
+ checkPinnedMismatch(currentWebView.getDomainSettingsDatabaseId());
}
}
}
});
- // 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;