]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
Correctly encode URLs in `loadUrlFromTextBox()`. Fixes https://redmine.stoutner...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 2ca1f0fb52d7d700a62c150a79e79cf873fab57a..5525439d3c31ee838d75ac722acbb3a8654e4689 100644 (file)
@@ -107,6 +107,7 @@ import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -209,7 +210,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `proxyThroughOrbot` is used in `onCreate()` and `applySettings()`
     private boolean proxyThroughOrbot;
 
-    // `currentDomain` is used in `onCreate() and `applyDomainSettings()`.
+    // `currentDomain` is used in `onCreate(), `onNavigationItemSelected()`, and `applyDomainSettings()`.
     private String currentDomain;
 
     // `pendingUrl` is used in `onCreate()` and `applySettings()`
@@ -253,7 +254,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     @SuppressLint("SetJavaScriptEnabled")
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.drawerlayout);
+        setContentView(R.layout.main_drawerlayout);
 
         // Get a handle for `inputMethodManager`.
         inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -266,12 +267,12 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         // This is needed to get rid of the Android Studio warning that `appBar` might be null.
         assert appBar != null;
 
-        // Add the custom url_app_bar layout, which shows the favoriteIcon, urlTextBar, and progressBar.
+        // Add the custom `url_app_bar` layout, which shows the favorite icon and the URL text bar.
         appBar.setCustomView(R.layout.url_app_bar);
         appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
 
         // Set the "go" button on the keyboard to load the URL in urlTextBox.
-        urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.urlTextBox);
+        urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.url_edittext);
         urlTextBox.setOnKeyListener(new View.OnKeyListener() {
             @Override
             public boolean onKey(View v, int keyCode, KeyEvent event) {
@@ -334,7 +335,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
         rootCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.root_coordinatorlayout);
         mainWebViewRelativeLayout = (RelativeLayout) findViewById(R.id.main_webview_relativelayout);
-        mainWebView = (WebView) findViewById(R.id.mainWebView);
+        mainWebView = (WebView) findViewById(R.id.main_webview);
         findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout);
         findOnPageEditText = (EditText) findViewById(R.id.find_on_page_edittext);
         fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.full_screen_video_framelayout);
@@ -392,7 +393,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                             BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
 
                             // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                            adView = findViewById(R.id.adView);
+                            adView = findViewById(R.id.adview);
                         }
 
                         // Remove the translucent navigation bar flag if it is set.
@@ -482,7 +483,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         });
 
         // Implement swipe to refresh
-        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
+        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refreshlayout);
         swipeRefreshLayout.setColorSchemeResources(R.color.blue_700);
         swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
             @Override
@@ -665,11 +666,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             }
         });
 
+        // Get a handle for the progress bar.
+        final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
+
         mainWebView.setWebChromeClient(new WebChromeClient() {
             // Update the progress bar when a page is loading.
             @Override
             public void onProgressChanged(WebView view, int progress) {
-                ProgressBar progressBar = (ProgressBar) appBar.getCustomView().findViewById(R.id.progressBar);
                 progressBar.setProgress(progress);
                 if (progress < 100) {
                     progressBar.setVisibility(View.VISIBLE);
@@ -688,7 +691,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 favoriteIcon = icon;
 
                 // Place the favorite icon in the appBar.
-                ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favoriteIcon);
+                ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favorite_icon);
                 imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
             }
 
@@ -745,7 +748,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                     BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
 
                     // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                    adView = findViewById(R.id.adView);
+                    adView = findViewById(R.id.adview);
                 }
             }
         });
@@ -793,7 +796,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         inFullScreenBrowsingMode = false;
 
         // Initialize AdView for the free flavor.
-        adView = findViewById(R.id.adView);
+        adView = findViewById(R.id.adview);
 
         // Initialize the privacy settings variables.
         javaScriptEnabled = false;
@@ -995,11 +998,11 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Display a `Snackbar`.
                 if (javaScriptEnabled) {  // JavaScrip is enabled.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
                 } else if (firstPartyCookiesEnabled) {  // JavaScript is disabled, but first-party cookies are enabled.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
                 } else {  // Privacy mode.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
                 }
 
                 // Reload the WebView.
@@ -1021,11 +1024,11 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Display a `Snackbar`.
                 if (firstPartyCookiesEnabled) {  // First-party cookies are enabled.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
                 } else if (javaScriptEnabled){  // JavaScript is still enabled.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
                 } else {  // Privacy mode.
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
                 }
 
                 // Reload the WebView.
@@ -1045,9 +1048,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                     // Display a `Snackbar`.
                     if (thirdPartyCookiesEnabled) {
-                        Snackbar.make(findViewById(R.id.mainWebView), R.string.third_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
+                        Snackbar.make(findViewById(R.id.main_webview), R.string.third_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
                     } else {
-                        Snackbar.make(findViewById(R.id.mainWebView), R.string.third_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
+                        Snackbar.make(findViewById(R.id.main_webview), R.string.third_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
                     }
 
                     // Reload the WebView.
@@ -1070,9 +1073,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Display a `Snackbar`.
                 if (domStorageEnabled) {
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show();
                 } else {
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show();
                 }
 
                 // Reload the WebView.
@@ -1091,9 +1094,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
 
                 // Display a `Snackbar`.
                 if (saveFormDataEnabled) {
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.form_data_enabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_enabled, Snackbar.LENGTH_SHORT).show();
                 } else {
-                    Snackbar.make(findViewById(R.id.mainWebView), R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show();
+                    Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show();
                 }
 
                 // Update the privacy icon.  `true` runs `invalidateOptionsMenu` as the last step.
@@ -1109,19 +1112,19 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 } else {
                     cookieManager.removeAllCookies(null);
                 }
-                Snackbar.make(findViewById(R.id.mainWebView), R.string.cookies_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.cookies_deleted, Snackbar.LENGTH_SHORT).show();
                 return true;
 
             case R.id.clearDomStorage:
                 WebStorage webStorage = WebStorage.getInstance();
                 webStorage.deleteAllData();
-                Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show();
                 return true;
 
             case R.id.clearFormData:
                 WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
                 mainWebViewDatabase.clearFormData();
-                Snackbar.make(findViewById(R.id.mainWebView), R.string.form_data_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_deleted, Snackbar.LENGTH_SHORT).show();
                 return true;
 
             case R.id.fontSizeFiftyPercent:
@@ -1269,12 +1272,18 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 break;
 
             case R.id.settings:
+                // Reset `currentDomain` so that domain settings are reapplied after returning to `MainWebViewActivity`.
+                currentDomain = "";
+
                 // Launch `SettingsActivity`.
                 Intent settingsIntent = new Intent(this, SettingsActivity.class);
                 startActivity(settingsIntent);
                 break;
 
             case R.id.domains:
+                // Reset `currentDomain` so that domain settings are reapplied after returning to `MainWebViewActivity`.
+                currentDomain = "";
+
                 // Launch `DomainsActivity`.
                 Intent domainsIntent = new Intent(this, DomainsActivity.class);
                 startActivity(domainsIntent);
@@ -1376,7 +1385,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
 
             // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-            adView = findViewById(R.id.adView);
+            adView = findViewById(R.id.adview);
         }
 
         // `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:  https://code.google.com/p/android/issues/detail?id=20493#c8
@@ -1778,9 +1787,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         // Get the text from urlTextBox and convert it to a string.  trim() removes white spaces from the beginning and end of the string.
         String unformattedUrlString = urlTextBox.getText().toString().trim();
 
-        URL unformattedUrl = null;
-        Uri.Builder formattedUri = new Uri.Builder();
-
         // Check to see if unformattedUrlString is a valid URL.  Otherwise, convert it into a Duck Duck Go search.
         if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
             // Add http:// at the beginning if it is missing.  Otherwise the app will segfault.
@@ -1788,6 +1794,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 unformattedUrlString = "http://" + unformattedUrlString;
             }
 
+            // Initialize `unformattedUrl`.
+            URL unformattedUrl = null;
+
             // Convert unformattedUrlString to a URL, then to a URI, and then back to a string, which sanitizes the input and adds in any missing components.
             try {
                 unformattedUrl = new URL(unformattedUrlString);
@@ -1795,17 +1804,21 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 e.printStackTrace();
             }
 
-            // The ternary operator (? :) makes sure that a null pointer exception is not thrown, which would happen if .get was called on a null value.
+            // The ternary operator (? :) makes sure that a null pointer exception is not thrown, which would happen if `.get` was called on a `null` value.
             final String scheme = unformattedUrl != null ? unformattedUrl.getProtocol() : null;
             final String authority = unformattedUrl != null ? unformattedUrl.getAuthority() : null;
             final String path = unformattedUrl != null ? unformattedUrl.getPath() : null;
             final String query = unformattedUrl != null ? unformattedUrl.getQuery() : null;
             final String fragment = unformattedUrl != null ? unformattedUrl.getRef() : null;
 
+            // Build the URI.
+            Uri.Builder formattedUri = new Uri.Builder();
             formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
-            formattedUrlString = formattedUri.build().toString();
+
+            // Decode `formattedUri` as a `String` in `UTF-8`.
+            formattedUrlString = URLDecoder.decode(formattedUri.build().toString(), "UTF-8");
         } else {
-            // Sanitize the search input and convert it to a DuckDuckGo search.
+            // Sanitize the search input and convert it to a search.
             final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
 
             // Use the correct search URL.
@@ -1891,7 +1904,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 hostname = hostname.substring(hostname.indexOf(".") + 1);
             }
 
-            FrameLayout urlAppBarFrameLayout = (FrameLayout) findViewById(R.id.url_app_bar_framelayout);
+            RelativeLayout urlAppBarRelativeLayout = (RelativeLayout) findViewById(R.id.url_app_bar_relativelayout);
 
             if (hostHasDomainSettings) {  // The url we are loading has custom domain settings.
                 // Get a cursor for the current host and move it to the first position.
@@ -1932,7 +1945,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 }
 
                 // 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.
-                urlAppBarFrameLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_green));
+                urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_green));
             } else {  // The URL we are loading does not have custom domain settings.  Load the defaults.
                 // Get the shared preference values.  `this` references the current context.
                 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
@@ -1978,7 +1991,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 }
 
                 // Set a transparent background on `urlTextBox`.  We have to use the deprecated `.getDrawable()` until the minimum API >= 21.
-                urlAppBarFrameLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.url_bar_background_transparent));
+                urlAppBarRelativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.url_bar_background_transparent));
             }
 
             // Close `domainsDatabaseHelper`.
@@ -2161,7 +2174,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
 
                 // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                adView = findViewById(R.id.adView);
+                adView = findViewById(R.id.adview);
             }
 
             // Remove the translucent navigation bar flag if it is set.