Refactor wake lock creation.

This commit is contained in:
akwizgran
2020-08-04 12:47:35 +01:00
parent 090123579d
commit d794777eb2
18 changed files with 248 additions and 98 deletions

View File

@@ -0,0 +1,19 @@
package org.briarproject.bramble.api.system;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface AndroidWakeLock {
/**
* Acquires the wake lock. This has no effect if the wake lock has already
* been acquired.
*/
void acquire();
/**
* Releases the wake lock. This has no effect if the wake lock has already
* been released.
*/
void release();
}

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble.api.system;
import android.os.PowerManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface AndroidWakeLockFactory {
/**
* Creates and returns a wake lock.
*
* @param levelAndFlags See {@link PowerManager#newWakeLock(int, String)}
*/
AndroidWakeLock createWakeLock(int levelAndFlags);
}

View File

@@ -0,0 +1,36 @@
package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothSocket;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import java.io.IOException;
@NotNullByDefault
class AndroidBluetoothConnectionFactory
implements BluetoothConnectionFactory<BluetoothSocket> {
private final BluetoothConnectionLimiter connectionLimiter;
private final AndroidWakeLockFactory wakeLockFactory;
private final TimeoutMonitor timeoutMonitor;
AndroidBluetoothConnectionFactory(
BluetoothConnectionLimiter connectionLimiter,
AndroidWakeLockFactory wakeLockFactory,
TimeoutMonitor timeoutMonitor) {
this.connectionLimiter = connectionLimiter;
this.wakeLockFactory = wakeLockFactory;
this.timeoutMonitor = timeoutMonitor;
}
@Override
public DuplexTransportConnection wrapSocket(DuplexPlugin plugin,
BluetoothSocket s) throws IOException {
return new AndroidBluetoothTransportConnection(plugin,
connectionLimiter, wakeLockFactory, timeoutMonitor, s);
}
}

View File

@@ -9,7 +9,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.Backoff;
@@ -18,7 +17,6 @@ import org.briarproject.bramble.api.plugin.PluginException;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.IoUtils; import org.briarproject.bramble.util.IoUtils;
@@ -60,14 +58,14 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> { class AndroidBluetoothPlugin
extends BluetoothPlugin<BluetoothSocket, BluetoothServerSocket> {
private static final Logger LOG = private static final Logger LOG =
getLogger(AndroidBluetoothPlugin.class.getName()); getLogger(AndroidBluetoothPlugin.class.getName());
private static final int MAX_DISCOVERY_MS = 10_000; private static final int MAX_DISCOVERY_MS = 10_000;
private final TaskScheduler scheduler;
private final AndroidExecutor androidExecutor; private final AndroidExecutor androidExecutor;
private final Context appContext; private final Context appContext;
private final Clock clock; private final Clock clock;
@@ -79,10 +77,9 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private volatile BluetoothAdapter adapter = null; private volatile BluetoothAdapter adapter = null;
AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor, BluetoothConnectionFactory<BluetoothSocket> connectionFactory,
Executor ioExecutor, Executor ioExecutor,
SecureRandom secureRandom, SecureRandom secureRandom,
TaskScheduler scheduler,
AndroidExecutor androidExecutor, AndroidExecutor androidExecutor,
Context appContext, Context appContext,
Clock clock, Clock clock,
@@ -90,9 +87,8 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
PluginCallback callback, PluginCallback callback,
int maxLatency, int maxLatency,
int maxIdleTime) { int maxIdleTime) {
super(connectionLimiter, timeoutMonitor, ioExecutor, secureRandom, super(connectionLimiter, connectionFactory, ioExecutor, secureRandom,
backoff, callback, maxLatency, maxIdleTime); backoff, callback, maxLatency, maxIdleTime);
this.scheduler = scheduler;
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
this.appContext = appContext; this.appContext = appContext;
this.clock = clock; this.clock = clock;
@@ -187,13 +183,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
@Override @Override
DuplexTransportConnection acceptConnection(BluetoothServerSocket ss) DuplexTransportConnection acceptConnection(BluetoothServerSocket ss)
throws IOException { throws IOException {
return wrapSocket(ss.accept()); return connectionFactory.wrapSocket(this, ss.accept());
}
private DuplexTransportConnection wrapSocket(BluetoothSocket s)
throws IOException {
return new AndroidBluetoothTransportConnection(this, connectionLimiter,
timeoutMonitor, appContext, scheduler, s);
} }
@Override @Override
@@ -210,7 +200,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
try { try {
s = d.createInsecureRfcommSocketToServiceRecord(u); s = d.createInsecureRfcommSocketToServiceRecord(u);
s.connect(); s.connect();
return wrapSocket(s); return connectionFactory.wrapSocket(this, s);
} catch (IOException e) { } catch (IOException e) {
IoUtils.tryToClose(s, LOG, WARNING); IoUtils.tryToClose(s, LOG, WARNING);
throw e; throw e;

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.plugin.bluetooth; package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothSocket;
import android.content.Context; import android.content.Context;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
@@ -12,8 +13,8 @@ import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -33,8 +34,8 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2; private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor; private final Executor ioExecutor;
private final TaskScheduler scheduler;
private final AndroidExecutor androidExecutor; private final AndroidExecutor androidExecutor;
private final AndroidWakeLockFactory wakeLockFactory;
private final Context appContext; private final Context appContext;
private final SecureRandom secureRandom; private final SecureRandom secureRandom;
private final EventBus eventBus; private final EventBus eventBus;
@@ -43,8 +44,8 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private final BackoffFactory backoffFactory; private final BackoffFactory backoffFactory;
public AndroidBluetoothPluginFactory(Executor ioExecutor, public AndroidBluetoothPluginFactory(Executor ioExecutor,
TaskScheduler scheduler,
AndroidExecutor androidExecutor, AndroidExecutor androidExecutor,
AndroidWakeLockFactory wakeLockFactory,
Context appContext, Context appContext,
SecureRandom secureRandom, SecureRandom secureRandom,
EventBus eventBus, EventBus eventBus,
@@ -52,8 +53,8 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
TimeoutMonitor timeoutMonitor, TimeoutMonitor timeoutMonitor,
BackoffFactory backoffFactory) { BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.androidExecutor = androidExecutor; this.androidExecutor = androidExecutor;
this.wakeLockFactory = wakeLockFactory;
this.appContext = appContext; this.appContext = appContext;
this.secureRandom = secureRandom; this.secureRandom = secureRandom;
this.eventBus = eventBus; this.eventBus = eventBus;
@@ -76,12 +77,15 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
public DuplexPlugin createPlugin(PluginCallback callback) { public DuplexPlugin createPlugin(PluginCallback callback) {
BluetoothConnectionLimiter connectionLimiter = BluetoothConnectionLimiter connectionLimiter =
new BluetoothConnectionLimiterImpl(eventBus); new BluetoothConnectionLimiterImpl(eventBus);
BluetoothConnectionFactory<BluetoothSocket> connectionFactory =
new AndroidBluetoothConnectionFactory(connectionLimiter,
wakeLockFactory, timeoutMonitor);
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin( AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
connectionLimiter, timeoutMonitor, ioExecutor, secureRandom, connectionLimiter, connectionFactory, ioExecutor, secureRandom,
scheduler, androidExecutor, appContext, clock, backoff, androidExecutor, appContext, clock, backoff, callback,
callback, MAX_LATENCY, MAX_IDLE_TIME); MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;
} }

View File

@@ -1,26 +1,20 @@
package org.briarproject.bramble.plugin.bluetooth; package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.PowerManager;
import org.briarproject.bramble.api.io.TimeoutMonitor; import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection; import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
import org.briarproject.bramble.api.system.TaskScheduler; import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.util.RenewableWakeLock; import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import static android.content.Context.POWER_SERVICE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
import static org.briarproject.bramble.util.AndroidUtils.getWakeLockTag;
import static org.briarproject.bramble.util.AndroidUtils.isValidBluetoothAddress; import static org.briarproject.bramble.util.AndroidUtils.isValidBluetoothAddress;
@NotNullByDefault @NotNullByDefault
@@ -28,26 +22,21 @@ class AndroidBluetoothTransportConnection
extends AbstractDuplexTransportConnection { extends AbstractDuplexTransportConnection {
private final BluetoothConnectionLimiter connectionLimiter; private final BluetoothConnectionLimiter connectionLimiter;
private final RenewableWakeLock wakeLock;
private final BluetoothSocket socket; private final BluetoothSocket socket;
private final InputStream in; private final InputStream in;
private final AndroidWakeLock wakeLock;
AndroidBluetoothTransportConnection(Plugin plugin, AndroidBluetoothTransportConnection(Plugin plugin,
BluetoothConnectionLimiter connectionLimiter, BluetoothConnectionLimiter connectionLimiter,
AndroidWakeLockFactory wakeLockFactory,
TimeoutMonitor timeoutMonitor, TimeoutMonitor timeoutMonitor,
Context appContext,
TaskScheduler scheduler,
BluetoothSocket socket) throws IOException { BluetoothSocket socket) throws IOException {
super(plugin); super(plugin);
this.connectionLimiter = connectionLimiter; this.connectionLimiter = connectionLimiter;
this.socket = socket; this.socket = socket;
in = timeoutMonitor.createTimeoutInputStream( in = timeoutMonitor.createTimeoutInputStream(
socket.getInputStream(), plugin.getMaxIdleTime() * 2); socket.getInputStream(), plugin.getMaxIdleTime() * 2);
PowerManager powerManager = (PowerManager) wakeLock = wakeLockFactory.createWakeLock(PARTIAL_WAKE_LOCK);
requireNonNull(appContext.getSystemService(POWER_SERVICE));
String tag = getWakeLockTag(appContext);
wakeLock = new RenewableWakeLock(powerManager, scheduler,
PARTIAL_WAKE_LOCK, tag, 1, MINUTES);
wakeLock.acquire(); wakeLock.acquire();
String address = socket.getRemoteDevice().getAddress(); String address = socket.getRemoteDevice().getAddress();
if (isValidBluetoothAddress(address)) remote.put(PROP_ADDRESS, address); if (isValidBluetoothAddress(address)) remote.put(PROP_ADDRESS, address);

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.PowerManager;
import org.briarproject.bramble.api.battery.BatteryManager; import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkManager;
@@ -12,11 +11,11 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginCallback;
import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.util.RenewableWakeLock;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -24,20 +23,16 @@ import java.util.concurrent.Executor;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static android.content.Context.MODE_PRIVATE; import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.POWER_SERVICE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.briarproject.bramble.util.AndroidUtils.getWakeLockTag;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class AndroidTorPlugin extends TorPlugin { class AndroidTorPlugin extends TorPlugin {
private final Context appContext; private final Context appContext;
private final RenewableWakeLock wakeLock; private final AndroidWakeLock wakeLock;
AndroidTorPlugin(Executor ioExecutor, AndroidTorPlugin(Executor ioExecutor,
TaskScheduler scheduler,
Context appContext, Context appContext,
NetworkManager networkManager, NetworkManager networkManager,
LocationUtils locationUtils, LocationUtils locationUtils,
@@ -46,6 +41,7 @@ class AndroidTorPlugin extends TorPlugin {
ResourceProvider resourceProvider, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, CircumventionProvider circumventionProvider,
BatteryManager batteryManager, BatteryManager batteryManager,
AndroidWakeLockFactory wakeLockFactory,
Backoff backoff, Backoff backoff,
TorRendezvousCrypto torRendezvousCrypto, TorRendezvousCrypto torRendezvousCrypto,
PluginCallback callback, PluginCallback callback,
@@ -58,11 +54,7 @@ class AndroidTorPlugin extends TorPlugin {
maxLatency, maxIdleTime, maxLatency, maxIdleTime,
appContext.getDir("tor", MODE_PRIVATE)); appContext.getDir("tor", MODE_PRIVATE));
this.appContext = appContext; this.appContext = appContext;
PowerManager pm = (PowerManager) wakeLock = wakeLockFactory.createWakeLock(PARTIAL_WAKE_LOCK);
appContext.getSystemService(POWER_SERVICE);
if (pm == null) throw new AssertionError();
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
getWakeLockTag(appContext), 1, MINUTES);
} }
@Override @Override

View File

@@ -13,10 +13,10 @@ import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.AndroidUtils;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -39,7 +39,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2; private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor; private final Executor ioExecutor;
private final TaskScheduler scheduler;
private final Context appContext; private final Context appContext;
private final NetworkManager networkManager; private final NetworkManager networkManager;
private final LocationUtils locationUtils; private final LocationUtils locationUtils;
@@ -49,10 +48,10 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private final ResourceProvider resourceProvider; private final ResourceProvider resourceProvider;
private final CircumventionProvider circumventionProvider; private final CircumventionProvider circumventionProvider;
private final BatteryManager batteryManager; private final BatteryManager batteryManager;
private final AndroidWakeLockFactory wakeLockFactory;
private final Clock clock; private final Clock clock;
public AndroidTorPluginFactory(Executor ioExecutor, public AndroidTorPluginFactory(Executor ioExecutor,
TaskScheduler scheduler,
Context appContext, Context appContext,
NetworkManager networkManager, NetworkManager networkManager,
LocationUtils locationUtils, LocationUtils locationUtils,
@@ -62,9 +61,9 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
ResourceProvider resourceProvider, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, CircumventionProvider circumventionProvider,
BatteryManager batteryManager, BatteryManager batteryManager,
AndroidWakeLockFactory wakeLockFactory,
Clock clock) { Clock clock) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext; this.appContext = appContext;
this.networkManager = networkManager; this.networkManager = networkManager;
this.locationUtils = locationUtils; this.locationUtils = locationUtils;
@@ -74,6 +73,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
this.resourceProvider = resourceProvider; this.resourceProvider = resourceProvider;
this.circumventionProvider = circumventionProvider; this.circumventionProvider = circumventionProvider;
this.batteryManager = batteryManager; this.batteryManager = batteryManager;
this.wakeLockFactory = wakeLockFactory;
this.clock = clock; this.clock = clock;
} }
@@ -117,11 +117,11 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl(); TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler, AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
appContext, networkManager, locationUtils, torSocketFactory, appContext, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, batteryManager, clock, resourceProvider, circumventionProvider, batteryManager,
backoff, torRendezvousCrypto, callback, architecture, wakeLockFactory, backoff, torRendezvousCrypto, callback,
MAX_LATENCY, MAX_IDLE_TIME); architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;
} }

View File

@@ -2,6 +2,7 @@ package org.briarproject.bramble.system;
import org.briarproject.bramble.api.event.EventExecutor; import org.briarproject.bramble.api.event.EventExecutor;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.SecureRandomProvider; import org.briarproject.bramble.api.system.SecureRandomProvider;
@@ -47,4 +48,10 @@ public class AndroidSystemModule {
ResourceProvider provideResourceProvider(AndroidResourceProvider provider) { ResourceProvider provideResourceProvider(AndroidResourceProvider provider) {
return provider; return provider;
} }
@Provides
AndroidWakeLockFactory provideWakeLockFactory(
AndroidWakeLockFactoryImpl wakeLockFactory) {
return wakeLockFactory;
}
} }

View File

@@ -0,0 +1,44 @@
package org.briarproject.bramble.system;
import android.app.Application;
import android.os.PowerManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.TaskScheduler;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static android.content.Context.POWER_SERVICE;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
import static org.briarproject.bramble.util.AndroidUtils.getWakeLockTag;
@Immutable
@NotNullByDefault
class AndroidWakeLockFactoryImpl implements AndroidWakeLockFactory {
private static final long LOCK_DURATION_MS = MINUTES.toMillis(1);
private final TaskScheduler scheduler;
private final Application app;
private final PowerManager powerManager;
@Inject
AndroidWakeLockFactoryImpl(TaskScheduler scheduler, Application app) {
this.scheduler = scheduler;
this.app = app;
powerManager = (PowerManager)
requireNonNull(app.getSystemService(POWER_SERVICE));
}
@Override
public AndroidWakeLock createWakeLock(int levelAndFlags) {
String tag = getWakeLockTag(app);
return new RenewableWakeLock(powerManager, scheduler, levelAndFlags,
tag, LOCK_DURATION_MS, MILLISECONDS);
}
}

View File

@@ -1,8 +1,9 @@
package org.briarproject.bramble.util; package org.briarproject.bramble.system;
import android.os.PowerManager; import android.os.PowerManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.api.system.TaskScheduler; import org.briarproject.bramble.api.system.TaskScheduler;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@@ -14,13 +15,14 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
public class RenewableWakeLock { class RenewableWakeLock implements AndroidWakeLock {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(RenewableWakeLock.class.getName()); getLogger(RenewableWakeLock.class.getName());
/** /**
* Automatically release the lock this many milliseconds after it's due * Automatically release the lock this many milliseconds after it's due
@@ -41,9 +43,8 @@ public class RenewableWakeLock {
@Nullable @Nullable
private Future<?> future; // Locking: lock private Future<?> future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager, RenewableWakeLock(PowerManager powerManager, TaskScheduler scheduler,
TaskScheduler scheduler, int levelAndFlags, String tag, int levelAndFlags, String tag, long duration, TimeUnit timeUnit) {
long duration, TimeUnit timeUnit) {
this.powerManager = powerManager; this.powerManager = powerManager;
this.scheduler = scheduler; this.scheduler = scheduler;
this.levelAndFlags = levelAndFlags; this.levelAndFlags = levelAndFlags;
@@ -52,6 +53,7 @@ public class RenewableWakeLock {
renewTask = this::renew; renewTask = this::renew;
} }
@Override
public void acquire() { public void acquire() {
if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag); if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag);
synchronized (lock) { synchronized (lock) {
@@ -82,6 +84,7 @@ public class RenewableWakeLock {
} }
} }
@Override
public void release() { public void release() {
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag); if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag);
synchronized (lock) { synchronized (lock) {

View File

@@ -0,0 +1,14 @@
package org.briarproject.bramble.plugin.bluetooth;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import java.io.IOException;
@NotNullByDefault
interface BluetoothConnectionFactory<S> {
DuplexTransportConnection wrapSocket(DuplexPlugin plugin, S socket)
throws IOException;
}

View File

@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection;
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementListeningEvent; import org.briarproject.bramble.api.keyagreement.event.KeyAgreementListeningEvent;
@@ -70,13 +69,13 @@ import static org.briarproject.bramble.util.StringUtils.macToString;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener { abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
private static final Logger LOG = private static final Logger LOG =
getLogger(BluetoothPlugin.class.getName()); getLogger(BluetoothPlugin.class.getName());
final BluetoothConnectionLimiter connectionLimiter; final BluetoothConnectionLimiter connectionLimiter;
final TimeoutMonitor timeoutMonitor; final BluetoothConnectionFactory<S> connectionFactory;
private final Executor ioExecutor; private final Executor ioExecutor;
private final SecureRandom secureRandom; private final SecureRandom secureRandom;
@@ -123,11 +122,15 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
abstract DuplexTransportConnection discoverAndConnect(String uuid); abstract DuplexTransportConnection discoverAndConnect(String uuid);
BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor, Executor ioExecutor, BluetoothConnectionFactory<S> connectionFactory,
SecureRandom secureRandom, Backoff backoff, Executor ioExecutor,
PluginCallback callback, int maxLatency, int maxIdleTime) { SecureRandom secureRandom,
Backoff backoff,
PluginCallback callback,
int maxLatency,
int maxIdleTime) {
this.connectionLimiter = connectionLimiter; this.connectionLimiter = connectionLimiter;
this.timeoutMonitor = timeoutMonitor; this.connectionFactory = connectionFactory;
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.secureRandom = secureRandom; this.secureRandom = secureRandom;
this.backoff = backoff; this.backoff = backoff;

View File

@@ -0,0 +1,34 @@
package org.briarproject.bramble.plugin.bluetooth;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import java.io.IOException;
import javax.annotation.concurrent.Immutable;
import javax.microedition.io.StreamConnection;
@Immutable
@NotNullByDefault
class JavaBluetoothConnectionFactory
implements BluetoothConnectionFactory<StreamConnection> {
private final BluetoothConnectionLimiter connectionLimiter;
private final TimeoutMonitor timeoutMonitor;
JavaBluetoothConnectionFactory(
BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor) {
this.connectionLimiter = connectionLimiter;
this.timeoutMonitor = timeoutMonitor;
}
@Override
public DuplexTransportConnection wrapSocket(DuplexPlugin plugin,
StreamConnection socket) throws IOException {
return new JavaBluetoothTransportConnection(plugin, connectionLimiter,
timeoutMonitor, socket);
}
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.plugin.bluetooth; package org.briarproject.bramble.plugin.bluetooth;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.Backoff;
@@ -26,7 +25,8 @@ import static org.briarproject.bramble.util.StringUtils.isValidMac;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> { class JavaBluetoothPlugin
extends BluetoothPlugin<StreamConnection, StreamConnectionNotifier> {
private static final Logger LOG = private static final Logger LOG =
getLogger(JavaBluetoothPlugin.class.getName()); getLogger(JavaBluetoothPlugin.class.getName());
@@ -35,10 +35,10 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
private volatile LocalDevice localDevice = null; private volatile LocalDevice localDevice = null;
JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager, JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager,
TimeoutMonitor timeoutMonitor, Executor ioExecutor, BluetoothConnectionFactory<StreamConnection> connectionFactory,
SecureRandom secureRandom, Backoff backoff, Executor ioExecutor, SecureRandom secureRandom, Backoff backoff,
PluginCallback callback, int maxLatency, int maxIdleTime) { PluginCallback callback, int maxLatency, int maxIdleTime) {
super(connectionManager, timeoutMonitor, ioExecutor, secureRandom, super(connectionManager, connectionFactory, ioExecutor, secureRandom,
backoff, callback, maxLatency, maxIdleTime); backoff, callback, maxLatency, maxIdleTime);
} }
@@ -96,7 +96,7 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
@Override @Override
DuplexTransportConnection acceptConnection(StreamConnectionNotifier ss) DuplexTransportConnection acceptConnection(StreamConnectionNotifier ss)
throws IOException { throws IOException {
return wrapSocket(ss.acceptAndOpen()); return connectionFactory.wrapSocket(this, ss.acceptAndOpen());
} }
@Override @Override
@@ -108,7 +108,8 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
DuplexTransportConnection connectTo(String address, String uuid) DuplexTransportConnection connectTo(String address, String uuid)
throws IOException { throws IOException {
String url = makeUrl(address, uuid); String url = makeUrl(address, uuid);
return wrapSocket((StreamConnection) Connector.open(url)); StreamConnection s = (StreamConnection) Connector.open(url);
return connectionFactory.wrapSocket(this, s);
} }
@Override @Override
@@ -120,10 +121,4 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
private String makeUrl(String address, String uuid) { private String makeUrl(String address, String uuid) {
return "btspp://" + address + ":" + uuid + ";name=RFCOMM"; return "btspp://" + address + ":" + uuid + ";name=RFCOMM";
} }
private DuplexTransportConnection wrapSocket(StreamConnection s)
throws IOException {
return new JavaBluetoothTransportConnection(this, connectionLimiter,
timeoutMonitor, s);
}
} }

View File

@@ -14,6 +14,7 @@ import java.security.SecureRandom;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.microedition.io.StreamConnection;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
@@ -57,10 +58,13 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
public DuplexPlugin createPlugin(PluginCallback callback) { public DuplexPlugin createPlugin(PluginCallback callback) {
BluetoothConnectionLimiter connectionLimiter = BluetoothConnectionLimiter connectionLimiter =
new BluetoothConnectionLimiterImpl(eventBus); new BluetoothConnectionLimiterImpl(eventBus);
BluetoothConnectionFactory<StreamConnection> connectionFactory =
new JavaBluetoothConnectionFactory(connectionLimiter,
timeoutMonitor);
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter, JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter,
timeoutMonitor, ioExecutor, secureRandom, backoff, callback, connectionFactory, ioExecutor, secureRandom, backoff, callback,
MAX_LATENCY, MAX_IDLE_TIME); MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;

View File

@@ -16,18 +16,18 @@ class JavaBluetoothTransportConnection
extends AbstractDuplexTransportConnection { extends AbstractDuplexTransportConnection {
private final BluetoothConnectionLimiter connectionLimiter; private final BluetoothConnectionLimiter connectionLimiter;
private final StreamConnection stream; private final StreamConnection socket;
private final InputStream in; private final InputStream in;
JavaBluetoothTransportConnection(Plugin plugin, JavaBluetoothTransportConnection(Plugin plugin,
BluetoothConnectionLimiter connectionLimiter, BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor, TimeoutMonitor timeoutMonitor,
StreamConnection stream) throws IOException { StreamConnection socket) throws IOException {
super(plugin); super(plugin);
this.connectionLimiter = connectionLimiter; this.connectionLimiter = connectionLimiter;
this.stream = stream; this.socket = socket;
in = timeoutMonitor.createTimeoutInputStream( in = timeoutMonitor.createTimeoutInputStream(
stream.openInputStream(), plugin.getMaxIdleTime() * 2); socket.openInputStream(), plugin.getMaxIdleTime() * 2);
} }
@Override @Override
@@ -37,13 +37,13 @@ class JavaBluetoothTransportConnection
@Override @Override
protected OutputStream getOutputStream() throws IOException { protected OutputStream getOutputStream() throws IOException {
return stream.openOutputStream(); return socket.openOutputStream();
} }
@Override @Override
protected void closeConnection(boolean exception) throws IOException { protected void closeConnection(boolean exception) throws IOException {
try { try {
stream.close(); socket.close();
} finally { } finally {
connectionLimiter.connectionClosed(this); connectionLimiter.connectionClosed(this);
} }

View File

@@ -28,10 +28,10 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
import org.briarproject.bramble.api.reporting.DevConfig; import org.briarproject.bramble.api.reporting.DevConfig;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory;
import org.briarproject.bramble.plugin.tor.AndroidTorPluginFactory; import org.briarproject.bramble.plugin.tor.AndroidTorPluginFactory;
@@ -124,7 +124,6 @@ public class AppModule {
@Provides @Provides
PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor, PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
TaskScheduler scheduler,
AndroidExecutor androidExecutor, AndroidExecutor androidExecutor,
SecureRandom random, SecureRandom random,
SocketFactory torSocketFactory, SocketFactory torSocketFactory,
@@ -136,16 +135,17 @@ public class AppModule {
ResourceProvider resourceProvider, ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider, CircumventionProvider circumventionProvider,
BatteryManager batteryManager, BatteryManager batteryManager,
AndroidWakeLockFactory wakeLockFactory,
Clock clock, Clock clock,
TimeoutMonitor timeoutMonitor) { TimeoutMonitor timeoutMonitor) {
Context appContext = app.getApplicationContext(); Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory( DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(
ioExecutor, scheduler, androidExecutor, appContext, random, ioExecutor, androidExecutor, wakeLockFactory, appContext,
eventBus, clock, timeoutMonitor, backoffFactory); random, eventBus, clock, timeoutMonitor, backoffFactory);
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor, DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
scheduler, appContext, networkManager, locationUtils, eventBus, appContext, networkManager, locationUtils, eventBus,
torSocketFactory, backoffFactory, resourceProvider, torSocketFactory, backoffFactory, resourceProvider,
circumventionProvider, batteryManager, clock); circumventionProvider, batteryManager, wakeLockFactory, clock);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
eventBus, backoffFactory, appContext); eventBus, backoffFactory, appContext);
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan); Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);