X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebView.java;h=19397117fe5a271fc91412b9fb3d2bd27381f615;hb=7ab2158319ff6d1e1b5087266e1c042e663452b3;hp=cf7cbdad3fb7f817f4e9d172b9699fabcee0b71e;hpb=4474c3d7c1c831fa46a3bfc17056bbd87ecacb9f;p=PrivacyBrowserAndroid.git diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java index cf7cbdad..19397117 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java @@ -24,10 +24,12 @@ package com.stoutner.privacybrowser.activities; import android.annotation.SuppressLint; import android.app.DialogFragment; import android.app.DownloadManager; +import android.content.BroadcastReceiver; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Bitmap; @@ -57,7 +59,6 @@ import android.support.v7.app.AppCompatDialogFragment; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; -import android.util.Log; import android.util.Patterns; import android.view.ContextMenu; import android.view.GestureDetector; @@ -129,6 +130,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `sslCertificate` is public static so it can be accessed from `ViewSslCertificate`. It is also used in `onCreate()`. public static SslCertificate sslCertificate; + // `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`. + public static String orbotStatus; + // `drawerLayout` is used in `onCreate()`, `onNewIntent()`, and `onBackPressed()`. private DrawerLayout drawerLayout; @@ -185,7 +189,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `fullScreenBrowsingModeEnabled` is used in `onCreate()` and `applySettings()`. private boolean fullScreenBrowsingModeEnabled; - // `inFullScreenBrowsingMode` is used in `onCreate()` and `applySettings()`. + // `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applySettings()`. private boolean inFullScreenBrowsingMode; // `hideSystemBarsOnFullscreen` is used in `onCreate()` and `applySettings()`. @@ -194,6 +198,15 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `translucentNavigationBarOnFullscreen` is used in `onCreate()` and `applySettings()`. private boolean translucentNavigationBarOnFullscreen; + // `proxyThroughOrbot` is used in `onCreate()` and `applySettings()` + private boolean proxyThroughOrbot; + + // `pendingUrl` is used in `onCreate()` and `applySettings()` + private static String pendingUrl; + + // `waitingForOrbotData` is used in `onCreate()` and `applySettings()`. + private String waitingForOrbotHTMLString; + // `findOnPageLinearLayout` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`. private LinearLayout findOnPageLinearLayout; @@ -268,6 +281,45 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); + // Set `waitingForOrbotHTMLString`. + waitingForOrbotHTMLString = "

" + getString(R.string.waiting_for_orbot) + "

"; + + // Initialize `pendingUrl`. + pendingUrl = ""; + + // Set the initial Orbot status. + orbotStatus = "unknown"; + + // Create an Orbot status `BroadcastReceiver`. + BroadcastReceiver orbotStatusBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // Store the content of the status message in `orbotStatus`. + orbotStatus = intent.getStringExtra("org.torproject.android.intent.extra.STATUS"); + + // If we are waiting on `pendingUrl`, load it now that Orbot is connected. + if (orbotStatus.equals("ON") && !pendingUrl.isEmpty()) { + + // Wait 500 milliseconds, because Orbot isn't really ready yet. + try { + Thread.sleep(500); + } catch (InterruptedException exception) { + // Do nothing. + } + + // Copy `pendingUrl` to `formattedUrlString` and reset `pendingUrl` to be empty. + formattedUrlString = pendingUrl; + pendingUrl = ""; + + // Load `formattedUrlString + mainWebView.loadUrl(formattedUrlString, customHeaders); + } + } + }; + + // Register `orbotStatusBroadcastReceiver` on `this` context. + this.registerReceiver(orbotStatusBroadcastReceiver, new IntentFilter("org.torproject.android.intent.action.STATUS")); + // Get handles for views that need to be accessed. drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout); rootCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.root_coordinatorlayout); @@ -559,25 +611,31 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Update the URL in urlTextBox when the page starts to load. @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { - // 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. - formattedUrlString = url; + // Check to see if we are waiting on Orbot. + if (pendingUrl.isEmpty()) { // 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. + formattedUrlString = url; - // Display the loading URL is the URL text box. - urlTextBox.setText(url); + // Display the loading URL is the URL text box. + urlTextBox.setText(url); + } } // 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) { - formattedUrlString = url; + // Check to see if we are waiting on Orbot. + if (pendingUrl.isEmpty()) { // we are not waiting on Orbot, so we need to process the URL. + formattedUrlString = url; - // Only update urlTextBox if the user is not typing in it. - if (!urlTextBox.hasFocus()) { - urlTextBox.setText(formattedUrlString); - } + // Only update urlTextBox if the user is not typing in it. + if (!urlTextBox.hasFocus()) { + urlTextBox.setText(formattedUrlString); + } - // Store the SSL certificate so it can be accessed from `ViewSslCertificate`. - sslCertificate = mainWebView.getCertificate(); + // Store the SSL certificate so it can be accessed from `ViewSslCertificate`. + sslCertificate = mainWebView.getCertificate(); + } } // Handle SSL Certificate errors. @@ -698,9 +756,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Initialize the default preference values the first time the program is run. `this` is the context. `false` keeps this command from resetting any current preferences back to default. PreferenceManager.setDefaultValues(this, R.xml.preferences, false); - // Apply the settings from the shared preferences. - applySettings(); - // Get the intent information that started the app. final Intent intent = getIntent(); @@ -710,13 +765,19 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN formattedUrlString = intentUriData.toString(); } - // If formattedUrlString is null assign the homepage to it. - if (formattedUrlString == null) { - formattedUrlString = homepage; - } + // Initialize `inFullScreenBrowsingMode`, which is always false at this point because Privacy Browser never starts in full screen browsing mode. + inFullScreenBrowsingMode = false; - // Load the initial website. - mainWebView.loadUrl(formattedUrlString, customHeaders); + // Initialize AdView for the free flavor. + adView = findViewById(R.id.adView); + + // Apply the settings from the shared preferences. + applySettings(); + + // Load `formattedUrlString` if we are not proxying through Orbot and waiting for Orbot to connect. + if (!(proxyThroughOrbot && !orbotStatus.equals("ON"))) { + mainWebView.loadUrl(formattedUrlString, customHeaders); + } // If the favorite icon is null, load the default. if (favoriteIcon == null) { @@ -725,13 +786,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable; favoriteIcon = favoriteIconBitmapDrawable.getBitmap(); } - - // Initialize `inFullScreenBrowsingMode`, which is always false at this point because Privacy Browser never starts in full screen browsing mode. - inFullScreenBrowsingMode = false; - - // Initialize AdView for the free flavor and request an ad. If this is not the free flavor BannerAd.requestAd() does nothing. - adView = findViewById(R.id.adView); - BannerAd.requestAd(adView); } @@ -1181,6 +1235,12 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN startActivity(settingsIntent); break; + case R.id.domains: + // Launch `DomainsList`. + Intent domainsIntent = new Intent(this, DomainsList.class); + startActivity(domainsIntent); + break; + case R.id.guide: // Launch `Guide`. Intent guideIntent = new Intent(this, Guide.class); @@ -1272,7 +1332,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN super.onConfigurationChanged(newConfig); // Reload the ad for the free flavor if we are not in full screen mode. - if (BuildConfig.FLAVOR.contentEquals("free") && adView.isShown() && !fullScreenVideoFrameLayout.isShown()) { + if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) { // Reload the ad. BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); @@ -1751,15 +1811,20 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); String customUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"); String javaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q="); - String javaScriptDisabledCustomSearchString = sharedPreferences.getString("javascript_disabled_search_custom_url", ""); + String javaScriptDisabledSearchCustomURLString = sharedPreferences.getString("javascript_disabled_search_custom_url", ""); String javaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q="); - String javaScriptEnabledCustomSearchString = sharedPreferences.getString("javascript_enabled_search_custom_url", ""); + String javaScriptEnabledSearchCustomURLString = sharedPreferences.getString("javascript_enabled_search_custom_url", ""); String homepageString = sharedPreferences.getString("homepage", "https://www.duckduckgo.com"); + String torHomepageString = sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"); + String torJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); + String torJavaScriptDisabledSearchCustomURLString = sharedPreferences.getString("tor_javascript_disabled_search_custom_url", ""); + String torJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q="); + String torJavaScriptEnabledSearchCustomURLString = sharedPreferences.getString("tor_javascript_enabled_search_custom_url", ""); String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100"); swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", false); adBlockerEnabled = sharedPreferences.getBoolean("block_ads", true); boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); - boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); + proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false); hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); @@ -1786,8 +1851,75 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } } - // Apply the other settings from `sharedPreferences`. - homepage = homepageString; + // Set the homepage, search, and proxy options. + if (proxyThroughOrbot) { // Set the Tor options. + // Set `torHomepageString` as `homepage`. + homepage = torHomepageString; + + // If formattedUrlString is null assign the homepage to it. + if (formattedUrlString == null) { + formattedUrlString = homepage; + } + + // Set JavaScript disabled search. + if (torJavaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptDisabledSearchURL = torJavaScriptDisabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptDisabledSearchURL = torJavaScriptDisabledSearchString; + } + + // Set JavaScript enabled search. + if (torJavaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptEnabledSearchURL = torJavaScriptEnabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptEnabledSearchURL = torJavaScriptEnabledSearchString; + } + + // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); + + // Display a message to the user if we are waiting on Orbot. + if (!orbotStatus.equals("ON")) { + // Save `formattedUrlString` in `pendingUrl`. + pendingUrl = formattedUrlString; + + // Load a waiting page. `null` specifies no encoding, which defaults to ASCII. + mainWebView.loadData(waitingForOrbotHTMLString, "text/html", null); + } + } else { // Set the non-Tor options. + // Set `homepageString` as `homepage`. + homepage = homepageString; + + // If formattedUrlString is null assign the homepage to it. + if (formattedUrlString == null) { + formattedUrlString = homepage; + } + + // Set JavaScript disabled search. + if (javaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptDisabledSearchURL = javaScriptDisabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptDisabledSearchURL = javaScriptDisabledSearchString; + } + + // Set JavaScript enabled search. + if (javaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptEnabledSearchURL = javaScriptEnabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptEnabledSearchURL = javaScriptEnabledSearchString; + } + + // Reset the proxy to default. The host is `""` and the port is `"0"`. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); + + // Reset `pendingUrl` if we are currently waiting for Orbot to connect. + if (!pendingUrl.isEmpty()) { + formattedUrlString = pendingUrl; + pendingUrl = ""; + } + } + + // Set swipe to refresh. swipeRefreshLayout.setEnabled(swipeToRefreshEnabled); // Set the user agent initial status. @@ -1808,20 +1940,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN break; } - // Set JavaScript disabled search. - if (javaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. - javaScriptDisabledSearchURL = javaScriptDisabledCustomSearchString; - } else { // Use the string from the pre-built list. - javaScriptDisabledSearchURL = javaScriptDisabledSearchString; - } - - // Set JavaScript enabled search. - if (javaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. - javaScriptEnabledSearchURL = javaScriptEnabledCustomSearchString; - } else { // Use the string from the pre-built list. - javaScriptEnabledSearchURL = javaScriptEnabledSearchString; - } - // Set Do Not Track status. if (doNotTrackEnabled) { customHeaders.put("DNT", "1"); @@ -1829,16 +1947,8 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN customHeaders.remove("DNT"); } - // Set Orbot proxy status. - if (proxyThroughOrbot) { - // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); - } else { // Reset the proxy to default. The host is `""` and the port is `"0"`. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); - } - - // If we are in full screen mode update the `SYSTEM_UI` flags. - if (inFullScreenBrowsingMode) { + // Apply the appropriate full screen mode the `SYSTEM_UI` flags. + if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { if (hideSystemBarsOnFullscreen) { // Hide everything. // Remove the translucent navigation setting if it is currently flagged. getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); @@ -1866,6 +1976,33 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } } + } else { // Switch to normal viewing mode. + // Reset `inFullScreenBrowsingMode` to `false`. + inFullScreenBrowsingMode = false; + + // Show the `appBar`. + appBar.show(); + + // Show the `BannerAd` in the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. + 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); + } + + // Remove the translucent navigation bar flag if it is set. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + + // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. + rootCoordinatorLayout.setSystemUiVisibility(0); + + // Constrain `rootCoordinatorLayout` inside the status and navigation bars. + rootCoordinatorLayout.setFitsSystemWindows(true); } }