+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.easyprivacy) { // EasyPrivacy.
+ // Toggle the EasyPrivacy status.
+ currentWebView.setEasyPrivacyEnabled(!currentWebView.getEasyPrivacyEnabled());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getEasyPrivacyEnabled());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.fanboys_annoyance_list) { // Fanboy's Annoyance List.
+ // Toggle Fanboy's Annoyance List status.
+ currentWebView.setFanboysAnnoyanceListEnabled(!currentWebView.getFanboysAnnoyanceListEnabled());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getFanboysAnnoyanceListEnabled());
+
+ // Update the status of Fanboy's Social Blocking List.
+ optionsFanboysSocialBlockingListMenuItem.setEnabled(!currentWebView.getFanboysAnnoyanceListEnabled());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.fanboys_social_blocking_list) { // Fanboy's Social Blocking List.
+ // Toggle Fanboy's Social Blocking List status.
+ currentWebView.setFanboysSocialBlockingListEnabled(!currentWebView.getFanboysSocialBlockingListEnabled());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getFanboysSocialBlockingListEnabled());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.ultralist) { // UltraList.
+ // Toggle the UltraList status.
+ currentWebView.setUltraListEnabled(!currentWebView.getUltraListEnabled());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getUltraListEnabled());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.ultraprivacy) { // UltraPrivacy.
+ // Toggle the UltraPrivacy status.
+ currentWebView.setUltraPrivacyEnabled(!currentWebView.getUltraPrivacyEnabled());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getUltraPrivacyEnabled());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.block_all_third_party_requests) { // Block all third-party requests.
+ //Toggle the third-party requests blocker status.
+ currentWebView.setBlockAllThirdPartyRequests(!currentWebView.getBlockAllThirdPartyRequests());
+
+ // Update the menu checkbox.
+ menuItem.setChecked(currentWebView.getBlockAllThirdPartyRequests());
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.proxy_none) { // Proxy - None.
+ // Update the proxy mode.
+ proxyMode = ProxyHelper.NONE;
+
+ // Apply the proxy mode.
+ applyProxy(true);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.proxy_tor) { // Proxy - Tor.
+ // Update the proxy mode.
+ proxyMode = ProxyHelper.TOR;
+
+ // Apply the proxy mode.
+ applyProxy(true);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.proxy_i2p) { // Proxy - I2P.
+ // Update the proxy mode.
+ proxyMode = ProxyHelper.I2P;
+
+ // Apply the proxy mode.
+ applyProxy(true);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.proxy_custom) { // Proxy - Custom.
+ // Update the proxy mode.
+ proxyMode = ProxyHelper.CUSTOM;
+
+ // Apply the proxy mode.
+ applyProxy(true);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_privacy_browser) { // User Agent - Privacy Browser.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[0]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_webview_default) { // User Agent - WebView Default.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString("");
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_firefox_on_android) { // User Agent - Firefox on Android.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[2]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_chrome_on_android) { // User Agent - Chrome on Android.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[3]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_safari_on_ios) { // User Agent - Safari on iOS.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[4]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_firefox_on_linux) { // User Agent - Firefox on Linux.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[5]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_chromium_on_linux) { // User Agent - Chromium on Linux.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[6]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_firefox_on_windows) { // User Agent - Firefox on Windows.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[7]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_chrome_on_windows) { // User Agent - Chrome on Windows.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[8]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_edge_on_windows) { // User Agent - Edge on Windows.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[9]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_internet_explorer_on_windows) { // User Agent - Internet Explorer on Windows.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[10]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_safari_on_macos) { // User Agent - Safari on macOS.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(getResources().getStringArray(R.array.user_agent_data)[11]);
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.user_agent_custom) { // User Agent - Custom.
+ // Update the user agent.
+ currentWebView.getSettings().setUserAgentString(sharedPreferences.getString(getString(R.string.custom_user_agent_key), getString(R.string.custom_user_agent_default_value)));
+
+ // Reload the current WebView.
+ currentWebView.reload();
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.font_size) { // Font size.
+ // Instantiate the font size dialog.
+ DialogFragment fontSizeDialogFragment = FontSizeDialog.displayDialog(currentWebView.getSettings().getTextZoom());
+
+ // Show the font size dialog.
+ fontSizeDialogFragment.show(getSupportFragmentManager(), getString(R.string.font_size));
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.swipe_to_refresh) { // Swipe to refresh.
+ // Toggle the stored status of swipe to refresh.
+ currentWebView.setSwipeToRefresh(!currentWebView.getSwipeToRefresh());
+
+ // Update the swipe refresh layout.
+ if (currentWebView.getSwipeToRefresh()) { // Swipe to refresh is enabled.
+ // Only enable the swipe refresh layout if the WebView is scrolled to the top. It is updated every time the scroll changes.
+ swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
+ } else { // Swipe to refresh is disabled.
+ // Disable the swipe refresh layout.
+ swipeRefreshLayout.setEnabled(false);
+ }
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.wide_viewport) { // Wide viewport.
+ // Toggle the viewport.
+ currentWebView.getSettings().setUseWideViewPort(!currentWebView.getSettings().getUseWideViewPort());
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.display_images) { // Display images.
+ // Toggle the displaying of images.
+ if (currentWebView.getSettings().getLoadsImagesAutomatically()) { // Images are currently loaded automatically.
+ // Disable loading of images.
+ currentWebView.getSettings().setLoadsImagesAutomatically(false);
+
+ // Reload the website to remove existing images.
+ currentWebView.reload();
+ } else { // Images are not currently loaded automatically.
+ // Enable loading of images. Missing images will be loaded without the need for a reload.
+ currentWebView.getSettings().setLoadsImagesAutomatically(true);
+ }
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.dark_webview) { // Dark WebView.
+ // Check to see if dark WebView is supported by this WebView.
+ if ((Build.VERSION.SDK_INT >= 33) && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { // The device is running API >= 33 and algorithmic darkening is supported.
+ // Toggle algorithmic darkening.
+ WebSettingsCompat.setAlgorithmicDarkeningAllowed(currentWebView.getSettings(), !WebSettingsCompat.isAlgorithmicDarkeningAllowed(currentWebView.getSettings()));
+ } else if ((Build.VERSION.SDK_INT < 33) && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { // The device is running API < 33 and the WebView supports force dark.
+ // Toggle the dark WebView setting.
+ //noinspection deprecation
+ if (WebSettingsCompat.getForceDark(currentWebView.getSettings()) == WebSettingsCompat.FORCE_DARK_ON) { // Dark WebView is currently enabled.
+ // Turn off dark WebView.
+ //noinspection deprecation
+ WebSettingsCompat.setForceDark(currentWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
+ } else { // Dark WebView is currently disabled.
+ // Turn on dark WebView.
+ //noinspection deprecation
+ WebSettingsCompat.setForceDark(currentWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
+ }
+ }
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.find_on_page) { // Find on page.
+ // Get a handle for the views.
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
+ EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext);
+
+ // Set the minimum height of the find on page linear layout to match the toolbar.
+ findOnPageLinearLayout.setMinimumHeight(toolbar.getHeight());
+
+ // Hide the toolbar.
+ toolbar.setVisibility(View.GONE);
+
+ // Show the find on page linear layout.
+ findOnPageLinearLayout.setVisibility(View.VISIBLE);
+
+ // Display the keyboard. The app must wait 200 ms before running the command to work around a bug in Android.
+ // http://stackoverflow.com/questions/5520085/android-show-softkeyboard-with-showsoftinput-is-not-working
+ findOnPageEditText.postDelayed(() -> {
+ // Set the focus on the find on page edit text.
+ findOnPageEditText.requestFocus();
+
+ // Get a handle for the input method manager.
+ InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ // Remove the lint warning below that the input method manager might be null.
+ assert inputMethodManager != null;
+
+ // Display the keyboard. `0` sets no input flags.
+ inputMethodManager.showSoftInput(findOnPageEditText, 0);
+ }, 200);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.print) { // Print.
+ // Get a print manager instance.
+ PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
+
+ // Remove the lint error below that print manager might be null.
+ assert printManager != null;
+
+ // Create a print document adapter from the current WebView.
+ PrintDocumentAdapter printDocumentAdapter = currentWebView.createPrintDocumentAdapter(getString(R.string.print));
+
+ // Print the document.
+ printManager.print(getString(R.string.privacy_browser_webpage), printDocumentAdapter, null);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.save_url) { // Save URL.
+ // Check the download preference.
+ if (downloadWithExternalApp) { // Download with an external app.
+ downloadUrlWithExternalApp(currentWebView.getCurrentUrl());
+ } else { // Handle the download inside of Privacy Browser.
+ // Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
+ new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
+ currentWebView.getAcceptCookies()).execute(currentWebView.getCurrentUrl());
+ }
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.save_archive) {
+ // Open the file picker with a default file name built from the current domain name.
+ saveWebpageArchiveActivityResultLauncher.launch(currentWebView.getCurrentDomainName() + ".mht");
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.save_image) { // Save image.
+ // Open the file picker with a default file name built from the current domain name.
+ saveWebpageImageActivityResultLauncher.launch(currentWebView.getCurrentDomainName() + ".png");
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.add_to_homescreen) { // Add to homescreen.
+ // Instantiate the create home screen shortcut dialog.
+ DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), currentWebView.getUrl(),
+ currentWebView.getFavoriteOrDefaultIcon());
+
+ // Show the create home screen shortcut dialog.
+ createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.view_source) { // View source.
+ // Create an intent to launch the view source activity.
+ Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class);
+
+ // Add the variables to the intent.
+ viewSourceIntent.putExtra(ViewSourceActivityKt.CURRENT_URL, currentWebView.getUrl());
+ viewSourceIntent.putExtra(ViewSourceActivityKt.USER_AGENT, currentWebView.getSettings().getUserAgentString());
+
+ // Make it so.
+ startActivity(viewSourceIntent);
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.share_message) { // Share a message.
+ // Prepare the share string.
+ String shareString = currentWebView.getTitle() + " – " + currentWebView.getUrl();
+
+ // Create the share intent.
+ Intent shareMessageIntent = new Intent(Intent.ACTION_SEND);
+
+ // Add the share string to the intent.
+ shareMessageIntent.putExtra(Intent.EXTRA_TEXT, shareString);
+
+ // Set the MIME type.
+ shareMessageIntent.setType("text/plain");
+
+ // Set the intent to open in a new task.
+ shareMessageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Make it so.
+ startActivity(Intent.createChooser(shareMessageIntent, getString(R.string.share_message)));
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.share_url) { // Share URL.
+ // Create the share intent.
+ Intent shareUrlIntent = new Intent(Intent.ACTION_SEND);
+
+ // Add the URL to the intent.
+ shareUrlIntent.putExtra(Intent.EXTRA_TEXT, currentWebView.getUrl());
+
+ // Add the title to the intent.
+ shareUrlIntent.putExtra(Intent.EXTRA_SUBJECT, currentWebView.getTitle());
+
+ // Set the MIME type.
+ shareUrlIntent.setType("text/plain");
+
+ // Set the intent to open in a new task.
+ shareUrlIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ //Make it so.
+ startActivity(Intent.createChooser(shareUrlIntent, getString(R.string.share_url)));
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.open_with_app) { // Open with app.
+ // Open the URL with an outside app.
+ openWithApp(currentWebView.getUrl());
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.open_with_browser) { // Open with browser.
+ // Open the URL with an outside browser.
+ openWithBrowser(currentWebView.getUrl());
+
+ // Consume the event.
+ return true;
+ } else if (menuItemId == R.id.add_or_edit_domain) { // Add or edit domain.
+ // Reapply the domain settings on returning to `MainWebViewActivity`.
+ reapplyDomainSettingsOnRestart = true;
+
+ // Check if domain settings currently exist.
+ if (currentWebView.getDomainSettingsApplied()) { // Edit the current domain settings.
+ // Create an intent to launch the domains activity.
+ Intent domainsIntent = new Intent(this, DomainsActivity.class);
+
+ // Add the extra information to the intent.
+ domainsIntent.putExtra(DomainsActivity.LOAD_DOMAIN, currentWebView.getDomainSettingsDatabaseId());
+ domainsIntent.putExtra(DomainsActivity.CLOSE_ON_BACK, true);
+ domainsIntent.putExtra(DomainsActivity.CURRENT_URL, currentWebView.getUrl());
+ domainsIntent.putExtra(DomainsActivity.CURRENT_IP_ADDRESSES, currentWebView.getCurrentIpAddresses());
+
+ // Get the current certificate.
+ SslCertificate sslCertificate = currentWebView.getCertificate();
+
+ // Check to see if the SSL certificate is populated.
+ if (sslCertificate != null) {
+ // Extract the certificate to strings.
+ String issuedToCName = sslCertificate.getIssuedTo().getCName();
+ String issuedToOName = sslCertificate.getIssuedTo().getOName();
+ String issuedToUName = sslCertificate.getIssuedTo().getUName();
+ String issuedByCName = sslCertificate.getIssuedBy().getCName();
+ String issuedByOName = sslCertificate.getIssuedBy().getOName();
+ String issuedByUName = sslCertificate.getIssuedBy().getUName();
+ long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
+ long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
+
+ // Add the certificate to the intent.
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_TO_CNAME, issuedToCName);
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_TO_ONAME, issuedToOName);
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_TO_UNAME, issuedToUName);
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_BY_CNAME, issuedByCName);
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_BY_ONAME, issuedByOName);
+ domainsIntent.putExtra(DomainsActivity.SSL_ISSUED_BY_UNAME, issuedByUName);
+ domainsIntent.putExtra(DomainsActivity.SSL_START_DATE, startDateLong);
+ domainsIntent.putExtra(DomainsActivity.SSL_END_DATE, endDateLong);