]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
Reload `DomainSettingsFragment` on rotate. Implements https://redmine.stoutner.com...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 06b4c4c4a136a94704b6def631df7bb3e80bfe76..6442fb2cca6e1c14def76e109e6aca218e1c668c 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;
@@ -122,9 +120,9 @@ 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`, `CreateBookmarkDialog`, `CreateBookmarkFolderDialog`, `DownloadFileDialog`, `DownloadImageDialog`, `EditBookmarkDialog`,
-    // `EditBookmarkFolderDialog`, `MoveToFolderDialog`, `SslCertificateErrorDialog`, `UrlHistoryDialog`, `ViewSslCertificateDialog`, `CreateHomeScreenShortcutDialog`, and `OrbotProxyHelper`.
-    // It is also used in `onCreate()`, `applyAppSettings()`, and `applyDomainSettings()`.
+    // `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;
 
     // `favoriteIconBitmap` is public static so it can be accessed from `CreateHomeScreenShortcutDialog`, `BookmarksActivity`, `CreateBookmarkDialog`, `CreateBookmarkFolderDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `ViewSslCertificateDialog`.
@@ -282,9 +280,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;
 
@@ -297,6 +292,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `mainWebViewRelativeLayout` is used in `onCreate()` and `onNavigationItemSelected()`.
     private RelativeLayout mainWebViewRelativeLayout;
 
+    // `urlIsLoading` is used in `onCreate()`, `loadUrl()`, and `applyDomainSettings()`.
+    private boolean urlIsLoading;
+
     @Override
     // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.  The whole premise of Privacy Browser is built around an understanding of these dangers.
     @SuppressLint("SetJavaScriptEnabled")
@@ -341,7 +339,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);
@@ -355,13 +352,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);
                 }
             }
         });
@@ -736,12 +729,18 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     if (navigatingHistory) {
                         applyDomainSettings(url);
                     }
+
+                    // Set `urlIsLoading` to `true`, so that redirects while loading do not trigger changes in the user agent, which forces another reload of the existing page.
+                    urlIsLoading = true;
                 }
             }
 
             // Update formattedUrlString and urlTextBox.  It is necessary to do this after the page finishes loading because the final URL can change during load.
             @Override
             public void onPageFinished(WebView view, String url) {
+                // Reset `urlIsLoading`, which is used to prevent reloads on redirect if the user agent changes.
+                urlIsLoading = false;
+
                 // Clear the cache and history if Incognito Mode is enabled.
                 if (incognitoModeEnabled) {
                     // Clear the cache.  `true` includes disk files.
@@ -2166,6 +2165,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
         // Load the URL.
         mainWebView.loadUrl(url, customHeaders);
+
+        // Set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website.
+        urlIsLoading = true;
     }
 
     public void findPreviousOnPage(View view) {
@@ -2436,6 +2438,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);
@@ -2459,20 +2466,50 @@ 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) {
                     cookieManager.setAcceptThirdPartyCookies(mainWebView, thirdPartyCookiesEnabled);
                 }
 
-                // Set the user agent.
-                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);
+                // 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) {
+                        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);
+                    }
                 }
 
                 // Set a green background on `urlTextBox` to indicate that custom domain settings are being used.  We have to use the deprecated `.getDrawable()` until the minimum API >= 21.
@@ -2488,9 +2525,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);
@@ -2504,22 +2538,23 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     cookieManager.setAcceptThirdPartyCookies(mainWebView, thirdPartyCookiesEnabled);
                 }
 
-                // Set the default user agent.
-                switch (userAgentString) {
-                    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(customUserAgentString);
-                        break;
-
-                    default:
-                        // Use the selected user agent.
-                        mainWebView.getSettings().setUserAgentString(userAgentString);
-                        break;
+                // 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 (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);
+                    }
                 }
 
                 // Set a transparent background on `urlTextBox`.  We have to use the deprecated `.getDrawable()` until the minimum API >= 21.
@@ -2582,23 +2617,39 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         if (firstPartyCookiesEnabled) {  // First-party cookies are enabled.
             firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_enabled);
         } else {  // First-party cookies are disabled.
-            firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled);
+            if (darkTheme) {
+                firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled_dark);
+            } else {
+                firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled_light);
+            }
         }
 
         // Update `domStorageIcon`.
         if (javaScriptEnabled && domStorageEnabled) {  // Both JavaScript and DOM storage are enabled.
             domStorageIconMenuItem.setIcon(R.drawable.dom_storage_enabled);
         } else if (javaScriptEnabled) {  // JavaScript is enabled but DOM storage is disabled.
-            domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled);
+            if (darkTheme) {
+                domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled_dark);
+            } else {
+                domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled_light);
+            }
         } else {  // JavaScript is disabled, so DOM storage is ghosted.
-            domStorageIconMenuItem.setIcon(R.drawable.dom_storage_ghosted);
+            if (darkTheme) {
+                domStorageIconMenuItem.setIcon(R.drawable.dom_storage_ghosted_dark);
+            } else {
+                domStorageIconMenuItem.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.
-            formDataIconMenuItem.setIcon(R.drawable.form_data_disabled);
+            if (darkTheme) {
+                formDataIconMenuItem.setIcon(R.drawable.form_data_disabled_dark);
+            } else {
+                formDataIconMenuItem.setIcon(R.drawable.form_data_disabled_light);
+            }
         }
 
         // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.  `this` references the current activity.
@@ -2612,7 +2663,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);
         }