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=115adcc2ca710f0881c90213658a903dc105efbe;hp=99a2ce30806441bbf5f3f9051f95d0d0899a74b3;hb=cb8575682954a7fad08de3c7c90efc97b605b558;hpb=a777fe1b2785ac15a70bed633c159b9d4e58b90a 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 99a2ce30..115adcc2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -23,6 +23,7 @@ package com.stoutner.privacybrowser.activities; import android.Manifest; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.DialogFragment; import android.app.DownloadManager; import android.content.ActivityNotFoundException; @@ -201,6 +202,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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; + int blockedRequests; int easyListBlockedRequests; int easyPrivacyBlockedRequests; int fanboysAnnoyanceListBlockedRequests; @@ -326,7 +328,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `saveFormDataEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`. It can be removed once the minimum API >= 26. private boolean saveFormDataEnabled; - // `nightMode` is used in `onCreate()` and `applyDomainSettings()`. + // `nightMode` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`. private boolean nightMode; // `displayWebpageImagesBoolean` is used in `applyAppSettings()` and `applyDomainSettings()`. @@ -338,13 +340,34 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `searchURL` is used in `loadURLFromTextBox()` and `applyAppSettings()`. private String searchURL; - // The block list variables are used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`. + // `mainMenu` is used in `onCreateOptionsMenu()` and `updatePrivacyIcons()`. + private Menu mainMenu; + + // `refreshMenuItem` is used in `onCreate()` and `onCreateOptionsMenu()`. + private MenuItem refreshMenuItem; + + // The blocklist menu items are used in `onCreate()`, `onCreateOptionsMenu()`, and `onPrepareOptionsMenu()`. + private MenuItem blocklistsMenuItem; + private MenuItem easyListMenuItem; + private MenuItem easyPrivacyMenuItem; + private MenuItem fanboysAnnoyanceListMenuItem; + private MenuItem fanboysSocialBlockingListMenuItem; + private MenuItem ultraPrivacyMenuItem; + private MenuItem blockAllThirdParyRequestsMenuItem; + + // The blocklist variables are used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`. private boolean easyListEnabled; private boolean easyPrivacyEnabled; private boolean fanboysAnnoyanceListEnabled; private boolean fanboysSocialBlockingListEnabled; private boolean ultraPrivacyEnabled; + // `webViewDefaultUserAgent` is used in `onCreate()` and `onPrepareOptionsMenu()`. + private String webViewDefaultUserAgent; + + // `defaultCustomUserAgentString` is used in `onPrepareOptionsMenu()` and `applyDomainSettings()`. + private String defaultCustomUserAgentString; + // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`. private Runtime privacyBrowserRuntime; @@ -390,6 +413,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `domainSettingsApplied` is used in `prepareOptionsMenu()`, `applyDomainSettings()`, and `setDisplayWebpageImages()`. private boolean domainSettingsApplied; + // `domainSettingsJavaScriptEnabled` is used in `onOptionsItemSelected()` and `applyDomainSettings()`. + private Boolean domainSettingsJavaScriptEnabled; + // `displayWebpageImagesInt` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`. private int displayWebpageImagesInt; @@ -408,8 +434,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. private EditText findOnPageEditText; - // `mainMenu` is used in `onCreateOptionsMenu()` and `updatePrivacyIcons()`. - private Menu mainMenu; + // `displayAdditionalAppBarIcons` is used in `onCreate()` and `onCreateOptionsMenu()`. + private boolean displayAdditionalAppBarIcons; // `drawerToggle` is used in `onCreate()`, `onPostCreate()`, `onConfigurationChanged()`, `onNewIntent()`, and `onNavigationItemSelected()`. private ActionBarDrawerToggle drawerToggle; @@ -437,7 +463,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `mainWebViewRelativeLayout` is used in `onCreate()` and `onNavigationItemSelected()`. private RelativeLayout mainWebViewRelativeLayout; - // `urlIsLoading` is used in `onCreate()`, `loadUrl()`, and `applyDomainSettings()`. + // `urlIsLoading` is used in `onCreate()`, `onCreateOptionsMenu()`, `loadUrl()`, and `applyDomainSettings()`. private boolean urlIsLoading; // `pinnedDomainSslCertificate` is used in `onCreate()` and `applyDomainSettings()`. @@ -872,7 +898,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return true; }); - // The `DrawerListener` is used to update the Navigation Menu. + // The drawer listener is used to update the navigation menu. drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { @Override public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { @@ -888,21 +914,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onDrawerStateChanged(int newState) { - if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) { // The drawer is opening or closing. - // Calculate the total blocked requests counter. - int totalBlockedRequests = easyListBlockedRequests + easyPrivacyBlockedRequests + fanboysAnnoyanceListBlockedRequests + fanboysSocialBlockingListBlockedRequests + - ultraPrivacyBlockedRequests + thirdPartyBlockedRequests; - + if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) { // A drawer is opening or closing. // Update the back, forward, history, and requests menu items. navigationBackMenuItem.setEnabled(mainWebView.canGoBack()); navigationForwardMenuItem.setEnabled(mainWebView.canGoForward()); navigationHistoryMenuItem.setEnabled((mainWebView.canGoBack() || mainWebView.canGoForward())); - navigationRequestsMenuItem.setTitle(getResources().getString(R.string.requests) + " - " + totalBlockedRequests); + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); - // Hide the keyboard (if displayed) so we can see the navigation menu. `0` indicates no additional flags. + // Hide the keyboard (if displayed). inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); - // Clear the focus from `urlTextBox` if it has it. + // Clear the focus from from the URL text box. urlTextBox.clearFocus(); } } @@ -1025,7 +1047,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onHideCustomView() { // Unset the full screen video flag. - displayingFullScreenVideo = true; + displayingFullScreenVideo = false; // Hide `fullScreenVideoFrameLayout`. fullScreenVideoFrameLayout.removeAllViews(); @@ -1203,6 +1225,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook saveFormDataEnabled = false; // Form data can be removed once the minimum API >= 26. nightMode = false; + // Store the default user agent. + webViewDefaultUserAgent = mainWebView.getSettings().getUserAgentString(); + // Initialize the WebView title. webViewTitle = getString(R.string.no_title); @@ -1244,6 +1269,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook fanboysSocialVersion = fanboysSocialList.get(0).get(0)[0]; ultraPrivacyVersion = ultraPrivacy.get(0).get(0)[0]; + // Get a handle for the activity. This is used to update the requests counter while the navigation menu is open. + Activity activity = this; + mainWebView.setWebViewClient(new WebViewClient() { // `shouldOverrideUrlLoading` makes this `WebView` the default handler for URLs inside the app, so that links are not kicked out to other apps. // The deprecated `shouldOverrideUrlLoading` must be used until API >= 24. @@ -1364,9 +1392,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Block third-party requests if enabled. if (isThirdPartyRequest && blockAllThirdPartyRequests) { - // Increment the third-party blocked requests counter. + // 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); + blockAllThirdParyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests)); + }); + // Add the request to the log. resourceRequests.add(new String[]{String.valueOf(REQUEST_THIRD_PARTY), url}); @@ -1377,9 +1413,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check UltraPrivacy if it is enabled. if (ultraPrivacyEnabled) { if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, ultraPrivacy)) { - // Increment the UltraPrivacy blocked requests counter. + // Increment the blocked requests counters. + blockedRequests++; ultraPrivacyBlockedRequests++; + // Update the titles of the blocklist menu items. This must be run from the UI thread. + activity.runOnUiThread(() -> { + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy)); + }); + // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } @@ -1397,9 +1441,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check EasyList if it is enabled. if (easyListEnabled) { if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyList)) { - // Increment the EasyList blocked requests counter. + // Increment the blocked requests counters. + blockedRequests++; easyListBlockedRequests++; + // Update the titles of the blocklist menu items. This must be run from the UI thread. + activity.runOnUiThread(() -> { + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + easyListMenuItem.setTitle(easyListBlockedRequests + " - " + getString(R.string.easylist)); + }); + // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). whiteListResultStringArray = null; @@ -1411,9 +1463,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check EasyPrivacy if it is enabled. if (easyPrivacyEnabled) { if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, easyPrivacy)) { - // Increment the EasyPrivacy blocked requests counter. + // Increment the blocked requests counters. + blockedRequests++; easyPrivacyBlockedRequests++; + // Update the titles of the blocklist menu items. This must be run from the UI thread. + activity.runOnUiThread(() -> { + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + easyPrivacyMenuItem.setTitle(easyPrivacyBlockedRequests + " - " + getString(R.string.easyprivacy)); + }); + // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). whiteListResultStringArray = null; @@ -1425,9 +1485,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check Fanboy’s Annoyance List if it is enabled. if (fanboysAnnoyanceListEnabled) { if (blockListHelper.isBlocked(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList)) { - // Increment the Fanboy's Annoyance List blocked requests counter. + // Increment the blocked requests counters. + blockedRequests++; fanboysAnnoyanceListBlockedRequests++; + // Update the titles of the blocklist menu items. This must be run from the UI thread. + activity.runOnUiThread(() -> { + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + fanboysAnnoyanceListMenuItem.setTitle(fanboysAnnoyanceListBlockedRequests + " - " + getString(R.string.fanboys_annoyance_list)); + }); + // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). whiteListResultStringArray = null; @@ -1436,9 +1504,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } 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 Fanboy's Social Blocking List blocked requests counter. + // Increment the blocked requests counters. + blockedRequests++; fanboysSocialBlockingListBlockedRequests++; + // Update the titles of the blocklist menu items. This must be run from the UI thread. + activity.runOnUiThread(() -> { + navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests); + fanboysSocialBlockingListMenuItem.setTitle(fanboysSocialBlockingListBlockedRequests + " - " + getString(R.string.fanboys_social_blocking_list)); + }); + // Reset the whitelist results tracker (because otherwise it will sometimes add results to the list due to a race condition). whiteListResultStringArray = null; @@ -1476,6 +1552,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook resourceRequests.clear(); // Initialize the counters for requests blocked by each blocklist. + blockedRequests = 0; easyListBlockedRequests = 0; easyPrivacyBlockedRequests = 0; fanboysAnnoyanceListBlockedRequests = 0; @@ -1513,6 +1590,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set `urlIsLoading` to `true`, so that redirects while loading do not trigger changes in the user agent, which forces another reload of the existing page. urlIsLoading = true; + + // Replace Refresh with Stop if the menu item has been created. (The WebView typically begins loading before the menu items are instantiated.) + if (refreshMenuItem != null) { + // Set the title. + refreshMenuItem.setTitle(R.string.stop); + + // If the icon is displayed in the AppBar, set it according to the theme. + if (displayAdditionalAppBarIcons) { + if (darkTheme) { + refreshMenuItem.setIcon(R.drawable.close_dark); + } else { + refreshMenuItem.setIcon(R.drawable.close_light); + } + } + } } } @@ -1524,6 +1616,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook cookieManager.flush(); } + // Update the Refresh menu item if it has been created. + if (refreshMenuItem != null) { + // Reset the Refresh title. + refreshMenuItem.setTitle(R.string.refresh); + + // If the icon is displayed in the AppBar, reset it according to the theme. + if (displayAdditionalAppBarIcons) { + if (darkTheme) { + refreshMenuItem.setIcon(R.drawable.refresh_enabled_dark); + } else { + refreshMenuItem.setIcon(R.drawable.refresh_enabled_light); + } + } + } + // Reset `urlIsLoading`, which is used to prevent reloads on redirect if the user agent changes. urlIsLoading = false; @@ -1866,7 +1973,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage); MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data); // Form data can be removed once the minimum API >= 26. MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data); // Form data can be removed once the minimum API >= 26. - MenuItem refreshMenuItem = menu.findItem(R.id.refresh); + refreshMenuItem = menu.findItem(R.id.refresh); + blocklistsMenuItem = menu.findItem(R.id.blocklists); + easyListMenuItem = menu.findItem(R.id.easylist); + easyPrivacyMenuItem = menu.findItem(R.id.easyprivacy); + fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list); + fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list); + ultraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy); + blockAllThirdParyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests); MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent); // Only display third-party cookies if API >= 21 @@ -1879,11 +1993,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Only show Ad Consent if this is the free flavor. adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free")); - // Get the shared preference values. `this` references the current context. + // Get the shared preference values. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + // Get the status of the additional AppBar icons. + displayAdditionalAppBarIcons = sharedPreferences.getBoolean("display_additional_app_bar_icons", false); + // Set the status of the additional app bar icons. Setting the refresh menu item to `SHOW_AS_ACTION_ALWAYS` makes it appear even on small devices like phones. - if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) { + if (displayAdditionalAppBarIcons) { toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); toggleDomStorageMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); @@ -1893,6 +2010,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); } + // Replace Refresh with Stop if a URL is already loading. + if (urlIsLoading) { + // Set the title. + refreshMenuItem.setTitle(R.string.stop); + + // If the icon is displayed in the AppBar, set it according to the theme. + if (displayAdditionalAppBarIcons) { + if (darkTheme) { + refreshMenuItem.setIcon(R.drawable.close_dark); + } else { + refreshMenuItem.setIcon(R.drawable.close_light); + } + } + } + return true; } @@ -1908,15 +2040,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook MenuItem clearCookiesMenuItem = menu.findItem(R.id.clear_cookies); MenuItem clearDOMStorageMenuItem = menu.findItem(R.id.clear_dom_storage); MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data); // Form data can be removed once the minimum API >= 26. - MenuItem easyListMenuItem = menu.findItem(R.id.easylist); - MenuItem easyPrivacyMenuItem = menu.findItem(R.id.easyprivacy); - MenuItem fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list); - MenuItem fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list); - MenuItem ultraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy); - MenuItem blockAllThirdParyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests); MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size); MenuItem swipeToRefreshMenuItem = menu.findItem(R.id.swipe_to_refresh); MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images); + MenuItem nightModeMenuItem = menu.findItem(R.id.night_mode); // Set the text for the domain menu item. if (domainSettingsApplied) { @@ -1938,6 +2065,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook blockAllThirdParyRequestsMenuItem.setChecked(blockAllThirdPartyRequests); swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled()); displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically()); + nightModeMenuItem.setChecked(nightMode); // Enable third-party cookies if first-party cookies are enabled. toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled); @@ -1977,7 +2105,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Enable Clear Data if any of the submenu items are enabled. clearDataMenuItem.setEnabled(clearCookiesMenuItem.isEnabled() || clearDOMStorageMenuItem.isEnabled() || clearFormDataMenuItem.isEnabled()); - // Update the display names for the blocklists with the number of blocked requests. + // 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)); @@ -1985,8 +2117,37 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy)); blockAllThirdParyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests)); - // Disable Fanboy's Social Blocking List if Fanboy's Annoyance List is checked. - fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListEnabled); + // Get the current user agent. + String currentUserAgent = mainWebView.getSettings().getUserAgentString(); + + // 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); + } else if (currentUserAgent.equals(webViewDefaultUserAgent)) { // WebView Default. + menu.findItem(R.id.user_agent_webview_default).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[2])) { // Firefox on Android. + menu.findItem(R.id.user_agent_firefox_on_android).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[3])) { // Chrome on Android. + menu.findItem(R.id.user_agent_chrome_on_android).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[4])) { // Safari on iOS. + menu.findItem(R.id.user_agent_safari_on_ios).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[5])) { // Firefox on Linux. + menu.findItem(R.id.user_agent_firefox_on_linux).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[6])) { // Chromium on Linux. + menu.findItem(R.id.user_agent_chromium_on_linux).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[7])) { // Firefox on Windows. + menu.findItem(R.id.user_agent_firefox_on_windows).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[8])) { // Chrome on Windows. + menu.findItem(R.id.user_agent_chrome_on_windows).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[9])) { // Edge on Windows. + menu.findItem(R.id.user_agent_edge_on_windows).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[10])) { // Internet Explorer on Windows. + menu.findItem(R.id.user_agent_internet_explorer_on_windows).setChecked(true); + } else if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[11])) { // Safari on macOS. + menu.findItem(R.id.user_agent_safari_on_macos).setChecked(true); + } else { // Custom user agent. + menu.findItem(R.id.user_agent_custom).setChecked(true); + } // Initialize font size variables. int fontSize = mainWebView.getSettings().getTextZoom(); @@ -2320,61 +2481,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook .show(); return true; - case R.id.font_size_twenty_five_percent: - mainWebView.getSettings().setTextZoom(25); - return true; - - case R.id.font_size_fifty_percent: - mainWebView.getSettings().setTextZoom(50); - return true; - - case R.id.font_size_seventy_five_percent: - mainWebView.getSettings().setTextZoom(75); - return true; - - case R.id.font_size_one_hundred_percent: - mainWebView.getSettings().setTextZoom(100); - return true; - - case R.id.font_size_one_hundred_twenty_five_percent: - mainWebView.getSettings().setTextZoom(125); - return true; - - case R.id.font_size_one_hundred_fifty_percent: - mainWebView.getSettings().setTextZoom(150); - return true; - - case R.id.font_size_one_hundred_seventy_five_percent: - mainWebView.getSettings().setTextZoom(175); - return true; - - case R.id.font_size_two_hundred_percent: - mainWebView.getSettings().setTextZoom(200); - return true; - - case R.id.swipe_to_refresh: - // Toggle swipe to refresh. - swipeRefreshLayout.setEnabled(!swipeRefreshLayout.isEnabled()); - return true; - - case R.id.display_images: - if (mainWebView.getSettings().getLoadsImagesAutomatically()) { // Images are currently loaded automatically. - mainWebView.getSettings().setLoadsImagesAutomatically(false); - mainWebView.reload(); - } else { // Images are not currently loaded automatically. - mainWebView.getSettings().setLoadsImagesAutomatically(true); - } - - // Set `onTheFlyDisplayImagesSet`. - onTheFlyDisplayImagesSet = true; - return true; - - case R.id.view_source: - // Launch the View Source activity. - Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class); - startActivity(viewSourceIntent); - return true; - case R.id.easylist: // Toggle the EasyList status. easyListEnabled = !easyListEnabled; @@ -2445,6 +2551,194 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook mainWebView.reload(); return true; + case R.id.user_agent_privacy_browser: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[0]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_webview_default: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(""); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_firefox_on_android: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[2]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_chrome_on_android: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[3]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_safari_on_ios: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[4]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_firefox_on_linux: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[5]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_chromium_on_linux: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[6]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_firefox_on_windows: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[7]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_chrome_on_windows: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[8]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_edge_on_windows: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[9]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_internet_explorer_on_windows: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[10]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_safari_on_macos: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[11]); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.user_agent_custom: + // Update the user agent. + mainWebView.getSettings().setUserAgentString(defaultCustomUserAgentString); + + // Reload the WebView. + mainWebView.reload(); + return true; + + case R.id.font_size_twenty_five_percent: + mainWebView.getSettings().setTextZoom(25); + return true; + + case R.id.font_size_fifty_percent: + mainWebView.getSettings().setTextZoom(50); + return true; + + case R.id.font_size_seventy_five_percent: + mainWebView.getSettings().setTextZoom(75); + return true; + + case R.id.font_size_one_hundred_percent: + mainWebView.getSettings().setTextZoom(100); + return true; + + case R.id.font_size_one_hundred_twenty_five_percent: + mainWebView.getSettings().setTextZoom(125); + return true; + + case R.id.font_size_one_hundred_fifty_percent: + mainWebView.getSettings().setTextZoom(150); + return true; + + case R.id.font_size_one_hundred_seventy_five_percent: + mainWebView.getSettings().setTextZoom(175); + return true; + + case R.id.font_size_two_hundred_percent: + mainWebView.getSettings().setTextZoom(200); + return true; + + case R.id.swipe_to_refresh: + // Toggle swipe to refresh. + swipeRefreshLayout.setEnabled(!swipeRefreshLayout.isEnabled()); + return true; + + case R.id.display_images: + if (mainWebView.getSettings().getLoadsImagesAutomatically()) { // Images are currently loaded automatically. + mainWebView.getSettings().setLoadsImagesAutomatically(false); + mainWebView.reload(); + } else { // Images are not currently loaded automatically. + mainWebView.getSettings().setLoadsImagesAutomatically(true); + } + + // Set `onTheFlyDisplayImagesSet`. + onTheFlyDisplayImagesSet = true; + return true; + + case R.id.night_mode: + // Toggle night mode. + nightMode = !nightMode; + + // Enable or disable JavaScript according to night mode, the global preference, and any domain settings. + 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. + // 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. + // Get a handle for the shared preference. + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + // Get the JavaScript preference. + javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false); + } + + // Apply the JavaScript setting to the WebView. + mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled); + + // Update the privacy icons. + updatePrivacyIcons(false); + + // Reload the website. + mainWebView.reload(); + return true; + + case R.id.view_source: + // Launch the View Source activity. + Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class); + startActivity(viewSourceIntent); + return true; + case R.id.share: // Setup the share string. String shareString = webViewTitle + " – " + urlTextBox.getText().toString(); @@ -2500,7 +2794,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return true; case R.id.refresh: - mainWebView.reload(); + if (menuItem.getTitle().equals(getString(R.string.refresh))) { // The refresh button was pushed. + // Reload the WebView. + mainWebView.reload(); + } else { // The stop button was pushed. + // Stop the loading of the WebView. + mainWebView.stopLoading(); + } return true; case R.id.ad_consent: @@ -3517,8 +3817,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Apply the domain settings. applyDomainSettings(url, true, false); - // Set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website. - urlIsLoading = true; + // If loading a website, set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website. + urlIsLoading = !url.equals(""); // Load the URL. mainWebView.loadUrl(url, customHeaders); @@ -3744,8 +4044,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook favoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(favoriteIconBitmap, 64, 64, true)); } - // Initialize the database handler. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. - // The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. + // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); // Get a full cursor from `domainsDatabaseHelper`. @@ -3800,7 +4099,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Store the general preference information. String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100"); String defaultUserAgentName = sharedPreferences.getString("user_agent", "Privacy Browser"); - String defaultCustomUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"); + defaultCustomUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"); boolean defaultSwipeToRefresh = sharedPreferences.getBoolean("swipe_to_refresh", true); nightMode = sharedPreferences.getBoolean("night_mode", false); @@ -3847,7 +4146,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook break; } - // Set `javaScriptEnabled` to be `true` if `night_mode` is `true`. + // Store the domain JavaScript status. This is used by the options menu night mode toggle. + domainSettingsJavaScriptEnabled = javaScriptEnabled; + + // Enable JavaScript if night mode is enabled. if (nightMode) { javaScriptEnabled = true; }