+ // Get the current tab position.
+ int currentTabPosition = tabLayout.getSelectedTabPosition();
+
+ // Store the saved states in the bundle.
+ savedInstanceState.putParcelableArrayList(SAVED_STATE_ARRAY_LIST, savedStateArrayList);
+ savedInstanceState.putParcelableArrayList(SAVED_NESTED_SCROLL_WEBVIEW_STATE_ARRAY_LIST, savedNestedScrollWebViewStateArrayList);
+ savedInstanceState.putInt(SAVED_TAB_POSITION, currentTabPosition);
+ savedInstanceState.putString(PROXY_MODE, proxyMode);
+ }
+
+ @Override
+ public void onDestroy() {
+ // Unregister the orbot status broadcast receiver if it exists.
+ if (orbotStatusBroadcastReceiver != null) {
+ this.unregisterReceiver(orbotStatusBroadcastReceiver);
+ }
+
+ // Close the bookmarks cursor if it exists.
+ if (bookmarksCursor != null) {
+ bookmarksCursor.close();
+ }
+
+ // Close the bookmarks database if it exists.
+ if (bookmarksDatabaseHelper != null) {
+ bookmarksDatabaseHelper.close();
+ }
+
+ // Stop populating the blocklists if the AsyncTask is running in the background.
+ if (populateBlocklists != null) {
+ populateBlocklists.cancel(true);
+ }
+
+ // Run the default commands.
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu. This adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.webview_options_menu, menu);
+
+ // Store a handle for the options menu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons()`.
+ optionsMenu = menu;
+
+ // Get handles for the class menu items.
+ optionsPrivacyMenuItem = menu.findItem(R.id.javascript);
+ optionsRefreshMenuItem = menu.findItem(R.id.refresh);
+ optionsCookiesMenuItem = menu.findItem(R.id.cookies);
+ optionsDomStorageMenuItem = menu.findItem(R.id.dom_storage);
+ optionsSaveFormDataMenuItem = menu.findItem(R.id.save_form_data); // Form data can be removed once the minimum API >= 26.
+ optionsClearDataMenuItem = menu.findItem(R.id.clear_data);
+ optionsClearCookiesMenuItem = menu.findItem(R.id.clear_cookies);
+ optionsClearDomStorageMenuItem = menu.findItem(R.id.clear_dom_storage);
+ optionsClearFormDataMenuItem = menu.findItem(R.id.clear_form_data); // Form data can be removed once the minimum API >= 26.
+ optionsBlocklistsMenuItem = menu.findItem(R.id.blocklists);
+ optionsEasyListMenuItem = menu.findItem(R.id.easylist);
+ optionsEasyPrivacyMenuItem = menu.findItem(R.id.easyprivacy);
+ optionsFanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list);
+ optionsFanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list);
+ optionsUltraListMenuItem = menu.findItem(R.id.ultralist);
+ optionsUltraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy);
+ optionsBlockAllThirdPartyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests);
+ optionsProxyMenuItem = menu.findItem(R.id.proxy);
+ optionsProxyNoneMenuItem = menu.findItem(R.id.proxy_none);
+ optionsProxyTorMenuItem = menu.findItem(R.id.proxy_tor);
+ optionsProxyI2pMenuItem = menu.findItem(R.id.proxy_i2p);
+ optionsProxyCustomMenuItem = menu.findItem(R.id.proxy_custom);
+ optionsUserAgentMenuItem = menu.findItem(R.id.user_agent);
+ optionsUserAgentPrivacyBrowserMenuItem = menu.findItem(R.id.user_agent_privacy_browser);
+ optionsUserAgentWebViewDefaultMenuItem = menu.findItem(R.id.user_agent_webview_default);
+ optionsUserAgentFirefoxOnAndroidMenuItem = menu.findItem(R.id.user_agent_firefox_on_android);
+ optionsUserAgentChromeOnAndroidMenuItem = menu.findItem(R.id.user_agent_chrome_on_android);
+ optionsUserAgentSafariOnIosMenuItem = menu.findItem(R.id.user_agent_safari_on_ios);
+ optionsUserAgentFirefoxOnLinuxMenuItem = menu.findItem(R.id.user_agent_firefox_on_linux);
+ optionsUserAgentChromiumOnLinuxMenuItem = menu.findItem(R.id.user_agent_chromium_on_linux);
+ optionsUserAgentFirefoxOnWindowsMenuItem = menu.findItem(R.id.user_agent_firefox_on_windows);
+ optionsUserAgentChromeOnWindowsMenuItem = menu.findItem(R.id.user_agent_chrome_on_windows);
+ optionsUserAgentEdgeOnWindowsMenuItem = menu.findItem(R.id.user_agent_edge_on_windows);
+ optionsUserAgentInternetExplorerOnWindowsMenuItem = menu.findItem(R.id.user_agent_internet_explorer_on_windows);
+ optionsUserAgentSafariOnMacosMenuItem = menu.findItem(R.id.user_agent_safari_on_macos);
+ optionsUserAgentCustomMenuItem = menu.findItem(R.id.user_agent_custom);
+ optionsSwipeToRefreshMenuItem = menu.findItem(R.id.swipe_to_refresh);
+ optionsWideViewportMenuItem = menu.findItem(R.id.wide_viewport);
+ optionsDisplayImagesMenuItem = menu.findItem(R.id.display_images);
+ optionsDarkWebViewMenuItem = menu.findItem(R.id.dark_webview);
+ optionsFontSizeMenuItem = menu.findItem(R.id.font_size);
+ optionsAddOrEditDomainMenuItem = menu.findItem(R.id.add_or_edit_domain);
+
+ // Get handles for the method menu items.
+ MenuItem bookmarksMenuItem = menu.findItem(R.id.bookmarks);
+ MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
+
+ // Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(false);
+
+ // Only display the form data menu items if the API < 26.
+ optionsSaveFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
+ optionsClearFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
+
+ // Disable the clear form data menu item if the API >= 26 so that the status of the main Clear Data is calculated correctly.
+ optionsClearFormDataMenuItem.setEnabled(Build.VERSION.SDK_INT < 26);
+
+ // Only display the dark WebView menu item if API >= 21.
+ optionsDarkWebViewMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
+
+ // Only show Ad Consent if this is the free flavor.
+ adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free"));
+
+ // Get the shared preferences.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ // Get the dark theme and app bar preferences.
+ boolean displayAdditionalAppBarIcons = sharedPreferences.getBoolean(getString(R.string.display_additional_app_bar_icons_key), 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 (displayAdditionalAppBarIcons) {
+ optionsRefreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ bookmarksMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ optionsCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ } else { //Do not display the additional icons.
+ optionsRefreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ bookmarksMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ optionsCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ }
+
+ // Replace Refresh with Stop if a URL is already loading.
+ if (currentWebView != null && currentWebView.getProgress() != 100) {
+ // Set the title.
+ optionsRefreshMenuItem.setTitle(R.string.stop);
+
+ // Set the icon if it is displayed in the app bar.
+ if (displayAdditionalAppBarIcons) {
+ // Get the current theme status.
+ int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+
+ // Set the icon according to the current theme status.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
+ optionsRefreshMenuItem.setIcon(R.drawable.close_blue_day);
+ } else {
+ optionsRefreshMenuItem.setIcon(R.drawable.close_blue_night);