From 80fa7d29b2fbb91df4f303a87059d535361b48f3 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 8 May 2020 17:59:12 +0100 Subject: [PATCH] Poll for connections in series, with a delay between attempts. The delay reduces interference between Bluetooth and wifi. --- .../bluetooth/AndroidBluetoothPlugin.java | 12 +++-- .../AndroidBluetoothPluginFactory.java | 14 ++++-- .../plugin/bluetooth/BluetoothPlugin.java | 46 ++++++++++++++----- .../bramble/plugin/DesktopPluginModule.java | 6 ++- .../plugin/bluetooth/JavaBluetoothPlugin.java | 10 ++-- .../bluetooth/JavaBluetoothPluginFactory.java | 12 +++-- .../briarproject/briar/android/AppModule.java | 4 +- 7 files changed, 72 insertions(+), 32 deletions(-) diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java index 9b121f09d..b175d2391 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java @@ -31,6 +31,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -78,11 +79,12 @@ class AndroidBluetoothPlugin extends BluetoothPlugin { AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, TimeoutMonitor timeoutMonitor, Executor ioExecutor, - SecureRandom secureRandom, AndroidExecutor androidExecutor, - Context appContext, Clock clock, Backoff backoff, - PluginCallback callback, int maxLatency, int maxIdleTime) { - super(connectionLimiter, timeoutMonitor, ioExecutor, secureRandom, - backoff, callback, maxLatency, maxIdleTime); + ScheduledExecutorService scheduler, SecureRandom secureRandom, + AndroidExecutor androidExecutor, Context appContext, Clock clock, + Backoff backoff, PluginCallback callback, int maxLatency, + int maxIdleTime) { + super(connectionLimiter, timeoutMonitor, ioExecutor, scheduler, + secureRandom, backoff, callback, maxLatency, maxIdleTime); this.androidExecutor = androidExecutor; this.appContext = appContext; this.clock = clock; diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java index bbf2e2744..bbecd02d2 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java @@ -16,6 +16,7 @@ import org.briarproject.bramble.api.system.Clock; import java.security.SecureRandom; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import javax.annotation.concurrent.Immutable; @@ -32,6 +33,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory { private static final double BACKOFF_BASE = 1.2; private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; private final AndroidExecutor androidExecutor; private final Context appContext; private final SecureRandom secureRandom; @@ -41,10 +43,12 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory { private final BackoffFactory backoffFactory; public AndroidBluetoothPluginFactory(Executor ioExecutor, - AndroidExecutor androidExecutor, Context appContext, - SecureRandom secureRandom, EventBus eventBus, Clock clock, - TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) { + ScheduledExecutorService scheduler, AndroidExecutor androidExecutor, + Context appContext, SecureRandom secureRandom, EventBus eventBus, + Clock clock, TimeoutMonitor timeoutMonitor, + BackoffFactory backoffFactory) { this.ioExecutor = ioExecutor; + this.scheduler = scheduler; this.androidExecutor = androidExecutor; this.appContext = appContext; this.secureRandom = secureRandom; @@ -71,8 +75,8 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin( - connectionLimiter, timeoutMonitor, ioExecutor, secureRandom, - androidExecutor, appContext, clock, backoff, + connectionLimiter, timeoutMonitor, ioExecutor, scheduler, + secureRandom, androidExecutor, appContext, clock, backoff, callback, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index 9187c538b..fc539e620 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -31,13 +31,17 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import java.io.IOException; import java.security.SecureRandom; import java.util.Collection; +import java.util.LinkedList; import java.util.UUID; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import javax.annotation.Nullable; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; @@ -60,10 +64,18 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { private static final Logger LOG = getLogger(BluetoothPlugin.class.getName()); + /** + * The delay between connection attempts when polling. This reduces + * interference between Bluetooth and wifi. + */ + private static final long CONNECTION_ATTEMPT_INTERVAL_MS = + SECONDS.toMillis(5); + final BluetoothConnectionLimiter connectionLimiter; final TimeoutMonitor timeoutMonitor; private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; private final SecureRandom secureRandom; private final Backoff backoff; private final PluginCallback callback; @@ -108,11 +120,13 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, TimeoutMonitor timeoutMonitor, Executor ioExecutor, - SecureRandom secureRandom, Backoff backoff, - PluginCallback callback, int maxLatency, int maxIdleTime) { + ScheduledExecutorService scheduler, SecureRandom secureRandom, + Backoff backoff, PluginCallback callback, int maxLatency, + int maxIdleTime) { this.connectionLimiter = connectionLimiter; this.timeoutMonitor = timeoutMonitor; this.ioExecutor = ioExecutor; + this.scheduler = scheduler; this.secureRandom = secureRandom; this.backoff = backoff; this.callback = callback; @@ -268,21 +282,31 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { properties) { if (!isRunning() || !shouldAllowContactConnections()) return; backoff.increment(); - for (Pair p : properties) { - connect(p.getFirst(), p.getSecond()); + LinkedList> connectable = + new LinkedList<>(); + for (Pair pair : properties) { + TransportProperties p = pair.getFirst(); + if (isNullOrEmpty(p.get(PROP_ADDRESS))) continue; + if (isNullOrEmpty(p.get(PROP_UUID))) continue; + connectable.add(pair); } + if (!connectable.isEmpty()) poll(connectable); } - private void connect(TransportProperties p, ConnectionHandler h) { - String address = p.get(PROP_ADDRESS); - if (isNullOrEmpty(address)) return; - String uuid = p.get(PROP_UUID); - if (isNullOrEmpty(uuid)) return; + private void poll(LinkedList> + connectable) { ioExecutor.execute(() -> { - DuplexTransportConnection d = createConnection(p); + if (!isRunning() || !shouldAllowContactConnections()) return; + Pair pair = + connectable.removeFirst(); + DuplexTransportConnection d = createConnection(pair.getFirst()); if (d != null) { backoff.reset(); - h.handleConnection(d); + pair.getSecond().handleConnection(d); + } + if (!connectable.isEmpty()) { + scheduler.schedule(() -> poll(connectable), + CONNECTION_ATTEMPT_INTERVAL_MS, MILLISECONDS); } }); } diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java index c00bd99d7..4edc6362b 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/DesktopPluginModule.java @@ -10,6 +10,7 @@ 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.reliability.ReliabilityLayerFactory; +import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.plugin.bluetooth.JavaBluetoothPluginFactory; import org.briarproject.bramble.plugin.modem.ModemPluginFactory; import org.briarproject.bramble.plugin.tcp.LanTcpPluginFactory; @@ -18,6 +19,7 @@ import org.briarproject.bramble.plugin.tcp.WanTcpPluginFactory; import java.security.SecureRandom; import java.util.Collection; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import dagger.Module; import dagger.Provides; @@ -30,12 +32,14 @@ public class DesktopPluginModule extends PluginModule { @Provides PluginConfig getPluginConfig(@IoExecutor Executor ioExecutor, + @Scheduler ScheduledExecutorService scheduler, SecureRandom random, BackoffFactory backoffFactory, ReliabilityLayerFactory reliabilityFactory, ShutdownManager shutdownManager, EventBus eventBus, TimeoutMonitor timeoutMonitor) { DuplexPluginFactory bluetooth = new JavaBluetoothPluginFactory( - ioExecutor, random, eventBus, timeoutMonitor, backoffFactory); + ioExecutor, scheduler, random, eventBus, timeoutMonitor, + backoffFactory); DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor, reliabilityFactory); DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor, diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java index ff9b7ee79..0c853120f 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java @@ -10,6 +10,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import java.io.IOException; import java.security.SecureRandom; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -36,10 +37,11 @@ class JavaBluetoothPlugin extends BluetoothPlugin { JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager, TimeoutMonitor timeoutMonitor, Executor ioExecutor, - SecureRandom secureRandom, Backoff backoff, - PluginCallback callback, int maxLatency, int maxIdleTime) { - super(connectionManager, timeoutMonitor, ioExecutor, secureRandom, - backoff, callback, maxLatency, maxIdleTime); + ScheduledExecutorService scheduler, SecureRandom secureRandom, + Backoff backoff, PluginCallback callback, int maxLatency, + int maxIdleTime) { + super(connectionManager, timeoutMonitor, ioExecutor, scheduler, + secureRandom, backoff, callback, maxLatency, maxIdleTime); } @Override diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java index 59fc25c86..8a1ebb521 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java @@ -12,6 +12,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import java.security.SecureRandom; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import javax.annotation.concurrent.Immutable; @@ -28,15 +29,18 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory { private static final double BACKOFF_BASE = 1.2; private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; private final SecureRandom secureRandom; private final EventBus eventBus; private final TimeoutMonitor timeoutMonitor; private final BackoffFactory backoffFactory; public JavaBluetoothPluginFactory(Executor ioExecutor, - SecureRandom secureRandom, EventBus eventBus, - TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) { + ScheduledExecutorService scheduler, SecureRandom secureRandom, + EventBus eventBus, TimeoutMonitor timeoutMonitor, + BackoffFactory backoffFactory) { this.ioExecutor = ioExecutor; + this.scheduler = scheduler; this.secureRandom = secureRandom; this.eventBus = eventBus; this.timeoutMonitor = timeoutMonitor; @@ -60,8 +64,8 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter, - timeoutMonitor, ioExecutor, secureRandom, backoff, callback, - MAX_LATENCY, MAX_IDLE_TIME); + timeoutMonitor, ioExecutor, scheduler, secureRandom, backoff, + callback, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; } 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 b9e074897..ddabafa32 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 @@ -127,8 +127,8 @@ public class AppModule { TimeoutMonitor timeoutMonitor) { Context appContext = app.getApplicationContext(); DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory( - ioExecutor, androidExecutor, appContext, random, eventBus, - clock, timeoutMonitor, backoffFactory); + ioExecutor, scheduler, androidExecutor, appContext, random, + eventBus, clock, timeoutMonitor, backoffFactory); DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor, scheduler, appContext, networkManager, locationUtils, eventBus, torSocketFactory, backoffFactory, resourceProvider,