import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.print.PrintDocumentAdapter;
import android.print.PrintManager;
+import android.provider.DocumentsContract;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.webkit.WebViewClient;
import android.webkit.WebViewDatabase;
import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
private MenuItem navigationRequestsMenuItem;
private MenuItem optionsPrivacyMenuItem;
private MenuItem optionsRefreshMenuItem;
- private MenuItem optionsFirstPartyCookiesMenuItem;
- private MenuItem optionsThirdPartyCookiesMenuItem;
+ private MenuItem optionsCookiesMenuItem;
private MenuItem optionsDomStorageMenuItem;
private MenuItem optionsSaveFormDataMenuItem;
private MenuItem optionsClearDataMenuItem;
// Get handles for the class menu items.
optionsPrivacyMenuItem = menu.findItem(R.id.javascript);
optionsRefreshMenuItem = menu.findItem(R.id.refresh);
- optionsFirstPartyCookiesMenuItem = menu.findItem(R.id.first_party_cookies);
- optionsThirdPartyCookiesMenuItem = menu.findItem(R.id.third_party_cookies);
+ 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);
// Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
updatePrivacyIcons(false);
- // Only display third-party cookies if API >= 21
- optionsThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
-
// 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);
if (displayAdditionalAppBarIcons) {
optionsRefreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
bookmarksMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- optionsFirstPartyCookiesMenuItem.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);
- optionsFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ optionsCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
// Replace Refresh with Stop if a URL is already loading.
optionsUltraPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRAPRIVACY) + " - " + getString(R.string.ultraprivacy));
optionsBlockAllThirdPartyRequestsMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " + getString(R.string.block_all_third_party_requests));
- // Only modify third-party cookies if the API >= 21.
- if (Build.VERSION.SDK_INT >= 21) {
- // Set the status of the third-party cookies checkbox.
- optionsThirdPartyCookiesMenuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
-
- // Enable third-party cookies if first-party cookies are enabled.
- optionsThirdPartyCookiesMenuItem.setEnabled(cookieManager.acceptCookie());
- }
-
// Enable DOM Storage if JavaScript is enabled.
optionsDomStorageMenuItem.setEnabled(currentWebView.getSettings().getJavaScriptEnabled());
}
}
- // Set the checked status of the first party cookies menu item.
- optionsFirstPartyCookiesMenuItem.setChecked(cookieManager.acceptCookie());
+ // Set the cookies menu item checked status.
+ optionsCookiesMenuItem.setChecked(cookieManager.acceptCookie());
// Enable Clear Cookies if there are any.
optionsClearCookiesMenuItem.setEnabled(cookieManager.hasCookies());
// Consume the event.
return true;
- } else if (menuItemId == R.id.first_party_cookies) { // First-party cookies.
+ } else if (menuItemId == R.id.cookies) { // Cookies.
// Switch the first-party cookie status.
cookieManager.setAcceptCookie(!cookieManager.acceptCookie());
- // Store the first-party cookie status.
- currentWebView.setAcceptFirstPartyCookies(cookieManager.acceptCookie());
+ // Store the cookie status.
+ currentWebView.setAcceptCookies(cookieManager.acceptCookie());
// Update the menu checkbox.
menuItem.setChecked(cookieManager.acceptCookie());
updatePrivacyIcons(true);
// Display a snackbar.
- if (cookieManager.acceptCookie()) { // First-party cookies are enabled.
- Snackbar.make(webViewPager, R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
+ if (cookieManager.acceptCookie()) { // Cookies are enabled.
+ Snackbar.make(webViewPager, R.string.cookies_enabled, Snackbar.LENGTH_SHORT).show();
} else if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScript is still enabled.
- Snackbar.make(webViewPager, R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
+ Snackbar.make(webViewPager, R.string.cookies_disabled, Snackbar.LENGTH_SHORT).show();
} else { // Privacy mode.
Snackbar.make(webViewPager, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
}
// Reload the current WebView.
currentWebView.reload();
- // Consume the event.
- return true;
- } else if (menuItemId == R.id.third_party_cookies) { // Third-party cookies.
- // Only act if the API >= 21. Otherwise, there are no third-party cookie controls.
- if (Build.VERSION.SDK_INT >= 21) {
- // Toggle the status of thirdPartyCookiesEnabled.
- cookieManager.setAcceptThirdPartyCookies(currentWebView, !cookieManager.acceptThirdPartyCookies(currentWebView));
-
- // Update the menu checkbox.
- menuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
-
- // Display a snackbar.
- if (cookieManager.acceptThirdPartyCookies(currentWebView)) {
- Snackbar.make(webViewPager, R.string.third_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
- } else {
- Snackbar.make(webViewPager, R.string.third_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
- }
-
- // Reload the current WebView.
- currentWebView.reload();
- }
-
// Consume the event.
return true;
} else if (menuItemId == R.id.dom_storage) { // DOM storage.
} else if (menuItemId == R.id.save_url) { // Save URL.
// 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(), SaveWebpageDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptFirstPartyCookies()).execute(currentWebView.getCurrentUrl());
+ currentWebView.getAcceptCookies()).execute(currentWebView.getCurrentUrl());
// Consume the event.
return true;
- } else if (menuItemId == R.id.save_image) { // Save image.
+ } else if (menuItemId == R.id.save_archive) {
// Instantiate the save dialog.
- DialogFragment saveImageFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_IMAGE, null, null, getString(R.string.webpage_png), null,
+ DialogFragment saveArchiveFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_ARCHIVE, currentWebView.getCurrentUrl(), null, null, null,
false);
// Show the save dialog. It must be named `save_dialog` so that the file picker can update the file name.
- saveImageFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
+ saveArchiveFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
- // Consume the event.
return true;
- } else if (menuItemId == R.id.save_archive) {
- /* TODO.
- try {
- // Create an MHT file.
- File mhtFile = File.createTempFile("mht_file", ".mht", getCacheDir());
-
- // Populate the MHT file.
- currentWebView.saveWebArchive(mhtFile.toString());
-
- // Check the file length.
- Log.i("MHT", "MHT file size: " + mhtFile.length());
- } catch (Exception exception){
- Log.i("MHT", "MHT exception: " + exception.toString());
- }
+ } else if (menuItemId == R.id.save_image) { // Save image.
+ // Instantiate the save dialog.
+ DialogFragment saveImageFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_IMAGE, currentWebView.getCurrentUrl(), null, null, null,
+ false);
- */
+ // Show the save dialog. It must be named `save_dialog` so that the file picker can update the file name.
+ saveImageFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
+ // Consume the event.
return true;
} else if (menuItemId == R.id.add_to_homescreen) { // Add to homescreen.
// Instantiate the create home screen shortcut dialog.
// Make it so.
startActivity(requestsIntent);
} else if (menuItemId == R.id.downloads) { // Downloads.
- // Launch the system Download Manager.
- Intent downloadManagerIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
+ // Try the default system download manager.
+ try {
+ // Launch the default system Download Manager.
+ Intent defaultDownloadManagerIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
- // Launch as a new task so that Download Manager and Privacy Browser show as separate windows in the recent tasks list.
- downloadManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // Launch as a new task so that the download manager and Privacy Browser show as separate windows in the recent tasks list.
+ defaultDownloadManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- // Make it so.
- startActivity(downloadManagerIntent);
+ // Make it so.
+ startActivity(defaultDownloadManagerIntent);
+ } catch (Exception defaultDownloadManagerException) {
+ // Try a generic file manager.
+ try {
+ // Create a generic file manager intent.
+ Intent genericFileManagerIntent = new Intent(Intent.ACTION_VIEW);
+
+ // Open the download directory.
+ genericFileManagerIntent.setDataAndType(Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()), DocumentsContract.Document.MIME_TYPE_DIR);
+
+ // Launch as a new task so that the file manager and Privacy Browser show as separate windows in the recent tasks list.
+ genericFileManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Make it so.
+ startActivity(genericFileManagerIntent);
+ } catch (Exception genericFileManagerException) {
+ // Try an alternate file manager.
+ try {
+ // Create an alternate file manager intent.
+ Intent alternateFileManagerIntent = new Intent(Intent.ACTION_VIEW);
+
+ // Open the download directory.
+ alternateFileManagerIntent.setDataAndType(Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()), "resource/folder");
+
+ // Launch as a new task so that the file manager and Privacy Browser show as separate windows in the recent tasks list.
+ alternateFileManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Open the alternate file manager.
+ startActivity(alternateFileManagerIntent);
+ } catch (Exception alternateFileManagerException) {
+ // Display a snackbar.
+ Snackbar.make(currentWebView, R.string.no_file_manager_detected, Snackbar.LENGTH_INDEFINITE).show();
+ }
+ }
+ }
} else if (menuItemId == R.id.domains) { // Domains.
// Set the flag to reapply the domain settings on restart when returning from Domain Settings.
reapplyDomainSettingsOnRestart = true;
menu.add(R.string.save_url).setOnMenuItemClickListener((MenuItem item) -> {
// 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(), SaveWebpageDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptFirstPartyCookies()).execute(linkUrl);
+ currentWebView.getAcceptCookies()).execute(linkUrl);
// Consume the event.
return true;
menu.add(R.string.save_image).setOnMenuItemClickListener((MenuItem item) -> {
// 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(), SaveWebpageDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptFirstPartyCookies()).execute(imageUrl);
+ currentWebView.getAcceptCookies()).execute(imageUrl);
// Consume the event.
return true;
menu.add(R.string.save_image).setOnMenuItemClickListener((MenuItem item) -> {
// 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(), SaveWebpageDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptFirstPartyCookies()).execute(imageUrl);
+ currentWebView.getAcceptCookies()).execute(imageUrl);
// Consume the event.
return true;
menu.add(R.string.save_url).setOnMenuItemClickListener((MenuItem item) -> {
// 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(), SaveWebpageDialog.SAVE_URL, currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptFirstPartyCookies()).execute(linkUrl);
+ currentWebView.getAcceptCookies()).execute(linkUrl);
// Consume the event.
return true;
// Remove the incorrect lint warning below that the dialog might be null.
assert dialog != null;
- // Get a handle for the file name edit text.
+ // Get handles for the views.
EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
+ CheckBox mhtCheckBox = dialog.findViewById(R.id.mht_checkbox);
// Get the file path string.
String openFilePath = fileNameEditText.getText().toString();
// Apply the domain settings. This resets the favorite icon and removes any domain settings.
applyDomainSettings(currentWebView, openFilePath, true, false, false);
- // Open the file.
- currentWebView.loadUrl(openFilePath);
+ // Open the file according to the type.
+ if (mhtCheckBox.isChecked()) { // Force opening of an MHT file.
+ try {
+ // Get the MHT file input stream.
+ InputStream mhtFileInputStream = getContentResolver().openInputStream(Uri.parse(openFilePath));
+
+ // Create a temporary MHT file.
+ File temporaryMhtFile = File.createTempFile("temporary_mht_file", ".mht", getCacheDir());
+
+ // Get a file output stream for the temporary MHT file.
+ FileOutputStream temporaryMhtFileOutputStream = new FileOutputStream(temporaryMhtFile);
+
+ // Create a transfer byte array.
+ byte[] transferByteArray = new byte[1024];
+
+ // Create an integer to track the number of bytes read.
+ int bytesRead;
+
+ // Copy the temporary MHT file input stream to the MHT output stream.
+ while ((bytesRead = mhtFileInputStream.read(transferByteArray)) > 0) {
+ temporaryMhtFileOutputStream.write(transferByteArray, 0, bytesRead);
+ }
+
+ // Flush the temporary MHT file output stream.
+ temporaryMhtFileOutputStream.flush();
+
+ // Close the streams.
+ temporaryMhtFileOutputStream.close();
+ mhtFileInputStream.close();
+
+ // Load the temporary MHT file.
+ currentWebView.loadUrl(temporaryMhtFile.toString());
+ } catch (Exception exception) {
+ // Display a snackbar.
+ Snackbar.make(currentWebView, getString(R.string.error) + " " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show();
+ }
+ } else { // Let the WebView handle opening of the file.
+ // Open the file.
+ currentWebView.loadUrl(openFilePath);
+ }
}
@Override
- public void onSaveWebpage(int saveType, @Nullable String originalUrlString, DialogFragment dialogFragment) {
+ public void onSaveWebpage(int saveType, @NonNull String originalUrlString, DialogFragment dialogFragment) {
// Get the dialog.
Dialog dialog = dialogFragment.getDialog();
String saveWebpageUrl;
// Store the URL.
- if ((originalUrlString != null) && originalUrlString.startsWith("data:")) {
+ if (originalUrlString.startsWith("data:")) {
// Save the original URL.
saveWebpageUrl = originalUrlString;
} else {
}
// Save the URL.
- new SaveUrl(this, this, saveWebpageFilePath, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptFirstPartyCookies()).execute(saveWebpageUrl);
+ new SaveUrl(this, this, saveWebpageFilePath, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptCookies()).execute(saveWebpageUrl);
+ break;
+
+ case SaveWebpageDialog.SAVE_ARCHIVE:
+ try {
+ // Create a temporary MHT file.
+ File temporaryMhtFile = File.createTempFile("temporary_mht_file", ".mht", getCacheDir());
+
+ // Save the temporary MHT file.
+ currentWebView.saveWebArchive(temporaryMhtFile.toString(), false, callbackValue -> {
+ if (callbackValue != null) { // The temporary MHT file was saved successfully.
+ try {
+ // Create a temporary MHT file input stream.
+ FileInputStream temporaryMhtFileInputStream = new FileInputStream(temporaryMhtFile);
+
+ // Get an output stream for the save webpage file path.
+ OutputStream mhtOutputStream = getContentResolver().openOutputStream(Uri.parse(saveWebpageFilePath));
+
+ // Create a transfer byte array.
+ byte[] transferByteArray = new byte[1024];
+
+ // Create an integer to track the number of bytes read.
+ int bytesRead;
+
+ // Copy the temporary MHT file input stream to the MHT output stream.
+ while ((bytesRead = temporaryMhtFileInputStream.read(transferByteArray)) > 0) {
+ mhtOutputStream.write(transferByteArray, 0, bytesRead);
+ }
+
+ // Close the streams.
+ mhtOutputStream.close();
+ temporaryMhtFileInputStream.close();
+
+ // Display a snackbar.
+ Snackbar.make(currentWebView, getString(R.string.file_saved) + " " + currentWebView.getCurrentUrl(), Snackbar.LENGTH_SHORT).show();
+ } catch (Exception exception) {
+ // Display a snackbar with the exception.
+ Snackbar.make(currentWebView, getString(R.string.error_saving_file) + " " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show();
+ } finally {
+ // Delete the temporary MHT file.
+ //noinspection ResultOfMethodCallIgnored
+ temporaryMhtFile.delete();
+ }
+ } else { // There was an unspecified error while saving the temporary MHT file.
+ // Display an error snackbar.
+ Snackbar.make(currentWebView, getString(R.string.error_saving_file), Snackbar.LENGTH_INDEFINITE).show();
+ }
+ });
+ } catch (IOException ioException) {
+ // Display a snackbar with the IO exception.
+ Snackbar.make(currentWebView, getString(R.string.error_saving_file) + " " + ioException.toString(), Snackbar.LENGTH_INDEFINITE).show();
+ }
break;
case SaveWebpageDialog.SAVE_IMAGE:
// Store the values from the shared preferences in variables.
incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false);
- boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false);
sanitizeGoogleAnalytics = sharedPreferences.getBoolean("google_analytics", true);
sanitizeFacebookClickIds = sharedPreferences.getBoolean("facebook_click_ids", true);
sanitizeTwitterAmpRedirects = sharedPreferences.getBoolean("twitter_amp_redirects", true);
// Apply the proxy.
applyProxy(false);
- // Set Do Not Track status.
- if (doNotTrackEnabled) {
- customHeaders.put("DNT", "1");
- } else {
- customHeaders.remove("DNT");
- }
-
// Get the current layout parameters. Using coordinator layout parameters allows the `setBehavior()` command and using app bar layout parameters allows the `setScrollFlags()` command.
CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
// Get the settings from the cursor.
nestedScrollWebView.setDomainSettingsDatabaseId(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
nestedScrollWebView.getSettings().setJavaScriptEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1);
- nestedScrollWebView.setAcceptFirstPartyCookies(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1);
- boolean domainThirdPartyCookiesEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1);
+ nestedScrollWebView.setAcceptCookies(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.COOKIES)) == 1);
nestedScrollWebView.getSettings().setDomStorageEnabled(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1);
// Form data can be removed once the minimum API >= 26.
boolean saveFormData = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1);
}
// Apply the cookie domain settings.
- cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies());
-
- // Set third-party cookies status if API >= 21.
- if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, domainThirdPartyCookiesEnabled);
- }
+ cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptCookies());
// Apply the form data setting if the API < 26.
if (Build.VERSION.SDK_INT < 26) {
} else { // The new URL does not have custom domain settings. Load the defaults.
// Store the values from the shared preferences.
nestedScrollWebView.getSettings().setJavaScriptEnabled(sharedPreferences.getBoolean("javascript", false));
- nestedScrollWebView.setAcceptFirstPartyCookies(sharedPreferences.getBoolean("first_party_cookies", false));
- boolean defaultThirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies", false);
+ nestedScrollWebView.setAcceptCookies(sharedPreferences.getBoolean(getString(R.string.cookies_key), false));
nestedScrollWebView.getSettings().setDomStorageEnabled(sharedPreferences.getBoolean("dom_storage", false));
boolean saveFormData = sharedPreferences.getBoolean("save_form_data", false); // Form data can be removed once the minimum API >= 26.
nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASYLIST, sharedPreferences.getBoolean("easylist", true));
nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY, sharedPreferences.getBoolean("ultraprivacy", true));
nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean("block_all_third_party_requests", false));
- // Apply the default first-party cookie setting.
- cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies());
+ // Apply the default cookie setting.
+ cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptCookies());
// Apply the default font size setting.
try {
// Reset the pinned variables.
nestedScrollWebView.setDomainSettingsDatabaseId(-1);
- // Set third-party cookies status if API >= 21.
- if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, defaultThirdPartyCookiesEnabled);
- }
-
// Get the array position of the user agent name.
int userAgentArrayPosition = userAgentNamesArray.getPosition(defaultUserAgentName);
// Update the privacy icon.
if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScript is enabled.
optionsPrivacyMenuItem.setIcon(R.drawable.javascript_enabled);
- } else if (currentWebView.getAcceptFirstPartyCookies()) { // JavaScript is disabled but cookies are enabled.
+ } else if (currentWebView.getAcceptCookies()) { // JavaScript is disabled but cookies are enabled.
optionsPrivacyMenuItem.setIcon(R.drawable.warning);
} else { // All the dangerous features are disabled.
optionsPrivacyMenuItem.setIcon(R.drawable.privacy_mode);
// Get the current theme status.
int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
- // Update the first-party cookies icon.
- if (currentWebView.getAcceptFirstPartyCookies()) { // First-party cookies are enabled.
- optionsFirstPartyCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
- } else { // First-party cookies are disabled.
+ // Update the cookies icon.
+ if (currentWebView.getAcceptCookies()) { // Cookies are enabled.
+ optionsCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
+ } else { // Cookies are disabled.
if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
- optionsFirstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_day);
+ optionsCookiesMenuItem.setIcon(R.drawable.cookies_disabled_day);
} else {
- optionsFirstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_night);
+ optionsCookiesMenuItem.setIcon(R.drawable.cookies_disabled_night);
}
}
// Get a handle for the cookie manager.
CookieManager cookieManager = CookieManager.getInstance();
- // Set the first-party cookie status.
- cookieManager.setAcceptCookie(currentWebView.getAcceptFirstPartyCookies());
+ // Set the cookie status.
+ cookieManager.setAcceptCookie(currentWebView.getAcceptCookies());
// Update the privacy icons. `true` redraws the icons in the app bar.
updatePrivacyIcons(true);
// Explicitly disable geolocation.
nestedScrollWebView.getSettings().setGeolocationEnabled(false);
+ // Allow loading of file:// URLs. This is necessary for opening MHT web archives, which are copies into a temporary cache location.
+ nestedScrollWebView.getSettings().setAllowFileAccess(true);
+
// Create a double-tap gesture detector to toggle full-screen mode.
GestureDetector doubleTapGestureDetector = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
// Override `onDoubleTap()`. All other events are handled using the default settings.
// Instantiate the save dialog.
DialogFragment saveDialogFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_URL, downloadUrl, formattedFileSizeString, fileNameString, userAgent,
- nestedScrollWebView.getAcceptFirstPartyCookies());
+ nestedScrollWebView.getAcceptCookies());
// Show the save dialog. It must be named `save_dialog` so that the file picker can update the file name.
saveDialogFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
@Override
public void onPageFinished(WebView view, String url) {
// Flush any cookies to persistent storage. The cookie manager has become very lazy about flushing cookies in recent versions.
- if (nestedScrollWebView.getAcceptFirstPartyCookies() && Build.VERSION.SDK_INT >= 21) {
+ if (nestedScrollWebView.getAcceptCookies() && Build.VERSION.SDK_INT >= 21) {
CookieManager.getInstance().flush();
}