commit e3bb52052fcb1e06b8c90bcacfe456d6a5d7758f
Author: Hans-Christoph Steiner <hans(a)eds.org>
Date: Tue Sep 1 20:49:27 2015 +0200
Orfox: add BroadcastReceiver to receive Tor status from Orbot
Run in thread so Tor status updates will be received while the Gecko event
sync is blocking the main thread. This might not be the best approach
since it probably means that the main UI will be frozen waiting for Tor to
reach ON status.
Queue URL Intents events when Orbot is not yet started
Instead of failing when opening a URL and Tor is not ready, queue those
Intents, then send them once we get STATUS_ON from Orbot.
Signed-off-by: Amogh Pradeep <amoghbl1(a)gmail.com>
---
.../base/java/org/mozilla/gecko/BrowserApp.java | 32 ++++++++++++++++++++++
.../main/java/org/mozilla/gecko/GeckoAppShell.java | 32 ++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
index 8d5bbddabc88..3cc087e66622 100644
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -13,11 +13,13 @@ import android.app.DownloadManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -35,6 +37,9 @@ import android.nfc.NfcEvent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.StrictMode;
@@ -1273,6 +1278,16 @@ public class BrowserApp extends GeckoApp
}
}
+ private BroadcastReceiver torStatusReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (TextUtils.equals(intent.getAction(), OrbotHelper.ACTION_STATUS)) {
+ GeckoAppShell.setTorStatus(intent);
+ }
+ }
+ };
+
public void checkStartOrbot() {
if (!OrbotHelper.isOrbotInstalled(this)) {
final Intent installOrbotIntent = OrbotHelper.getOrbotInstallIntent(this);
@@ -1293,6 +1308,14 @@ public class BrowserApp extends GeckoApp
});
builder.show();
} else {
+ /* run in thread so Tor status updates will be received while the
+ * Gecko event sync is blocking the main thread */
+ HandlerThread handlerThread = new HandlerThread("torStatusReceiver");
+ handlerThread.start();
+ Looper looper = handlerThread.getLooper();
+ Handler handler = new Handler(looper);
+ registerReceiver(torStatusReceiver, new IntentFilter(OrbotHelper.ACTION_STATUS),
+ null, handler);
OrbotHelper.requestStartTor(this);
}
}
@@ -1335,6 +1358,15 @@ public class BrowserApp extends GeckoApp
for (BrowserAppDelegate delegate : delegates) {
delegate.onPause(this);
}
+
+ if (torStatusReceiver != null)
+ {
+ try {
+ unregisterReceiver(torStatusReceiver);
+ } catch (IllegalArgumentException e) {
+ Log.w(LOGTAG, "Tor status receiver couldn't be unregistered", e);
+ }
+ }
}
@Override
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
index 7dbb286cae04..f67603f853e2 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -18,10 +18,13 @@ import java.net.Proxy;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TreeMap;
@@ -39,6 +42,8 @@ import org.mozilla.gecko.util.ProxySelector;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.geckoview.BuildConfig;
+import info.guardianproject.netcipher.proxy.OrbotHelper;
+
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -110,7 +115,11 @@ public class GeckoAppShell
// We have static members only.
private GeckoAppShell() { }
+ /* Initialize as STATUS_OFF */
+ private static String sTorStatus = OrbotHelper.STATUS_OFF;
+
private static final CrashHandler CRASH_HANDLER = new CrashHandler() {
+
@Override
protected String getAppPackageName() {
final Context appContext = getAppContext();
@@ -200,6 +209,8 @@ public class GeckoAppShell
static private int sDensityDpi;
static private int sScreenDepth;
+ static final Queue<Intent> PENDING_URL_INTENTS = new ConcurrentLinkedQueue<Intent>();
+
/* Is the value in sVibrationEndTime valid? */
private static boolean sVibrationMaybePlaying;
@@ -251,6 +262,16 @@ public class GeckoAppShell
private static Rect sScreenSize;
+ static void sendPendingUrlIntents() {
+ try {
+ Context context = getApplicationContext();
+ while (!PENDING_URL_INTENTS.isEmpty()) {
+ final Intent intent = PENDING_URL_INTENTS.poll();
+ context.startActivity(intent);
+ }
+ } catch (NoSuchElementException e) {}
+ }
+
@WrapForJNI(stubName = "NotifyObservers", dispatchTo = "gecko")
private static native void nativeNotifyObservers(String topic, String data);
@@ -1874,4 +1895,15 @@ public class GeckoAppShell
public static String getDefaultLocale() {
return Locale.getDefault().toString();
}
+
+ public static void setTorStatus(Intent intent) {
+ sTorStatus = intent.getStringExtra(OrbotHelper.EXTRA_STATUS);
+ if (OrbotHelper.STATUS_ON.equals(sTorStatus)) {
+ sendPendingUrlIntents();
+ }
+ }
+
+ public static String getTorStatus() {
+ return sTorStatus;
+ }
}