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

View File

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

View File

@@ -1,26 +1,20 @@
package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.PowerManager;
import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.util.RenewableWakeLock;
import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static android.content.Context.POWER_SERVICE;
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.util.AndroidUtils.getWakeLockTag;
import static org.briarproject.bramble.util.AndroidUtils.isValidBluetoothAddress;
@NotNullByDefault
@@ -28,26 +22,21 @@ class AndroidBluetoothTransportConnection
extends AbstractDuplexTransportConnection {
private final BluetoothConnectionLimiter connectionLimiter;
private final RenewableWakeLock wakeLock;
private final BluetoothSocket socket;
private final InputStream in;
private final AndroidWakeLock wakeLock;
AndroidBluetoothTransportConnection(Plugin plugin,
BluetoothConnectionLimiter connectionLimiter,
AndroidWakeLockFactory wakeLockFactory,
TimeoutMonitor timeoutMonitor,
Context appContext,
TaskScheduler scheduler,
BluetoothSocket socket) throws IOException {
super(plugin);
this.connectionLimiter = connectionLimiter;
this.socket = socket;
in = timeoutMonitor.createTimeoutInputStream(
socket.getInputStream(), plugin.getMaxIdleTime() * 2);
PowerManager powerManager = (PowerManager)
requireNonNull(appContext.getSystemService(POWER_SERVICE));
String tag = getWakeLockTag(appContext);
wakeLock = new RenewableWakeLock(powerManager, scheduler,
PARTIAL_WAKE_LOCK, tag, 1, MINUTES);
wakeLock = wakeLockFactory.createWakeLock(PARTIAL_WAKE_LOCK);
wakeLock.acquire();
String address = socket.getRemoteDevice().getAddress();
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.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.PowerManager;
import org.briarproject.bramble.api.battery.BatteryManager;
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.plugin.Backoff;
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.LocationUtils;
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.util.concurrent.Executor;
@@ -24,20 +23,16 @@ import java.util.concurrent.Executor;
import javax.net.SocketFactory;
import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.POWER_SERVICE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.briarproject.bramble.util.AndroidUtils.getWakeLockTag;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class AndroidTorPlugin extends TorPlugin {
private final Context appContext;
private final RenewableWakeLock wakeLock;
private final AndroidWakeLock wakeLock;
AndroidTorPlugin(Executor ioExecutor,
TaskScheduler scheduler,
Context appContext,
NetworkManager networkManager,
LocationUtils locationUtils,
@@ -46,6 +41,7 @@ class AndroidTorPlugin extends TorPlugin {
ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider,
BatteryManager batteryManager,
AndroidWakeLockFactory wakeLockFactory,
Backoff backoff,
TorRendezvousCrypto torRendezvousCrypto,
PluginCallback callback,
@@ -58,11 +54,7 @@ class AndroidTorPlugin extends TorPlugin {
maxLatency, maxIdleTime,
appContext.getDir("tor", MODE_PRIVATE));
this.appContext = appContext;
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
if (pm == null) throw new AssertionError();
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
getWakeLockTag(appContext), 1, MINUTES);
wakeLock = wakeLockFactory.createWakeLock(PARTIAL_WAKE_LOCK);
}
@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.duplex.DuplexPlugin;
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.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.util.AndroidUtils;
import java.util.concurrent.Executor;
@@ -39,7 +39,6 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final TaskScheduler scheduler;
private final Context appContext;
private final NetworkManager networkManager;
private final LocationUtils locationUtils;
@@ -49,10 +48,10 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
private final ResourceProvider resourceProvider;
private final CircumventionProvider circumventionProvider;
private final BatteryManager batteryManager;
private final AndroidWakeLockFactory wakeLockFactory;
private final Clock clock;
public AndroidTorPluginFactory(Executor ioExecutor,
TaskScheduler scheduler,
Context appContext,
NetworkManager networkManager,
LocationUtils locationUtils,
@@ -62,9 +61,9 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
ResourceProvider resourceProvider,
CircumventionProvider circumventionProvider,
BatteryManager batteryManager,
AndroidWakeLockFactory wakeLockFactory,
Clock clock) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext;
this.networkManager = networkManager;
this.locationUtils = locationUtils;
@@ -74,6 +73,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
this.resourceProvider = resourceProvider;
this.circumventionProvider = circumventionProvider;
this.batteryManager = batteryManager;
this.wakeLockFactory = wakeLockFactory;
this.clock = clock;
}
@@ -117,11 +117,11 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
appContext, networkManager, locationUtils, torSocketFactory,
clock, resourceProvider, circumventionProvider, batteryManager,
backoff, torRendezvousCrypto, callback, architecture,
MAX_LATENCY, MAX_IDLE_TIME);
wakeLockFactory, backoff, torRendezvousCrypto, callback,
architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(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.system.AndroidExecutor;
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.api.system.SecureRandomProvider;
@@ -47,4 +48,10 @@ public class AndroidSystemModule {
ResourceProvider provideResourceProvider(AndroidResourceProvider 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 org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.AndroidWakeLock;
import org.briarproject.bramble.api.system.TaskScheduler;
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.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@ThreadSafe
@NotNullByDefault
public class RenewableWakeLock {
class RenewableWakeLock implements AndroidWakeLock {
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
@@ -41,9 +43,8 @@ public class RenewableWakeLock {
@Nullable
private Future<?> future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager,
TaskScheduler scheduler, int levelAndFlags, String tag,
long duration, TimeUnit timeUnit) {
RenewableWakeLock(PowerManager powerManager, TaskScheduler scheduler,
int levelAndFlags, String tag, long duration, TimeUnit timeUnit) {
this.powerManager = powerManager;
this.scheduler = scheduler;
this.levelAndFlags = levelAndFlags;
@@ -52,6 +53,7 @@ public class RenewableWakeLock {
renewTask = this::renew;
}
@Override
public void acquire() {
if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag);
synchronized (lock) {
@@ -82,6 +84,7 @@ public class RenewableWakeLock {
}
}
@Override
public void release() {
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag);
synchronized (lock) {