import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
-import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
import android.util.Patterns;
import android.view.ContextMenu;
import android.view.GestureDetector;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcutDialog.CreateHomeScreenSchortcutListener,
SslCertificateErrorDialog.SslCertificateErrorListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, UrlHistoryDialog.UrlHistoryListener {
- // `darkTheme` is public static so it can be accessed from `AboutActivity`, `GuideActivity`, `AddDomainDialog`, `SettingsActivity`, `DomainsActivity`, `DomainsSettingsActivity`, `BookmarksActivity`, `BookmarksDatabaseViewActivity`,
+ // `darkTheme` is public static so it can be accessed from `AboutActivity`, `GuideActivity`, `AddDomainDialog`, `SettingsActivity`, `DomainsActivity`, `DomainsListFragment`, `BookmarksActivity`, `BookmarksDatabaseViewActivity`,
// `CreateBookmarkDialog`, `CreateBookmarkFolderDialog`, `DownloadFileDialog`, `DownloadImageDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `MoveToFolderDialog`, `SslCertificateErrorDialog`, `UrlHistoryDialog`, `ViewSslCertificateDialog`,
// `CreateHomeScreenShortcutDialog`, and `OrbotProxyHelper`. It is also used in `onCreate()`, `applyAppSettings()`, `applyDomainSettings()`, and `updatePrivacyIcons()`.
public static boolean darkTheme;
// `adBlockerEnabled` is used in `onCreate()` and `applyAppSettings()`.
private boolean adBlockerEnabled;
- // `privacyBrowserRuntime` is used in `onCreate()` and `applyAppSettings()`.
+ // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
private Runtime privacyBrowserRuntime;
// `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
// `waitingForOrbotData` is used in `onCreate()` and `applyAppSettings()`.
private String waitingForOrbotHTMLString;
- // `privateDataDirectoryString` is used in `onCreate()` and `onNavigationItemSelected()`.
+ // `privateDataDirectoryString` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`.
private String privateDataDirectoryString;
// `findOnPageLinearLayout` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
// `finalGrayColorSpam` is used in `onCreate()` and `highlightUrlText()`.
private ForegroundColorSpan finalGrayColorSpan;
- // `boldStyleSpan` is used in `onCreate()` and `highlightUrlText()`.
- private StyleSpan boldStyleSpan;
-
// `adView` is used in `onCreate()` and `onConfigurationChanged()`.
private View adView;
redColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.red_a700));
initialGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
finalGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
- boldStyleSpan = new StyleSpan(Typeface.BOLD);
// Get a handle for `urlTextBox`.
urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.url_edittext);
urlTextBox.getText().removeSpan(redColorSpan);
urlTextBox.getText().removeSpan(initialGrayColorSpan);
urlTextBox.getText().removeSpan(finalGrayColorSpan);
- urlTextBox.getText().removeSpan(boldStyleSpan);
} else { // The user has stopped editing `urlTextBox`.
// Reapply the highlighting.
highlightUrlText();
MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage);
MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_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 fontSizeMenuItem = menu.findItem(R.id.font_size);
MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images);
// Enable third-party cookies if first-party cookies are enabled.
toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled);
- // Enable DOM Storage if JavaScript is enabled.
+ // Enable `DOM Storage` if JavaScript is enabled.
toggleDomStorageMenuItem.setEnabled(javaScriptEnabled);
- // Enable Clear Cookies if there are any.
+ // Enable `Clear Cookies` if there are any.
clearCookiesMenuItem.setEnabled(cookieManager.hasCookies());
- // Enable Clear Form Data is there is any.
+ // Get a count of the number of files in the `Local Storage` directory.
+ File localStorageDirectory = new File (privateDataDirectoryString + "/app_webview/Local Storage/");
+ int localStorageDirectoryNumberOfFiles = 0;
+ if (localStorageDirectory.exists()) {
+ localStorageDirectoryNumberOfFiles = localStorageDirectory.list().length;
+ }
+
+ // Get a count of the number of files in the `IndexedDB` directory.
+ File indexedDBDirectory = new File (privateDataDirectoryString + "/app_webview/IndexedDB");
+ int indexedDBDirectoryNumberOfFiles = 0;
+ if (indexedDBDirectory.exists()) {
+ indexedDBDirectoryNumberOfFiles = indexedDBDirectory.list().length;
+ }
+
+ // 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());
// Delete the DOM Storage.
WebStorage webStorage = WebStorage.getInstance();
webStorage.deleteAllData();
+
+ // Manually remove `IndexedDB` if it exists.
+ try {
+ privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ } catch (IOException e) {
+ // Do nothing if an error is thrown.
+ }
}
}
})
WebStorage webStorage = WebStorage.getInstance();
webStorage.deleteAllData();
- // Manually delete the DOM storage directory, as `WebStorage` sometimes will not flush its changes to disk before `System.exit(0)` is run.
+ // Manually delete the DOM storage files and directories, as `WebStorage` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// We have to use a `String[]` because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise.
privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
+
+ // We have to use multiple commands because `Runtime.exec()` does not like `*`.
+ privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
+ privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
+ privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
} catch (IOException e) {
// Do nothing if an error is thrown.
}
if (urlString.startsWith("http://")) { // Highlight connections that are not encrypted.
urlTextBox.getText().setSpan(redColorSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- // urlTextBox.getText().setSpan(boldStyleSpan, 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
} else if (urlString.startsWith("https://")) { // Highlight connections that are encrypted.
urlTextBox.getText().setSpan(initialGrayColorSpan, 0, 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}