]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
Add Searx to the list of search engines. Implements https://redmine.stoutner.com...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 4200fb5e1efc74c0b5f76566cd06ab8f7c0b8681..f826f6d130ab63e969ac5c6ae31e723ea0af2441 100644 (file)
@@ -122,8 +122,10 @@ import java.util.Set;
 public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcutDialog.CreateHomeScreenSchortcutListener,
         SslCertificateErrorDialog.SslCertificateErrorListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, UrlHistoryDialog.UrlHistoryListener {
 
-    // `appBar` is public static so it can be accessed from `OrbotProxyHelper`.  It is also used in `onCreate()`, `onOptionsItemSelected()`, `closeFindOnPage()`, and `applyAppSettings()`.
-    public static ActionBar appBar;
+    // `darkTheme` is public static so it can be accessed from `AboutActivity`, `GuideActivity`, `AddDomainDialog`, `SettingsActivity`, `DomainsActivity`, `DomainsSettingsActivity`, `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`.
     // It is also used in `onCreate()`, `onCreateHomeScreenShortcutCreate()`, and `applyDomainSettings`.
@@ -149,6 +151,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     public static boolean reloadOnRestartBoolean;
 
 
+    // `appBar` is used in `onCreate()`, `onOptionsItemSelected()`, `closeFindOnPage()`, and `applyAppSettings()`.
+    private ActionBar appBar;
+
     // `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, and `applyDomainSettings()`.
     private boolean navigatingHistory;
 
@@ -292,13 +297,32 @@ 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")
     // 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.
+        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+        // Get the theme preference.
+        darkTheme = sharedPreferences.getBoolean("dark_theme", false);
+
+        // Set the activity theme.
+        if (darkTheme) {
+            setTheme(R.style.PrivacyBrowserDark);
+        } else {
+            setTheme(R.style.PrivacyBrowserLight);
+        }
+
+        // Run the default commands.
         super.onCreate(savedInstanceState);
+
+        // Set the content view.
         setContentView(R.layout.main_drawerlayout);
 
         // Get a handle for `inputMethodManager`.
@@ -715,12 +739,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.
@@ -1082,9 +1112,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        // Hide the keyboard (if displayed) so we can see the options menu.  `0` indicates no additional flags.
-        inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
-
         // Get handles for the menu items.
         MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
         MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies);
@@ -2148,6 +2175,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) {
@@ -2218,6 +2248,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             // Set the proxy.  `this` refers to the current activity where an `AlertDialog` might be displayed.
             OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118");
 
+            // Set the `appBar` background to indicate proxying through Orbot is enabled.  `this` refers to the context.
+            if (darkTheme) {
+                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30));
+            } else {
+                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50));
+            }
+
             // Display a message to the user if we are waiting on Orbot.
             if (!orbotStatus.equals("ON")) {
                 // Set `waitingForOrbot`.
@@ -2245,6 +2282,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             // Reset the proxy to default.  The host is `""` and the port is `"0"`.
             OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0");
 
+            // Set the default `appBar` background.  `this` refers to the context.
+            if (darkTheme) {
+                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900));
+            } else {
+                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100));
+            }
+
             // Reset `waitingForOrbot.
             waitingForOrbot = false;
         }
@@ -2434,17 +2478,23 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     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) {
+                    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);
+                    }
                 }
 
                 // 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.
-                urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_green));
+                if (darkTheme) {
+                    urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
+                } else {
+                    urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
+                }
             } else {  // The URL we are loading does not have custom domain settings.  Load the defaults.
                 // Store the values from `sharedPreferences` in variables.
                 javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
@@ -2468,26 +2518,28 @@ 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 (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;
+                    }
                 }
 
                 // Set a transparent background on `urlTextBox`.  We have to use the deprecated `.getDrawable()` until the minimum API >= 21.
-                urlAppBarRelativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.url_bar_background_transparent));
+                urlAppBarRelativeLayout.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
             }
 
             // Close `domainsDatabaseHelper`.
@@ -2546,23 +2598,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.
@@ -2576,7 +2644,7 @@ 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);
+            // 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);
         }