diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitor.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitor.java new file mode 100644 index 000000000..e9620c9bd --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitor.java @@ -0,0 +1,45 @@ +package org.briarproject.bramble.mailbox; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.Plugin; + +import javax.annotation.concurrent.ThreadSafe; + +import static java.util.concurrent.TimeUnit.MINUTES; + +@ThreadSafe +@NotNullByDefault +interface TorReachabilityMonitor { + + /** + * How long the Tor plugin needs to be continuously + * {@link Plugin.State#ACTIVE active} before we assume our contacts can + * reach our hidden service. + */ + long REACHABILITY_PERIOD_MS = MINUTES.toMillis(10); + + /** + * Starts the monitor. + */ + void start(); + + /** + * Destroys the monitor. + */ + void destroy(); + + /** + * Adds an observer that will be called when our Tor hidden service becomes + * reachable. If our hidden service is already reachable, the observer is + * called immediately. + *
+ * Observers are removed after being called, or when the monitor is
+ * {@link #destroy() destroyed}.
+ */
+ void addObserver(TorReachabilityObserver o);
+
+ interface TorReachabilityObserver {
+
+ void onTorReachable();
+ }
+}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java
new file mode 100644
index 000000000..a82d1a966
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/TorReachabilityMonitorImpl.java
@@ -0,0 +1,128 @@
+package org.briarproject.bramble.mailbox;
+
+import org.briarproject.bramble.api.Cancellable;
+import org.briarproject.bramble.api.event.Event;
+import org.briarproject.bramble.api.event.EventBus;
+import org.briarproject.bramble.api.event.EventListener;
+import org.briarproject.bramble.api.lifecycle.IoExecutor;
+import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+import org.briarproject.bramble.api.plugin.Plugin;
+import org.briarproject.bramble.api.plugin.PluginManager;
+import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
+import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
+import org.briarproject.bramble.api.system.TaskScheduler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
+import javax.inject.Inject;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
+import static org.briarproject.bramble.api.plugin.TorConstants.ID;
+
+@ThreadSafe
+@NotNullByDefault
+class TorReachabilityMonitorImpl
+ implements TorReachabilityMonitor, EventListener {
+
+ private final Executor ioExecutor;
+ private final TaskScheduler taskScheduler;
+ private final PluginManager pluginManager;
+ private final EventBus eventBus;
+ private final Object lock = new Object();
+
+ @GuardedBy("lock")
+ private boolean reachable = false, destroyed = false;
+
+ @GuardedBy("lock")
+ private final List