From 2d28dcada205cc77279a3a1ddb3950e20932a099 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Wed, 16 Dec 2015 13:48:56 -0200
Subject: [PATCH] Create two new events to signal enabling and disabling of
 transports

---
 briar-android/res/values/strings.xml          |  4 ++
 .../android/DashboardActivity.java            | 43 ++++++++++++++++++-
 .../plugins/droidtooth/DroidtoothPlugin.java  |  4 +-
 .../briarproject/plugins/tor/TorPlugin.java   | 11 +++--
 .../api/event/TransportDisabledEvent.java     | 17 ++++++++
 .../api/event/TransportEnabledEvent.java      | 17 ++++++++
 .../api/plugins/PluginCallback.java           |  7 ++-
 .../plugins/PluginManagerImpl.java            | 15 ++++++-
 .../briarproject/plugins/tcp/TcpPlugin.java   |  4 +-
 .../plugins/bluetooth/BluetoothPlugin.java    |  4 +-
 .../plugins/DuplexClientTest.java             |  6 ++-
 .../plugins/DuplexServerTest.java             |  6 ++-
 .../plugins/PluginManagerImplTest.java        |  6 ++-
 .../plugins/tcp/LanTcpPluginTest.java         |  6 ++-
 14 files changed, 132 insertions(+), 18 deletions(-)
 create mode 100644 briar-api/src/org/briarproject/api/event/TransportDisabledEvent.java
 create mode 100644 briar-api/src/org/briarproject/api/event/TransportEnabledEvent.java

diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index 0ce4e1c57a..85fe74090e 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -116,6 +116,10 @@
     <string name="online">Online</string>
     <string name="offline">Offline</string>
     <string name="send">Send</string>
+    <string name="data_transports">Data Transports</string>
+    <string name="transport_tor">Internet via Tor</string>
+    <string name="transport_bt">Bluetooth</string>
+    <string name="transport_lan">Local Area Network</string>
 
     <!-- Dialogs -->
     <string name="dialog_title_lost_password">Lost password</string>
diff --git a/briar-android/src/org/briarproject/android/DashboardActivity.java b/briar-android/src/org/briarproject/android/DashboardActivity.java
index fc9d05b881..b499c6794f 100644
--- a/briar-android/src/org/briarproject/android/DashboardActivity.java
+++ b/briar-android/src/org/briarproject/android/DashboardActivity.java
@@ -18,9 +18,19 @@ import org.briarproject.android.contact.ContactListActivity;
 import org.briarproject.android.forum.ForumListActivity;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.LocalAuthor;
+import org.briarproject.api.TransportId;
 import org.briarproject.api.android.ReferenceManager;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.event.Event;
+import org.briarproject.api.event.EventBus;
+import org.briarproject.api.event.EventListener;
+import org.briarproject.api.event.TransportAddedEvent;
+import org.briarproject.api.event.TransportDisabledEvent;
+import org.briarproject.api.event.TransportEnabledEvent;
+import org.briarproject.api.event.TransportRemovedEvent;
+import org.briarproject.api.plugins.Plugin;
+import org.briarproject.api.plugins.PluginManager;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -34,15 +44,17 @@ import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
 
-public class DashboardActivity extends BriarActivity {
+public class DashboardActivity extends BriarActivity implements EventListener {
 
 	private static final Logger LOG =
 			Logger.getLogger(DashboardActivity.class.getName());
 
 	@Inject private ReferenceManager referenceManager;
+	@Inject private PluginManager pluginManager;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
+	@Inject private volatile EventBus eventBus;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -50,12 +62,41 @@ public class DashboardActivity extends BriarActivity {
 		handleIntent(getIntent());
 	}
 
+	@Override
+	public void onResume() {
+		super.onResume();
+
+		eventBus.addListener(this);
+	}
+
+	@Override
+	public void onPause() {
+		super.onPause();
+
+		eventBus.removeListener(this);
+	}
+
 	@Override
 	public void onNewIntent(Intent i) {
 		super.onNewIntent(i);
 		handleIntent(i);
 	}
 
+	@Override
+	public void eventOccurred(Event e) {
+		if (e instanceof TransportEnabledEvent) {
+			TransportId id = ((TransportEnabledEvent) e).getTransportId();
+			if (LOG.isLoggable(INFO)) {
+				LOG.info("TransportEnabledEvent: " + id.getString());
+			}
+		} else if (e instanceof TransportDisabledEvent) {
+			TransportId id = ((TransportDisabledEvent) e).getTransportId();
+			if (LOG.isLoggable(INFO)) {
+				LOG.info("TransportDisabledEvent: " + id.getString());
+			}
+		}
+	}
+
 	private void handleIntent(Intent i) {
 		boolean failed = i.getBooleanExtra("briar.STARTUP_FAILED", false);
 		long handle = i.getLongExtra("briar.LOCAL_AUTHOR_HANDLE", -1);
diff --git a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
index 4191e35617..06dfd1dc9c 100644
--- a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
@@ -172,7 +172,7 @@ class DroidtoothPlugin implements DuplexPlugin {
 				}
 				LOG.info("Socket bound");
 				socket = ss;
-				callback.pollNow();
+				callback.transportEnabled();
 				acceptContactConnections();
 			}
 		});
@@ -196,6 +196,8 @@ class DroidtoothPlugin implements DuplexPlugin {
 			if (ss != null) ss.close();
 		} catch (IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+		} finally {
+			callback.transportDisabled();
 		}
 	}
 
diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
index ffd6919dbf..ebd954dfa5 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
@@ -391,6 +391,8 @@ class TorPlugin implements DuplexPlugin, EventHandler,
 			if (ss != null) ss.close();
 		} catch (IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+		} finally {
+			callback.transportDisabled();
 		}
 	}
 
@@ -459,7 +461,10 @@ class TorPlugin implements DuplexPlugin, EventHandler,
 	private void enableNetwork(boolean enable) throws IOException {
 		if (!running) return;
 		if (LOG.isLoggable(INFO)) LOG.info("Enabling network: " + enable);
-		if (!enable) circuitBuilt.set(false);
+		if (!enable) {
+			circuitBuilt.set(false);
+			callback.transportDisabled();
+		}
 		networkEnabled = enable;
 		controlConnection.setConf("DisableNetwork", enable ? "0" : "1");
 	}
@@ -549,7 +554,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
 	public void circuitStatus(String status, String id, String path) {
 		if (status.equals("BUILT") && !circuitBuilt.getAndSet(true)) {
 			LOG.info("First circuit built");
-			if (isRunning()) callback.pollNow();
+			if (isRunning()) callback.transportEnabled();
 		}
 	}
 
@@ -567,7 +572,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
 		if (LOG.isLoggable(INFO)) LOG.info(severity + " " + msg);
 		if (severity.equals("NOTICE") && msg.startsWith("Bootstrapped 100%")) {
 			bootstrapped = true;
-			if (isRunning()) callback.pollNow();
+			if (isRunning()) callback.transportEnabled();
 		}
 	}
 
diff --git a/briar-api/src/org/briarproject/api/event/TransportDisabledEvent.java b/briar-api/src/org/briarproject/api/event/TransportDisabledEvent.java
new file mode 100644
index 0000000000..1efb575fdf
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/TransportDisabledEvent.java
@@ -0,0 +1,17 @@
+package org.briarproject.api.event;
+
+import org.briarproject.api.TransportId;
+
+/** An event that is broadcast when a transport is disabled. */
+public class TransportDisabledEvent extends Event {
+
+	private final TransportId transportId;
+
+	public TransportDisabledEvent(TransportId transportId) {
+		this.transportId = transportId;
+	}
+
+	public TransportId getTransportId() {
+		return transportId;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/event/TransportEnabledEvent.java b/briar-api/src/org/briarproject/api/event/TransportEnabledEvent.java
new file mode 100644
index 0000000000..7a72d83587
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/TransportEnabledEvent.java
@@ -0,0 +1,17 @@
+package org.briarproject.api.event;
+
+import org.briarproject.api.TransportId;
+
+/** An event that is broadcast when a transport is enabled. */
+public class TransportEnabledEvent extends Event {
+
+	private final TransportId transportId;
+
+	public TransportEnabledEvent(TransportId transportId) {
+		this.transportId = transportId;
+	}
+
+	public TransportId getTransportId() {
+		return transportId;
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/plugins/PluginCallback.java b/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
index 3a5890b2d2..34361a2cab 100644
--- a/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
+++ b/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
@@ -50,6 +50,9 @@ public interface PluginCallback {
 	 */
 	void showMessage(String... message);
 
-	/** Schedules the plugin to be polled immediately. */
-	void pollNow();
+	/** Signal that the transport got enabled. */
+	void transportEnabled();
+
+	/** Signal that the transport got disabled. */
+	void transportDisabled();
 }
diff --git a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
index 5344808482..4742d82513 100644
--- a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
+++ b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
@@ -6,6 +6,9 @@ import org.briarproject.api.TransportId;
 import org.briarproject.api.TransportProperties;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.event.EventBus;
+import org.briarproject.api.event.TransportDisabledEvent;
+import org.briarproject.api.event.TransportEnabledEvent;
 import org.briarproject.api.lifecycle.IoExecutor;
 import org.briarproject.api.plugins.ConnectionManager;
 import org.briarproject.api.plugins.Plugin;
@@ -48,6 +51,7 @@ class PluginManagerImpl implements PluginManager {
 			Logger.getLogger(PluginManagerImpl.class.getName());
 
 	private final Executor ioExecutor;
+	private final EventBus eventBus;
 	private final SimplexPluginConfig simplexPluginConfig;
 	private final DuplexPluginConfig duplexPluginConfig;
 	private final Clock clock;
@@ -60,12 +64,13 @@ class PluginManagerImpl implements PluginManager {
 	private final List<DuplexPlugin> duplexPlugins;
 
 	@Inject
-	PluginManagerImpl(@IoExecutor Executor ioExecutor,
+	PluginManagerImpl(@IoExecutor Executor ioExecutor, EventBus eventBus,
 			SimplexPluginConfig simplexPluginConfig,
 			DuplexPluginConfig duplexPluginConfig, Clock clock,
 			DatabaseComponent db, Poller poller,
 			ConnectionManager connectionManager, UiCallback uiCallback) {
 		this.ioExecutor = ioExecutor;
+		this.eventBus = eventBus;
 		this.simplexPluginConfig = simplexPluginConfig;
 		this.duplexPluginConfig = duplexPluginConfig;
 		this.clock = clock;
@@ -360,10 +365,16 @@ class PluginManagerImpl implements PluginManager {
 			uiCallback.showMessage(message);
 		}
 
-		public void pollNow() {
+		public void transportEnabled() {
+			eventBus.broadcast(new TransportEnabledEvent(id));
+
 			Plugin p = plugins.get(id);
 			if (p != null) poller.pollNow(p);
 		}
+
+		public void transportDisabled() {
+			eventBus.broadcast(new TransportDisabledEvent(id));
+		}
 	}
 
 	private class SimplexCallback extends PluginCallbackImpl
diff --git a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
index 369b5a6d28..48f731464f 100644
--- a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
+++ b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
@@ -106,7 +106,7 @@ abstract class TcpPlugin implements DuplexPlugin {
 				SocketAddress local = ss.getLocalSocketAddress();
 				setLocalSocketAddress((InetSocketAddress) local);
 				if (LOG.isLoggable(INFO)) LOG.info("Listening on " + local);
-				callback.pollNow();
+				callback.transportEnabled();
 				acceptContactConnections();
 			}
 		});
@@ -117,6 +117,8 @@ abstract class TcpPlugin implements DuplexPlugin {
 			if (ss != null) ss.close();
 		} catch (IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+		} finally {
+			callback.transportDisabled();
 		}
 	}
 
diff --git a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
index 3db1dfebfa..792db1398d 100644
--- a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
+++ b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
@@ -117,7 +117,7 @@ class BluetoothPlugin implements DuplexPlugin {
 					return;
 				}
 				socket = ss;
-				callback.pollNow();
+				callback.transportEnabled();
 				acceptContactConnections(ss);
 			}
 		});
@@ -145,6 +145,8 @@ class BluetoothPlugin implements DuplexPlugin {
 			if (ss != null) ss.close();
 		} catch (IOException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+		} finally {
+			callback.transportDisabled();
 		}
 	}
 
diff --git a/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java b/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
index e36624a5dd..a32cf9683b 100644
--- a/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
@@ -100,11 +100,13 @@ public abstract class DuplexClientTest extends DuplexTest {
 
 		public void showMessage(String... message) {}
 
-		public void pollNow() {}
-
 		public void incomingConnectionCreated(DuplexTransportConnection d) {}
 
 		public void outgoingConnectionCreated(ContactId contactId,
 				DuplexTransportConnection d) {}
+
+		public void transportEnabled() {}
+
+		public void transportDisabled() {}
 	}
 }
diff --git a/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java b/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
index ba73b0ace3..daf3c47407 100644
--- a/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
@@ -99,8 +99,6 @@ public abstract class DuplexServerTest extends DuplexTest {
 
 		public void showMessage(String... message) {}
 
-		public void pollNow() {}
-
 		public void incomingConnectionCreated(DuplexTransportConnection d) {
 			System.out.println("Connection received");
 			sendChallengeReceiveResponse(d);
@@ -109,5 +107,9 @@ public abstract class DuplexServerTest extends DuplexTest {
 
 		public void outgoingConnectionCreated(ContactId c,
 				DuplexTransportConnection d) {}
+
+		public void transportEnabled() {}
+
+		public void transportDisabled() {}
 	}
 }
diff --git a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
index 5493a0178b..1394a998b4 100644
--- a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
@@ -3,6 +3,8 @@ package org.briarproject.plugins;
 import org.briarproject.BriarTestCase;
 import org.briarproject.api.TransportId;
 import org.briarproject.api.db.DatabaseComponent;
+import org.briarproject.api.event.EventBus;
+import org.briarproject.api.lifecycle.IoExecutor;
 import org.briarproject.api.plugins.ConnectionManager;
 import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
@@ -32,6 +34,7 @@ public class PluginManagerImplTest extends BriarTestCase {
 		Clock clock = new SystemClock();
 		Mockery context = new Mockery();
 		final Executor ioExecutor = Executors.newCachedThreadPool();
+		final EventBus eventBus = context.mock(EventBus.class);
 		final SimplexPluginConfig simplexPluginConfig =
 				context.mock(SimplexPluginConfig.class);
 		final DuplexPluginConfig duplexPluginConfig =
@@ -121,9 +124,10 @@ public class PluginManagerImplTest extends BriarTestCase {
 			oneOf(simplexPlugin).stop();
 			oneOf(duplexPlugin).stop();
 		}});
-		PluginManagerImpl p = new PluginManagerImpl(ioExecutor,
+		PluginManagerImpl p = new PluginManagerImpl(ioExecutor, eventBus,
 				simplexPluginConfig, duplexPluginConfig, clock, db, poller,
 				dispatcher, uiCallback);
+
 		// Two plugins should be started and stopped
 		assertTrue(p.start());
 		assertTrue(p.stop());
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
index b929c8f528..575b8f136e 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
@@ -205,13 +205,15 @@ public class LanTcpPluginTest extends BriarTestCase {
 
 		public void showMessage(String... message) {}
 
-		public void pollNow() {}
-
 		public void incomingConnectionCreated(DuplexTransportConnection d) {
 			connectionsLatch.countDown();
 		}
 
 		public void outgoingConnectionCreated(ContactId c,
 				DuplexTransportConnection d) {}
+
+		public void transportEnabled() {}
+
+		public void transportDisabled() {}
 	}
 }
-- 
GitLab