From c6b88b51f0e01414728b498fa0eaf3c15fd619cf Mon Sep 17 00:00:00 2001
From: goapunk <goapunk@riseup.net>
Date: Tue, 22 May 2018 14:21:55 +0200
Subject: [PATCH] Make plugins and polling configurable

* Move PluginConfig out of bramble-android. Projects using bramble now need to provide it.
* Add a PluginConfig#shouldPoll() method which can be used to disable polling altogether.
* Move Poller instantiation to the PluginManager.
---
 .../bramble/BrambleAndroidModule.java         |  2 -
 .../bramble/plugin/AndroidPluginModule.java   | 67 -------------------
 .../bramble/api/plugin/PluginConfig.java      |  2 +
 .../bramble/plugin/PluginManagerImpl.java     | 26 ++++++-
 .../bramble/plugin/PluginModule.java          | 15 -----
 .../briarproject/bramble/plugin/Poller.java   |  1 -
 .../bramble/plugin/PluginManagerImplTest.java | 20 +++++-
 .../bramble/test/TestPluginConfigModule.java  |  5 ++
 .../bramble/plugin/DesktopPluginModule.java   |  5 ++
 .../briarproject/briar/android/AppModule.java | 60 +++++++++++++++++
 10 files changed, 114 insertions(+), 89 deletions(-)
 delete mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java

diff --git a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java
index dd5e9c3942..1ec2563482 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java
@@ -1,12 +1,10 @@
 package org.briarproject.bramble;
 
-import org.briarproject.bramble.plugin.AndroidPluginModule;
 import org.briarproject.bramble.system.AndroidSystemModule;
 
 import dagger.Module;
 
 @Module(includes = {
-		AndroidPluginModule.class,
 		AndroidSystemModule.class
 })
 public class BrambleAndroidModule {
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java
deleted file mode 100644
index 0714b8d478..0000000000
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.briarproject.bramble.plugin;
-
-import android.app.Application;
-import android.content.Context;
-
-import org.briarproject.bramble.api.event.EventBus;
-import org.briarproject.bramble.api.lifecycle.IoExecutor;
-import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
-import org.briarproject.bramble.api.plugin.BackoffFactory;
-import org.briarproject.bramble.api.plugin.PluginConfig;
-import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
-import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
-import org.briarproject.bramble.api.system.AndroidExecutor;
-import org.briarproject.bramble.api.system.LocationUtils;
-import org.briarproject.bramble.api.system.Scheduler;
-import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
-import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory;
-import org.briarproject.bramble.plugin.tor.TorPluginFactory;
-
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-import javax.net.SocketFactory;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public class AndroidPluginModule {
-
-	@Provides
-	PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
-			@Scheduler ScheduledExecutorService scheduler,
-			AndroidExecutor androidExecutor, SecureRandom random,
-			SocketFactory torSocketFactory, BackoffFactory backoffFactory,
-			Application app, LocationUtils locationUtils, EventBus eventBus) {
-		Context appContext = app.getApplicationContext();
-		DuplexPluginFactory bluetooth =
-				new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
-						appContext, random, eventBus, backoffFactory);
-		DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler,
-				appContext, locationUtils, eventBus, torSocketFactory,
-				backoffFactory);
-		DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
-				scheduler, backoffFactory, appContext);
-		Collection<DuplexPluginFactory> duplex =
-				Arrays.asList(bluetooth, tor, lan);
-		@NotNullByDefault
-		PluginConfig pluginConfig = new PluginConfig() {
-
-			@Override
-			public Collection<DuplexPluginFactory> getDuplexFactories() {
-				return duplex;
-			}
-
-			@Override
-			public Collection<SimplexPluginFactory> getSimplexFactories() {
-				return Collections.emptyList();
-			}
-		};
-		return pluginConfig;
-	}
-}
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginConfig.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginConfig.java
index 5518b7c6bc..6bf13cedde 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginConfig.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginConfig.java
@@ -12,4 +12,6 @@ public interface PluginConfig {
 	Collection<DuplexPluginFactory> getDuplexFactories();
 
 	Collection<SimplexPluginFactory> getSimplexFactories();
+
+	boolean shouldPoll();
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
index 7e05f5b347..a534eb357e 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.lifecycle.Service;
 import org.briarproject.bramble.api.lifecycle.ServiceException;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 import org.briarproject.bramble.api.plugin.ConnectionManager;
+import org.briarproject.bramble.api.plugin.ConnectionRegistry;
 import org.briarproject.bramble.api.plugin.Plugin;
 import org.briarproject.bramble.api.plugin.PluginCallback;
 import org.briarproject.bramble.api.plugin.PluginConfig;
@@ -29,8 +30,11 @@ import org.briarproject.bramble.api.properties.TransportProperties;
 import org.briarproject.bramble.api.properties.TransportPropertyManager;
 import org.briarproject.bramble.api.settings.Settings;
 import org.briarproject.bramble.api.settings.SettingsManager;
+import org.briarproject.bramble.api.system.Clock;
+import org.briarproject.bramble.api.system.Scheduler;
 import org.briarproject.bramble.api.ui.UiCallback;
 
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -40,6 +44,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
@@ -57,11 +62,15 @@ class PluginManagerImpl implements PluginManager, Service {
 			Logger.getLogger(PluginManagerImpl.class.getName());
 
 	private final Executor ioExecutor;
+	private final ScheduledExecutorService scheduler;
 	private final EventBus eventBus;
 	private final PluginConfig pluginConfig;
 	private final ConnectionManager connectionManager;
+	private final ConnectionRegistry connectionRegistry;
 	private final SettingsManager settingsManager;
 	private final TransportPropertyManager transportPropertyManager;
+	private final SecureRandom random;
+	private final Clock clock;
 	private final UiCallback uiCallback;
 	private final Map<TransportId, Plugin> plugins;
 	private final List<SimplexPlugin> simplexPlugins;
@@ -70,22 +79,30 @@ class PluginManagerImpl implements PluginManager, Service {
 	private final AtomicBoolean used = new AtomicBoolean(false);
 
 	@Inject
-	PluginManagerImpl(@IoExecutor Executor ioExecutor, EventBus eventBus,
+	PluginManagerImpl(@IoExecutor Executor ioExecutor,
+			@Scheduler ScheduledExecutorService scheduler, EventBus eventBus,
 			PluginConfig pluginConfig, ConnectionManager connectionManager,
+			ConnectionRegistry connectionRegistry,
 			SettingsManager settingsManager,
 			TransportPropertyManager transportPropertyManager,
+			SecureRandom random, Clock clock,
 			UiCallback uiCallback) {
 		this.ioExecutor = ioExecutor;
+		this.scheduler = scheduler;
 		this.eventBus = eventBus;
 		this.pluginConfig = pluginConfig;
 		this.connectionManager = connectionManager;
+		this.connectionRegistry = connectionRegistry;
 		this.settingsManager = settingsManager;
 		this.transportPropertyManager = transportPropertyManager;
+		this.random = random;
+		this.clock = clock;
 		this.uiCallback = uiCallback;
 		plugins = new ConcurrentHashMap<>();
 		simplexPlugins = new CopyOnWriteArrayList<>();
 		duplexPlugins = new CopyOnWriteArrayList<>();
 		startLatches = new ConcurrentHashMap<>();
+
 	}
 
 	@Override
@@ -123,6 +140,13 @@ class PluginManagerImpl implements PluginManager, Service {
 				ioExecutor.execute(new PluginStarter(d, startLatch));
 			}
 		}
+		// Instantiate the poller
+		if (pluginConfig.shouldPoll()) {
+			LOG.info("Starting poller");
+			Poller poller = new Poller(ioExecutor, scheduler, connectionManager,
+					connectionRegistry, this, random, clock);
+			eventBus.addListener(poller);
+		}
 	}
 
 	@Override
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java
index 43ed215557..773910481b 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java
@@ -26,8 +26,6 @@ public class PluginModule {
 	public static class EagerSingletons {
 		@Inject
 		PluginManager pluginManager;
-		@Inject
-		Poller poller;
 	}
 
 	@Provides
@@ -35,19 +33,6 @@ public class PluginModule {
 		return new BackoffFactoryImpl();
 	}
 
-	@Provides
-	@Singleton
-	Poller providePoller(@IoExecutor Executor ioExecutor,
-			@Scheduler ScheduledExecutorService scheduler,
-			ConnectionManager connectionManager,
-			ConnectionRegistry connectionRegistry, PluginManager pluginManager,
-			SecureRandom random, Clock clock, EventBus eventBus) {
-		Poller poller = new Poller(ioExecutor, scheduler, connectionManager,
-				connectionRegistry, pluginManager, random, clock);
-		eventBus.addListener(poller);
-		return poller;
-	}
-
 	@Provides
 	@Singleton
 	ConnectionManager provideConnectionManager(
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
index 61a5c6137a..c68126282a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
@@ -54,7 +54,6 @@ class Poller implements EventListener {
 	private final Lock lock;
 	private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
 
-	@Inject
 	Poller(@IoExecutor Executor ioExecutor,
 			@Scheduler ScheduledExecutorService scheduler,
 			ConnectionManager connectionManager,
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
index aa96dc3966..958f1218df 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java
@@ -2,6 +2,7 @@ package org.briarproject.bramble.plugin;
 
 import org.briarproject.bramble.api.event.EventBus;
 import org.briarproject.bramble.api.plugin.ConnectionManager;
+import org.briarproject.bramble.api.plugin.ConnectionRegistry;
 import org.briarproject.bramble.api.plugin.PluginConfig;
 import org.briarproject.bramble.api.plugin.PluginException;
 import org.briarproject.bramble.api.plugin.TransportId;
@@ -13,6 +14,7 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback;
 import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
 import org.briarproject.bramble.api.properties.TransportPropertyManager;
 import org.briarproject.bramble.api.settings.SettingsManager;
+import org.briarproject.bramble.api.system.Clock;
 import org.briarproject.bramble.api.ui.UiCallback;
 import org.briarproject.bramble.test.BrambleTestCase;
 import org.jmock.Expectations;
@@ -20,9 +22,13 @@ import org.jmock.Mockery;
 import org.jmock.lib.concurrent.Synchroniser;
 import org.junit.Test;
 
+import java.security.SecureRandom;
 import java.util.Arrays;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 import static org.briarproject.bramble.test.TestUtils.getTransportId;
 
@@ -34,10 +40,16 @@ public class PluginManagerImplTest extends BrambleTestCase {
 			setThreadingPolicy(new Synchroniser());
 		}};
 		Executor ioExecutor = Executors.newSingleThreadExecutor();
+		RejectedExecutionHandler policy =
+				new ScheduledThreadPoolExecutor.DiscardPolicy();
+		ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1, policy);
+		SecureRandom random = new SecureRandom();
+		Clock clock = context.mock(Clock.class);
 		EventBus eventBus = context.mock(EventBus.class);
 		PluginConfig pluginConfig = context.mock(PluginConfig.class);
 		ConnectionManager connectionManager =
 				context.mock(ConnectionManager.class);
+		ConnectionRegistry connectionRegistry = context.mock(ConnectionRegistry.class);
 		SettingsManager settingsManager =
 				context.mock(SettingsManager.class);
 		TransportPropertyManager transportPropertyManager =
@@ -71,6 +83,8 @@ public class PluginManagerImplTest extends BrambleTestCase {
 			will(returnValue(simplexFailId));
 			allowing(duplexPlugin).getId();
 			will(returnValue(duplexId));
+			allowing(pluginConfig).shouldPoll();
+			will(returnValue(false));
 			// start()
 			// First simplex plugin
 			oneOf(pluginConfig).getSimplexFactories();
@@ -112,9 +126,9 @@ public class PluginManagerImplTest extends BrambleTestCase {
 			oneOf(duplexPlugin).stop();
 		}});
 
-		PluginManagerImpl p = new PluginManagerImpl(ioExecutor, eventBus,
-				pluginConfig, connectionManager, settingsManager,
-				transportPropertyManager, uiCallback);
+		PluginManagerImpl p = new PluginManagerImpl(ioExecutor, scheduler, eventBus,
+				pluginConfig, connectionManager, connectionRegistry, settingsManager,
+				transportPropertyManager, random, clock, uiCallback);
 
 		// Two plugins should be started and stopped
 		p.startService();
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java
index e016abc4d9..9617834595 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java
@@ -58,6 +58,11 @@ public class TestPluginConfigModule {
 			public Collection<SimplexPluginFactory> getSimplexFactories() {
 				return Collections.singletonList(simplex);
 			}
+
+			@Override
+			public boolean shouldPoll() {
+				return false;
+			}
 		};
 		return pluginConfig;
 	}
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
index 288a34b901..2a44d0e44f 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java
@@ -59,6 +59,11 @@ public class DesktopPluginModule extends PluginModule {
 			public Collection<SimplexPluginFactory> getSimplexFactories() {
 				return simplex;
 			}
+
+			@Override
+			public boolean shouldPoll() {
+				return true;
+			}
 		};
 		return pluginConfig;
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
index ed954e2414..a8c958ea8a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
@@ -1,6 +1,7 @@
 package org.briarproject.briar.android;
 
 import android.app.Application;
+import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.StrictMode;
 
@@ -8,13 +9,25 @@ import org.briarproject.bramble.api.crypto.CryptoComponent;
 import org.briarproject.bramble.api.crypto.PublicKey;
 import org.briarproject.bramble.api.db.DatabaseConfig;
 import org.briarproject.bramble.api.event.EventBus;
+import org.briarproject.bramble.api.lifecycle.IoExecutor;
 import org.briarproject.bramble.api.lifecycle.LifecycleManager;
 import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.bramble.api.plugin.BackoffFactory;
+import org.briarproject.bramble.api.plugin.PluginConfig;
+import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
+import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
 import org.briarproject.bramble.api.reporting.DevConfig;
+import org.briarproject.bramble.api.reporting.DevReporter;
+import org.briarproject.bramble.api.system.AndroidExecutor;
+import org.briarproject.bramble.api.system.LocationUtils;
+import org.briarproject.bramble.api.system.Scheduler;
 import org.briarproject.bramble.api.ui.UiCallback;
 import org.briarproject.bramble.util.AndroidUtils;
+import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
+import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory;
+import org.briarproject.bramble.plugin.tor.TorPluginFactory;
 import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.api.android.AndroidNotificationManager;
 import org.briarproject.briar.api.android.DozeWatchdog;
@@ -23,9 +36,16 @@ import org.briarproject.briar.api.android.ScreenFilterMonitor;
 
 import java.io.File;
 import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import javax.net.SocketFactory;
 
 import dagger.Module;
 import dagger.Provides;
@@ -97,6 +117,46 @@ public class AppModule {
 		return databaseConfig;
 	}
 
+	@Provides
+	PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
+			@Scheduler ScheduledExecutorService scheduler,
+			AndroidExecutor androidExecutor, SecureRandom random,
+			SocketFactory torSocketFactory, BackoffFactory backoffFactory,
+			Application app, LocationUtils locationUtils, DevReporter reporter,
+			EventBus eventBus) {
+		Context appContext = app.getApplicationContext();
+		DuplexPluginFactory bluetooth =
+				new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
+						appContext, random, eventBus, backoffFactory);
+		DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler,
+				appContext, locationUtils, eventBus,
+				torSocketFactory, backoffFactory);
+		DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
+				scheduler, backoffFactory, appContext);
+		Collection<DuplexPluginFactory> duplex =
+				Arrays.asList(bluetooth, tor, lan);
+		@NotNullByDefault
+		PluginConfig pluginConfig = new PluginConfig() {
+
+			@Override
+			public Collection<DuplexPluginFactory> getDuplexFactories() {
+				return duplex;
+			}
+
+			@Override
+			public Collection<SimplexPluginFactory> getSimplexFactories() {
+				return Collections.emptyList();
+			}
+
+			@Override
+			public boolean shouldPoll() {
+				return true;
+			}
+
+		};
+		return pluginConfig;
+	}
+
 	@Provides
 	@Singleton
 	DevConfig provideDevConfig(Application app, CryptoComponent crypto) {
-- 
GitLab