]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
Don't reset the `WebView` title `onPageStarted()`, because `onPageStarted()` is run...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 67a4700d6ae7a219596ab9e661f3b44ea5d2c77c..0d8534cbf7a51fffda56048163219219f0160f31 100644 (file)
@@ -34,7 +34,6 @@ import android.content.SharedPreferences;
 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;
@@ -63,7 +62,6 @@ import android.text.Editable;
 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;
@@ -106,6 +104,7 @@ import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
@@ -122,7 +121,7 @@ import java.util.Set;
 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;
@@ -216,7 +215,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `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()`.
@@ -252,7 +251,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `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()`.
@@ -282,9 +281,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `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;
 
@@ -344,7 +340,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         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);
@@ -358,13 +353,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     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();
-
-                    // Scroll to the beginning of the text.
-                    urlTextBox.setScrollX(0);
                 }
             }
         });
@@ -721,9 +712,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             // Update the URL in urlTextBox when the page starts to load.
             @Override
             public void onPageStarted(WebView view, String url, Bitmap favicon) {
-                // Reset `webViewTitle`
-                webViewTitle = getString(R.string.no_title);
-
                 // Check to see if we are waiting on Orbot.
                 if (!waitingForOrbot) {  // We are not waiting on Orbot, so we need to process the URL.
                     // We need to update `formattedUrlString` at the beginning of the load, so that if the user toggles JavaScript during the load the new website is reloaded.
@@ -1118,6 +1106,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         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);
@@ -1133,13 +1122,30 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         // 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());
 
@@ -1394,6 +1400,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                                         // 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.
+                                        }
                                 }
                             }
                         })
@@ -1474,12 +1487,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
             case R.id.share:
                 // Setup the share string.
-                String shareString;
-                if (webViewTitle != null) {
-                    shareString = webViewTitle + " – " + urlTextBox.getText().toString();
-                } else {
-                    shareString = urlTextBox.getText().toString();
-                }
+                String shareString = webViewTitle + " – " + urlTextBox.getText().toString();
 
                 // Create the share intent.
                 Intent shareIntent = new Intent();
@@ -1498,8 +1506,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 // Show the Find on Page `RelativeLayout`.
                 findOnPageLinearLayout.setVisibility(View.VISIBLE);
 
-                // Display the keyboard.  We have to 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
+                // Display the keyboard.  We have to 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(new Runnable()
                 {
                     @Override
@@ -1508,7 +1515,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                         // Set the focus on `findOnPageEditText`.
                         findOnPageEditText.requestFocus();
 
-                        // Display the keyboard.
+                        // Display the keyboard.  `0` sets no input flags.
                         inputMethodManager.showSoftInput(findOnPageEditText, 0);
                     }
                 }, 200);
@@ -1660,10 +1667,16 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     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.
                     }
@@ -2448,6 +2461,11 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             // Get a handle for the shared preference.  `this` references the current context.
             SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
 
+            // Store the default font size and user agent information.
+            String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
+            String defaultUserAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
+            String defaultCustomUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0");
+
             if (domainSettingsApplied) {  // The url we are loading has custom domain settings.
                 // Get a cursor for the current host and move it to the first position.
                 Cursor currentHostDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
@@ -2471,7 +2489,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
                 mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
                 mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
-                mainWebView.getSettings().setTextZoom(fontSize);
+
+                // Apply the font size.
+                if (fontSize == 0) {  // Apply the default font size.
+                    mainWebView.getSettings().setTextZoom(Integer.valueOf(defaultFontSizeString));
+                } else {  // Apply the specified font size.
+                    mainWebView.getSettings().setTextZoom(fontSize);
+                }
 
                 // Set third-party cookies status if API >= 21.
                 if (Build.VERSION.SDK_INT >= 21) {
@@ -2480,12 +2504,34 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Only set the user agent if the webpage is not currently loading.  Otherwise, changing the user agent on redirects can cause the original website to reload.  <https://redmine.stoutner.com/issues/160>
                 if (!urlIsLoading) {
-                    if (userAgentString.equals("WebView default user agent")) {
-                        // Set the user agent to `""`, which uses the default value.
-                        mainWebView.getSettings().setUserAgentString("");
-                    } else {
-                        // Use the selected user agent.
-                        mainWebView.getSettings().setUserAgentString(userAgentString);
+                    switch (userAgentString) {
+                        case "System default user agent":
+                            // Set the user agent according to the system default.
+                            switch (defaultUserAgentString) {
+                                case "WebView default user agent":
+                                    // Set the user agent to `""`, which uses the default value.
+                                    mainWebView.getSettings().setUserAgentString("");
+                                    break;
+
+                                case "Custom user agent":
+                                    // Set the custom user agent.
+                                    mainWebView.getSettings().setUserAgentString(defaultCustomUserAgentString);
+                                    break;
+
+                                default:
+                                    // Use the selected user agent.
+                                    mainWebView.getSettings().setUserAgentString(defaultUserAgentString);
+                            }
+                            break;
+
+                        case "WebView default user agent":
+                            // Set the user agent to `""`, which uses the default value.
+                            mainWebView.getSettings().setUserAgentString("");
+                            break;
+
+                        default:
+                            // Use the selected user agent.
+                            mainWebView.getSettings().setUserAgentString(userAgentString);
                     }
                 }
 
@@ -2502,9 +2548,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
                 domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
                 saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
-                String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
-                String customUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0");
-                String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
 
                 // Apply the default settings.
                 mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
@@ -2520,7 +2563,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Only set the user agent if the webpage is not currently loading.  Otherwise, changing the user agent on redirects can cause the original website to reload.  <https://redmine.stoutner.com/issues/160>
                 if (!urlIsLoading) {
-                    switch (userAgentString) {
+                    switch (defaultUserAgentString) {
                         case "WebView default user agent":
                             // Set the user agent to `""`, which uses the default value.
                             mainWebView.getSettings().setUserAgentString("");
@@ -2528,13 +2571,12 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                         case "Custom user agent":
                             // Set the custom user agent.
-                            mainWebView.getSettings().setUserAgentString(customUserAgentString);
+                            mainWebView.getSettings().setUserAgentString(defaultCustomUserAgentString);
                             break;
 
                         default:
                             // Use the selected user agent.
-                            mainWebView.getSettings().setUserAgentString(userAgentString);
-                            break;
+                            mainWebView.getSettings().setUserAgentString(defaultUserAgentString);
                     }
                 }
 
@@ -2644,7 +2686,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
         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);
         }