From f7ad9e2325cd19f0571e569ff160f2fffac5c5a5 Mon Sep 17 00:00:00 2001 From: Soren Stoutner <soren@stoutner.com> Date: Wed, 22 Feb 2017 13:46:42 -0700 Subject: [PATCH] Wait for Orbot to connect when proxying though Orbot before trying to load a URL. --- .idea/dictionaries/soren.xml | 1 + .idea/inspectionProfiles/Project_Default.xml | 1 + .../activities/MainWebView.java | 134 ++++++++++-------- .../helpers/OrbotProxyHelper.java | 8 ++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 84 insertions(+), 61 deletions(-) diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index f0da2a0d..84598132 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -60,6 +60,7 @@ <w>parameterized</w> <w>parentfolder</w> <w>programatically</w> + <w>proxying</w> <w>qwant</w> <w>radiobutton</w> <w>radiogroup</w> diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 46885f81..ba31176e 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,6 +2,7 @@ <profile version="1.0"> <option name="myName" value="Project Default" /> <option name="myLocal" value="true" /> + <inspection_tool class="AndroidLintTypographyEllipsis" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true"> <option name="myValues"> <value> 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 e0cd5394..eb6392b2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java @@ -202,7 +202,10 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN private boolean proxyThroughOrbot; // `pendingUrl` is used in `onCreate()` and `applySettings()` - private String pendingUrl; + 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; @@ -278,6 +281,45 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } }); + // Set `waitingForOrbotHTMLString`. + waitingForOrbotHTMLString = "<html><body><br/><center><h1>" + getString(R.string.waiting_for_orbot) + "</h1></center></body></html>"; + + // 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); @@ -711,45 +753,9 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Replace the header that `WebView` creates for `X-Requested-With` with a null value. The default value is the application ID (com.stoutner.privacybrowser.standard). customHeaders.put("X-Requested-With", ""); - // Set the initial Orbot status. - orbotStatus = "unknown"; - - // Create a 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. - } - - // Load `pendingUrl`. - formattedUrlString = pendingUrl; - mainWebView.loadUrl(formattedUrlString, customHeaders); - - // Reset `pendingUrl` to be empty. - pendingUrl = ""; - } - } - }; - - // Register `orbotStatusBroadcastReceiver` on `this` context. - this.registerReceiver(orbotStatusBroadcastReceiver, new IntentFilter("org.torproject.android.intent.action.STATUS")); - // 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(); @@ -759,22 +765,11 @@ 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 `pendingUrl`. - pendingUrl = ""; - - if (proxyThroughOrbot & !orbotStatus.equals("ON")) { // We are waiting on Orbot. - // Save `formattedUrlString` in `pendingUrl`. - pendingUrl = formattedUrlString; + // Apply the settings from the shared preferences. + applySettings(); - // Load a waiting page. `null` specifies no encoding, which defaults to ASCII. - mainWebView.loadData("<html><body><br/><center><h1>Waiting for Orbot to connect...</h1></center></body></html>", "text/html", null); - } else { - // Load the initial website. + // Load `formattedUrlString` if we are not proxying through Orbot and waiting for Orbot to connect. + if (!(proxyThroughOrbot & !orbotStatus.equals("ON"))) { mainWebView.loadUrl(formattedUrlString, customHeaders); } @@ -1864,6 +1859,11 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // 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; @@ -1880,10 +1880,24 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // 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; @@ -1900,6 +1914,12 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // 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. @@ -1930,7 +1950,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN customHeaders.remove("DNT"); } - // If we are in full screen mode update the `SYSTEM_UI` flags. + // Update the `SYSTEM_UI` flags if we are in full screen mode. if (inFullScreenBrowsingMode) { if (hideSystemBarsOnFullscreen) { // Hide everything. // Remove the translucent navigation setting if it is currently flagged. @@ -1960,14 +1980,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } } } - - if (proxyThroughOrbot & !orbotStatus.equals("ON")) { // We are waiting on Orbot. - // Save `formattedUrlString` in `pendingUrl`. - pendingUrl = formattedUrlString; - - // Load a waiting page. `null` specifies no encoding, which defaults to ASCII. - mainWebView.loadData("<html><body><br/><center><h1>Waiting for Orbot to connect...</h1></center></body></html>", "text/html", null); - } } private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java index c4cbc6b9..8d0e4082 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java @@ -86,8 +86,16 @@ public class OrbotProxyHelper { // Ask Orbot to connect if its current status is not "ON". if (!MainWebView.orbotStatus.equals("ON")) { + // Request Orbot to start. Intent orbotIntent = new Intent("org.torproject.android.intent.action.START"); + + // Send the intent to the Orbot package. orbotIntent.setPackage("org.torproject.android"); + + // Request a status response be sent back to this package. + orbotIntent.putExtra("org.torproject.android.intent.extra.PACKAGE_NAME", privacyBrowserContext.getPackageName()); + + // Make it so. privacyBrowserContext.sendBroadcast(orbotIntent); } } catch (PackageManager.NameNotFoundException exception){ // If an exception is thrown, Orbot is not installed. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cfaa785d..3fa168fa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -348,6 +348,7 @@ <!-- Orbot. --> <string name="orbot_proxy_not_installed">Orbot proxy will not work unless Orbot is installed.</string> + <string name="waiting_for_orbot">Waiting for Orbot to connect...</string> <!-- About Activity. --> <string name="about_privacy_browser">About Privacy Browser</string> -- 2.47.2