// AppCompatActivity from android.support.v7.app.AppCompatActivity must be used to have access to the SupportActionBar until the minimum API is >= 21.
public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener,
- CreateHomeScreenShortcutDialog.CreateHomeScreenSchortcutListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener,
+ CreateHomeScreenShortcutDialog.CreateHomeScreenShortcutListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener,
DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener, EditBookmarkFolderDialog.EditBookmarkFolderListener,
HttpAuthenticationDialog.HttpAuthenticationListener, NavigationView.OnNavigationItemSelectedListener, PinnedSslCertificateMismatchDialog.PinnedSslCertificateMismatchListener,
SslCertificateErrorDialog.SslCertificateErrorListener, UrlHistoryDialog.UrlHistoryListener {
// and `OrbotProxyHelper`. It is also used in `onCreate()`, `applyAppSettings()`, `applyDomainSettings()`, and `updatePrivacyIcons()`.
public static boolean darkTheme;
+ // `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()`, `onCreateHomeScreenShortcutCreate()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `applyDomainSettings()`.
// `domStorageEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`.
private boolean domStorageEnabled;
- // `saveFormDataEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`.
+ // `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()`.
// Remove Android Studio's warning about deprecations. We have to use the deprecated `getColor()` until API >= 23.
@SuppressWarnings("deprecation")
protected void onCreate(Bundle savedInstanceState) {
- // Get a handle for `sharedPreferences`. `this` references the current context.
+ // Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- // Get the theme preference.
+ // Get the theme and screenshot preferences.
darkTheme = sharedPreferences.getBoolean("dark_theme", false);
+ allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
+
+ // Disable screenshots if not allowed.
+ if (!allowScreenshots) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ }
// Set the activity theme.
if (darkTheme) {
firstPartyCookiesEnabled = false;
thirdPartyCookiesEnabled = false;
domStorageEnabled = false;
- saveFormDataEnabled = false;
+ saveFormDataEnabled = false; // Form data can be removed once the minimum API >= 26.
nightMode = false;
// Initialize the WebView title.
MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies);
MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage);
- MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data);
+ 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);
+ MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
- // Only display third-party cookies if SDK >= 21
+ // Only display third-party cookies if API >= 21
toggleThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
+ // Only display the form data menu items if the API < 26.
+ toggleSaveFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
+ clearFormDataMenuItem.setVisible(Build.VERSION.SDK_INT < 26);
+
+ // 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.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- // Set the status of the additional app bar icons. The default is `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)) {
toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
toggleDomStorageMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- toggleSaveFormDataMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
} else { //Do not display the additional icons.
toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
toggleDomStorageMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- toggleSaveFormDataMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ refreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
return true;
MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies);
MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage);
- MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data);
+ MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data); // Form data can be removed once the minimum API >= 26.
MenuItem clearDataMenuItem = menu.findItem(R.id.clear_data);
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);
+ MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data); // Form data can be removed once the minimum API >= 26.
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 adConsentMenuItem = menu.findItem(R.id.ad_consent);
// Set the text for the domain menu item.
if (domainSettingsApplied) {
toggleFirstPartyCookiesMenuItem.setChecked(firstPartyCookiesEnabled);
toggleThirdPartyCookiesMenuItem.setChecked(thirdPartyCookiesEnabled);
toggleDomStorageMenuItem.setChecked(domStorageEnabled);
- toggleSaveFormDataMenuItem.setChecked(saveFormDataEnabled);
+ toggleSaveFormDataMenuItem.setChecked(saveFormDataEnabled); // Form data can be removed once the minimum API >= 26.
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically());
// Enable `Clear DOM Storage` if there is any.
clearDOMStorageMenuItem.setEnabled(localStorageDirectoryNumberOfFiles > 0 || indexedDBDirectoryNumberOfFiles > 0);
- // Enable `Clear Form Data` is there is any.
- WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
- clearFormDataMenuItem.setEnabled(mainWebViewDatabase.hasFormData());
+ // Enable `Clear Form Data` is there is any. This can be removed once the minimum API >= 26.
+ if (Build.VERSION.SDK_INT < 26) {
+ WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
+ clearFormDataMenuItem.setEnabled(mainWebViewDatabase.hasFormData());
+ }
// Enable `Clear Data` if any of the submenu items are enabled.
clearDataMenuItem.setEnabled(clearCookiesMenuItem.isEnabled() || clearDOMStorageMenuItem.isEnabled() || clearFormDataMenuItem.isEnabled());
fontSizeMenuItem.setTitle(fontSizeTitle);
selectedFontSizeMenuItem.setChecked(true);
- // Only show Ad Consent if this is the free flavor.
- adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free"));
-
// Run all the other default commands.
super.onPrepareOptionsMenu(menu);
mainWebView.reload();
return true;
+ // Form data can be removed once the minimum API >= 26.
case R.id.toggle_save_form_data:
// Switch the status of saveFormDataEnabled.
saveFormDataEnabled = !saveFormDataEnabled;
.show();
return true;
+ // Form data can be remove once the minimum API >= 26.
case R.id.clear_form_data:
Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_deleted, Snackbar.LENGTH_LONG)
.setAction(R.string.undo, v -> {
}
}
- // Clear form data.
- if (clearEverything || sharedPreferences.getBoolean("clear_form_data", true)) {
+ // Clear form data if the API < 26.
+ if ((Build.VERSION.SDK_INT < 26) && (clearEverything || sharedPreferences.getBoolean("clear_form_data", true))) {
WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(this);
webViewDatabase.clearFormData();
firstPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1);
thirdPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1);
domStorageEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1);
+ // Form data can be removed once the minimum API >= 26.
saveFormDataEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1);
easyListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST)) == 1);
easyPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1);
mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
- mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+
+ // Apply the form data setting if the API < 26.
+ if (Build.VERSION.SDK_INT < 26) {
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+ }
// Apply the font size.
if (fontSize == 0) { // Apply the default font size.
firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
- saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
+ saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false); // Form data can be removed once the minimum API >= 26.
easyListEnabled = sharedPreferences.getBoolean("easylist", true);
easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true);
fanboysAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true);
mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
- mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
mainWebView.getSettings().setTextZoom(Integer.valueOf(defaultFontSizeString));
swipeRefreshLayout.setEnabled(defaultSwipeToRefresh);
+ // Apply the form data setting if the API < 26.
+ if (Build.VERSION.SDK_INT < 26) {
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+ }
+
// Reset the pinned SSL certificate information.
domainSettingsDatabaseId = -1;
pinnedDomainSslCertificate = false;
}
private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) {
- // Get handles for the icons.
- MenuItem privacyIconMenuItem = mainMenu.findItem(R.id.toggle_javascript);
- MenuItem firstPartyCookiesIconMenuItem = mainMenu.findItem(R.id.toggle_first_party_cookies);
- MenuItem domStorageIconMenuItem = mainMenu.findItem(R.id.toggle_dom_storage);
- MenuItem formDataIconMenuItem = mainMenu.findItem(R.id.toggle_save_form_data);
+ // Get handles for the menu items.
+ MenuItem privacyMenuItem = mainMenu.findItem(R.id.toggle_javascript);
+ MenuItem firstPartyCookiesMenuItem = mainMenu.findItem(R.id.toggle_first_party_cookies);
+ MenuItem domStorageMenuItem = mainMenu.findItem(R.id.toggle_dom_storage);
+ MenuItem refreshMenuItem = mainMenu.findItem(R.id.refresh);
- // Update `privacyIcon`.
+ // Update the privacy icon.
if (javaScriptEnabled) { // JavaScript is enabled.
- privacyIconMenuItem.setIcon(R.drawable.javascript_enabled);
+ privacyMenuItem.setIcon(R.drawable.javascript_enabled);
} else if (firstPartyCookiesEnabled) { // JavaScript is disabled but cookies are enabled.
- privacyIconMenuItem.setIcon(R.drawable.warning);
+ privacyMenuItem.setIcon(R.drawable.warning);
} else { // All the dangerous features are disabled.
- privacyIconMenuItem.setIcon(R.drawable.privacy_mode);
+ privacyMenuItem.setIcon(R.drawable.privacy_mode);
}
- // Update `firstPartyCookiesIcon`.
+ // Update the first-party cookies icon.
if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
- firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_enabled);
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
} else { // First-party cookies are disabled.
if (darkTheme) {
- firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled_dark);
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_dark);
} else {
- firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled_light);
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_light);
}
}
- // Update `domStorageIcon`.
+ // Update the DOM storage icon.
if (javaScriptEnabled && domStorageEnabled) { // Both JavaScript and DOM storage are enabled.
- domStorageIconMenuItem.setIcon(R.drawable.dom_storage_enabled);
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_enabled);
} else if (javaScriptEnabled) { // JavaScript is enabled but DOM storage is disabled.
if (darkTheme) {
- domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled_dark);
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_dark);
} else {
- domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled_light);
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_light);
}
} else { // JavaScript is disabled, so DOM storage is ghosted.
if (darkTheme) {
- domStorageIconMenuItem.setIcon(R.drawable.dom_storage_ghosted_dark);
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_dark);
} else {
- domStorageIconMenuItem.setIcon(R.drawable.dom_storage_ghosted_light);
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_light);
}
}
- // Update `formDataIcon`.
- if (saveFormDataEnabled) { // Form data is enabled.
- formDataIconMenuItem.setIcon(R.drawable.form_data_enabled);
- } else { // Form data is disabled.
- if (darkTheme) {
- formDataIconMenuItem.setIcon(R.drawable.form_data_disabled_dark);
- } else {
- formDataIconMenuItem.setIcon(R.drawable.form_data_disabled_light);
- }
+ // Update the refresh icon.
+ if (darkTheme) {
+ refreshMenuItem.setIcon(R.drawable.refresh_enabled_dark);
+ } else {
+ refreshMenuItem.setIcon(R.drawable.refresh_enabled_light);
}
// `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.