mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Merge branch '1142-wakeful-tasks' into 'master'
Hold a wake lock while running scheduled tasks See merge request briar/briar!1268
This commit is contained in:
@@ -1,9 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.system;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public interface AndroidWakeLockFactory {
|
|
||||||
|
|
||||||
AndroidWakeLock createWakeLock();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.briarproject.bramble.api.system;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface AndroidWakeLockManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a wake lock with the given tag. The tag is only used for
|
||||||
|
* logging; the underlying OS wake lock will use its own tag.
|
||||||
|
*/
|
||||||
|
AndroidWakeLock createWakeLock(String tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the given task while holding a wake lock.
|
||||||
|
*/
|
||||||
|
void runWakefully(Runnable r, String tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the given task to the given executor while holding a wake lock.
|
||||||
|
* The lock is released when the task completes, or if an exception is
|
||||||
|
* thrown while submitting or running the task.
|
||||||
|
*/
|
||||||
|
void executeWakefully(Runnable r, Executor executor, String tag);
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.event.EventExecutor;
|
||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkStatus;
|
import org.briarproject.bramble.api.network.NetworkStatus;
|
||||||
@@ -17,6 +18,7 @@ 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.system.TaskScheduler;
|
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -51,6 +53,7 @@ class AndroidNetworkManager implements NetworkManager, Service {
|
|||||||
|
|
||||||
private final TaskScheduler scheduler;
|
private final TaskScheduler scheduler;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
private final Executor eventExecutor;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final AtomicReference<Future<?>> connectivityCheck =
|
private final AtomicReference<Future<?>> connectivityCheck =
|
||||||
new AtomicReference<>();
|
new AtomicReference<>();
|
||||||
@@ -60,9 +63,10 @@ class AndroidNetworkManager implements NetworkManager, Service {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AndroidNetworkManager(TaskScheduler scheduler, EventBus eventBus,
|
AndroidNetworkManager(TaskScheduler scheduler, EventBus eventBus,
|
||||||
Application app) {
|
@EventExecutor Executor eventExecutor, Application app) {
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
|
this.eventExecutor = eventExecutor;
|
||||||
this.appContext = app.getApplicationContext();
|
this.appContext = app.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +108,8 @@ class AndroidNetworkManager implements NetworkManager, Service {
|
|||||||
|
|
||||||
private void scheduleConnectionStatusUpdate(int delay, TimeUnit unit) {
|
private void scheduleConnectionStatusUpdate(int delay, TimeUnit unit) {
|
||||||
Future<?> newConnectivityCheck =
|
Future<?> newConnectivityCheck =
|
||||||
scheduler.schedule(this::updateConnectionStatus, delay, unit);
|
scheduler.schedule(this::updateConnectionStatus, eventExecutor,
|
||||||
|
delay, unit);
|
||||||
Future<?> oldConnectivityCheck =
|
Future<?> oldConnectivityCheck =
|
||||||
connectivityCheck.getAndSet(newConnectivityCheck);
|
connectivityCheck.getAndSet(newConnectivityCheck);
|
||||||
if (oldConnectivityCheck != null) oldConnectivityCheck.cancel(false);
|
if (oldConnectivityCheck != null) oldConnectivityCheck.cancel(false);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ 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.duplex.DuplexPlugin;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -15,15 +15,15 @@ class AndroidBluetoothConnectionFactory
|
|||||||
implements BluetoothConnectionFactory<BluetoothSocket> {
|
implements BluetoothConnectionFactory<BluetoothSocket> {
|
||||||
|
|
||||||
private final BluetoothConnectionLimiter connectionLimiter;
|
private final BluetoothConnectionLimiter connectionLimiter;
|
||||||
private final AndroidWakeLockFactory wakeLockFactory;
|
private final AndroidWakeLockManager wakeLockManager;
|
||||||
private final TimeoutMonitor timeoutMonitor;
|
private final TimeoutMonitor timeoutMonitor;
|
||||||
|
|
||||||
AndroidBluetoothConnectionFactory(
|
AndroidBluetoothConnectionFactory(
|
||||||
BluetoothConnectionLimiter connectionLimiter,
|
BluetoothConnectionLimiter connectionLimiter,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
TimeoutMonitor timeoutMonitor) {
|
TimeoutMonitor timeoutMonitor) {
|
||||||
this.connectionLimiter = connectionLimiter;
|
this.connectionLimiter = connectionLimiter;
|
||||||
this.wakeLockFactory = wakeLockFactory;
|
this.wakeLockManager = wakeLockManager;
|
||||||
this.timeoutMonitor = timeoutMonitor;
|
this.timeoutMonitor = timeoutMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +31,6 @@ class AndroidBluetoothConnectionFactory
|
|||||||
public DuplexTransportConnection wrapSocket(DuplexPlugin plugin,
|
public DuplexTransportConnection wrapSocket(DuplexPlugin plugin,
|
||||||
BluetoothSocket s) throws IOException {
|
BluetoothSocket s) throws IOException {
|
||||||
return new AndroidBluetoothTransportConnection(plugin,
|
return new AndroidBluetoothTransportConnection(plugin,
|
||||||
connectionLimiter, wakeLockFactory, timeoutMonitor, s);
|
connectionLimiter, wakeLockManager, timeoutMonitor, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ 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.AndroidWakeLockManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@@ -35,7 +35,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final AndroidExecutor androidExecutor;
|
private final AndroidExecutor androidExecutor;
|
||||||
private final AndroidWakeLockFactory wakeLockFactory;
|
private final AndroidWakeLockManager wakeLockManager;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final SecureRandom secureRandom;
|
private final SecureRandom secureRandom;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
@@ -45,7 +45,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
public AndroidBluetoothPluginFactory(Executor ioExecutor,
|
public AndroidBluetoothPluginFactory(Executor ioExecutor,
|
||||||
AndroidExecutor androidExecutor,
|
AndroidExecutor androidExecutor,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
Context appContext,
|
Context appContext,
|
||||||
SecureRandom secureRandom,
|
SecureRandom secureRandom,
|
||||||
EventBus eventBus,
|
EventBus eventBus,
|
||||||
@@ -54,7 +54,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
BackoffFactory backoffFactory) {
|
BackoffFactory backoffFactory) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.androidExecutor = androidExecutor;
|
this.androidExecutor = androidExecutor;
|
||||||
this.wakeLockFactory = wakeLockFactory;
|
this.wakeLockManager = wakeLockManager;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
this.secureRandom = secureRandom;
|
this.secureRandom = secureRandom;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
@@ -79,7 +79,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
|||||||
new BluetoothConnectionLimiterImpl(eventBus);
|
new BluetoothConnectionLimiterImpl(eventBus);
|
||||||
BluetoothConnectionFactory<BluetoothSocket> connectionFactory =
|
BluetoothConnectionFactory<BluetoothSocket> connectionFactory =
|
||||||
new AndroidBluetoothConnectionFactory(connectionLimiter,
|
new AndroidBluetoothConnectionFactory(connectionLimiter,
|
||||||
wakeLockFactory, timeoutMonitor);
|
wakeLockManager, 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(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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.AndroidWakeLock;
|
import org.briarproject.bramble.api.system.AndroidWakeLock;
|
||||||
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -27,7 +27,7 @@ class AndroidBluetoothTransportConnection
|
|||||||
|
|
||||||
AndroidBluetoothTransportConnection(Plugin plugin,
|
AndroidBluetoothTransportConnection(Plugin plugin,
|
||||||
BluetoothConnectionLimiter connectionLimiter,
|
BluetoothConnectionLimiter connectionLimiter,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
TimeoutMonitor timeoutMonitor,
|
TimeoutMonitor timeoutMonitor,
|
||||||
BluetoothSocket socket) throws IOException {
|
BluetoothSocket socket) throws IOException {
|
||||||
super(plugin);
|
super(plugin);
|
||||||
@@ -35,7 +35,7 @@ class AndroidBluetoothTransportConnection
|
|||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
in = timeoutMonitor.createTimeoutInputStream(
|
in = timeoutMonitor.createTimeoutInputStream(
|
||||||
socket.getInputStream(), plugin.getMaxIdleTime() * 2);
|
socket.getInputStream(), plugin.getMaxIdleTime() * 2);
|
||||||
wakeLock = wakeLockFactory.createWakeLock();
|
wakeLock = wakeLockManager.createWakeLock("BluetoothConnection");
|
||||||
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);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ 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.AndroidWakeLock;
|
||||||
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
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;
|
||||||
@@ -40,7 +40,7 @@ class AndroidTorPlugin extends TorPlugin {
|
|||||||
ResourceProvider resourceProvider,
|
ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager,
|
BatteryManager batteryManager,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
Backoff backoff,
|
Backoff backoff,
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
TorRendezvousCrypto torRendezvousCrypto,
|
||||||
PluginCallback callback,
|
PluginCallback callback,
|
||||||
@@ -53,7 +53,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;
|
||||||
wakeLock = wakeLockFactory.createWakeLock();
|
wakeLock = wakeLockManager.createWakeLock("TorPlugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ 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.AndroidWakeLockManager;
|
||||||
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;
|
||||||
@@ -48,7 +48,7 @@ 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 AndroidWakeLockManager wakeLockManager;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
public AndroidTorPluginFactory(Executor ioExecutor,
|
public AndroidTorPluginFactory(Executor ioExecutor,
|
||||||
@@ -61,7 +61,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
ResourceProvider resourceProvider,
|
ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager,
|
BatteryManager batteryManager,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
@@ -73,7 +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.wakeLockManager = wakeLockManager;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
|
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
|
||||||
appContext, networkManager, locationUtils, torSocketFactory,
|
appContext, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, batteryManager,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
wakeLockFactory, backoff, torRendezvousCrypto, callback,
|
wakeLockManager, backoff, torRendezvousCrypto, callback,
|
||||||
architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
package org.briarproject.bramble.system;
|
package org.briarproject.bramble.system;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.event.EventExecutor;
|
import org.briarproject.bramble.api.event.EventExecutor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
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.AndroidWakeLockManager;
|
||||||
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;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
@@ -17,6 +21,23 @@ import dagger.Provides;
|
|||||||
@Module
|
@Module
|
||||||
public class AndroidSystemModule {
|
public class AndroidSystemModule {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
|
|
||||||
|
public AndroidSystemModule() {
|
||||||
|
// Discard tasks that are submitted during shutdown
|
||||||
|
RejectedExecutionHandler policy =
|
||||||
|
new ScheduledThreadPoolExecutor.DiscardPolicy();
|
||||||
|
scheduledExecutorService = new ScheduledThreadPoolExecutor(1, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ScheduledExecutorService provideScheduledExecutorService(
|
||||||
|
LifecycleManager lifecycleManager) {
|
||||||
|
lifecycleManager.registerForShutdown(scheduledExecutorService);
|
||||||
|
return scheduledExecutorService;
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
SecureRandomProvider provideSecureRandomProvider(
|
SecureRandomProvider provideSecureRandomProvider(
|
||||||
@@ -51,8 +72,8 @@ public class AndroidSystemModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
AndroidWakeLockFactory provideWakeLockFactory(
|
AndroidWakeLockManager provideWakeLockManager(
|
||||||
AndroidWakeLockFactoryImpl wakeLockFactory) {
|
AndroidWakeLockManagerImpl wakeLockManager) {
|
||||||
return wakeLockFactory;
|
return wakeLockManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ import android.os.SystemClock;
|
|||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.AlarmListener;
|
import org.briarproject.bramble.api.system.AlarmListener;
|
||||||
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.FutureTask;
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
@@ -50,6 +52,7 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
|
|||||||
private static final long ALARM_MS = INTERVAL_FIFTEEN_MINUTES;
|
private static final long ALARM_MS = INTERVAL_FIFTEEN_MINUTES;
|
||||||
|
|
||||||
private final Application app;
|
private final Application app;
|
||||||
|
private final AndroidWakeLockManager wakeLockManager;
|
||||||
private final ScheduledExecutorService scheduledExecutorService;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
private final AlarmManager alarmManager;
|
private final AlarmManager alarmManager;
|
||||||
|
|
||||||
@@ -58,8 +61,10 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
|
|||||||
private final Queue<ScheduledTask> tasks = new PriorityQueue<>();
|
private final Queue<ScheduledTask> tasks = new PriorityQueue<>();
|
||||||
|
|
||||||
AndroidTaskScheduler(Application app,
|
AndroidTaskScheduler(Application app,
|
||||||
|
AndroidWakeLockManager wakeLockManager,
|
||||||
ScheduledExecutorService scheduledExecutorService) {
|
ScheduledExecutorService scheduledExecutorService) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
this.wakeLockManager = wakeLockManager;
|
||||||
this.scheduledExecutorService = scheduledExecutorService;
|
this.scheduledExecutorService = scheduledExecutorService;
|
||||||
alarmManager = (AlarmManager)
|
alarmManager = (AlarmManager)
|
||||||
requireNonNull(app.getSystemService(ALARM_SERVICE));
|
requireNonNull(app.getSystemService(ALARM_SERVICE));
|
||||||
@@ -67,8 +72,9 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startService() {
|
public void startService() {
|
||||||
scheduledExecutorService.scheduleAtFixedRate(this::runDueTasks,
|
scheduledExecutorService.scheduleAtFixedRate(
|
||||||
TICK_MS, TICK_MS, MILLISECONDS);
|
() -> wakeLockManager.runWakefully(this::runDueTasks,
|
||||||
|
"TaskTicker"), TICK_MS, TICK_MS, MILLISECONDS);
|
||||||
scheduleAlarm();
|
scheduleAlarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +84,13 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<?> schedule(Runnable task, long delay, TimeUnit unit) {
|
public Future<?> schedule(Runnable task, Executor executor, long delay,
|
||||||
|
TimeUnit unit) {
|
||||||
long now = SystemClock.elapsedRealtime();
|
long now = SystemClock.elapsedRealtime();
|
||||||
long dueMillis = now + MILLISECONDS.convert(delay, unit);
|
long dueMillis = now + MILLISECONDS.convert(delay, unit);
|
||||||
ScheduledTask s = new ScheduledTask(task, dueMillis);
|
Runnable wakeful = () ->
|
||||||
|
wakeLockManager.executeWakefully(task, executor, "TaskHandoff");
|
||||||
|
ScheduledTask s = new ScheduledTask(wakeful, dueMillis);
|
||||||
if (dueMillis <= now) {
|
if (dueMillis <= now) {
|
||||||
scheduledExecutorService.execute(s);
|
scheduledExecutorService.execute(s);
|
||||||
} else {
|
} else {
|
||||||
@@ -93,27 +102,29 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<?> scheduleWithFixedDelay(Runnable task, long delay,
|
public Future<?> scheduleWithFixedDelay(Runnable task, Executor executor,
|
||||||
long interval, TimeUnit unit) {
|
long delay, long interval, TimeUnit unit) {
|
||||||
Runnable wrapped = () -> {
|
Runnable wrapped = () -> {
|
||||||
task.run();
|
task.run();
|
||||||
scheduleWithFixedDelay(task, interval, interval, unit);
|
scheduleWithFixedDelay(task, executor, interval, interval, unit);
|
||||||
};
|
};
|
||||||
return schedule(wrapped, delay, unit);
|
return schedule(wrapped, executor, delay, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAlarm(Intent intent) {
|
public void onAlarm(Intent intent) {
|
||||||
int extraPid = intent.getIntExtra(EXTRA_PID, -1);
|
wakeLockManager.runWakefully(() -> {
|
||||||
int currentPid = Process.myPid();
|
int extraPid = intent.getIntExtra(EXTRA_PID, -1);
|
||||||
if (extraPid == currentPid) {
|
int currentPid = Process.myPid();
|
||||||
LOG.info("Alarm");
|
if (extraPid == currentPid) {
|
||||||
rescheduleAlarm();
|
LOG.info("Alarm");
|
||||||
runDueTasks();
|
rescheduleAlarm();
|
||||||
} else if (LOG.isLoggable(INFO)) {
|
runDueTasks();
|
||||||
LOG.info("Ignoring alarm with PID " + extraPid
|
} else if (LOG.isLoggable(INFO)) {
|
||||||
+ ", current PID is " + currentPid);
|
LOG.info("Ignoring alarm with PID " + extraPid
|
||||||
}
|
+ ", current PID is " + currentPid);
|
||||||
|
}
|
||||||
|
}, "TaskAlarm");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runDueTasks() {
|
private void runDueTasks() {
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import android.app.Application;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.system.AlarmListener;
|
import org.briarproject.bramble.api.system.AlarmListener;
|
||||||
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||||
|
|
||||||
import java.util.concurrent.RejectedExecutionHandler;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -24,22 +23,14 @@ public class AndroidTaskSchedulerModule {
|
|||||||
AndroidTaskScheduler scheduler;
|
AndroidTaskScheduler scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ScheduledExecutorService scheduledExecutorService;
|
|
||||||
|
|
||||||
public AndroidTaskSchedulerModule() {
|
|
||||||
// Discard tasks that are submitted during shutdown
|
|
||||||
RejectedExecutionHandler policy =
|
|
||||||
new ScheduledThreadPoolExecutor.DiscardPolicy();
|
|
||||||
scheduledExecutorService = new ScheduledThreadPoolExecutor(1, policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
AndroidTaskScheduler provideAndroidTaskScheduler(
|
AndroidTaskScheduler provideAndroidTaskScheduler(
|
||||||
LifecycleManager lifecycleManager, Application app) {
|
LifecycleManager lifecycleManager, Application app,
|
||||||
lifecycleManager.registerForShutdown(scheduledExecutorService);
|
AndroidWakeLockManager wakeLockManager,
|
||||||
AndroidTaskScheduler scheduler =
|
ScheduledExecutorService scheduledExecutorService) {
|
||||||
new AndroidTaskScheduler(app, scheduledExecutorService);
|
AndroidTaskScheduler scheduler = new AndroidTaskScheduler(app,
|
||||||
|
wakeLockManager, scheduledExecutorService);
|
||||||
lifecycleManager.registerService(scheduler);
|
lifecycleManager.registerService(scheduler);
|
||||||
return scheduler;
|
return scheduler;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,15 @@ package org.briarproject.bramble.system;
|
|||||||
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.AndroidWakeLock;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.FINE;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around a {@link SharedWakeLock} that provides the more convenient
|
* A wrapper around a {@link SharedWakeLock} that provides the more convenient
|
||||||
* semantics of {@link AndroidWakeLock} (i.e. calls to acquire() and release()
|
* semantics of {@link AndroidWakeLock} (i.e. calls to acquire() and release()
|
||||||
@@ -15,19 +21,34 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidWakeLockImpl implements AndroidWakeLock {
|
class AndroidWakeLockImpl implements AndroidWakeLock {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(AndroidWakeLockImpl.class.getName());
|
||||||
|
|
||||||
|
private static final AtomicInteger INSTANCE_ID = new AtomicInteger(0);
|
||||||
|
|
||||||
private final SharedWakeLock sharedWakeLock;
|
private final SharedWakeLock sharedWakeLock;
|
||||||
|
private final String tag;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private boolean held = false;
|
private boolean held = false;
|
||||||
|
|
||||||
AndroidWakeLockImpl(SharedWakeLock sharedWakeLock) {
|
AndroidWakeLockImpl(SharedWakeLock sharedWakeLock, String tag) {
|
||||||
this.sharedWakeLock = sharedWakeLock;
|
this.sharedWakeLock = sharedWakeLock;
|
||||||
|
this.tag = tag + "_" + INSTANCE_ID.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acquire() {
|
public void acquire() {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (!held) {
|
if (held) {
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine(tag + " already acquired");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine(tag + " acquiring shared wake lock");
|
||||||
|
}
|
||||||
held = true;
|
held = true;
|
||||||
sharedWakeLock.acquire();
|
sharedWakeLock.acquire();
|
||||||
}
|
}
|
||||||
@@ -38,8 +59,15 @@ class AndroidWakeLockImpl implements AndroidWakeLock {
|
|||||||
public void release() {
|
public void release() {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (held) {
|
if (held) {
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine(tag + " releasing shared wake lock");
|
||||||
|
}
|
||||||
held = false;
|
held = false;
|
||||||
sharedWakeLock.release();
|
sharedWakeLock.release();
|
||||||
|
} else {
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine(tag + " already released");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ 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.AndroidWakeLock;
|
||||||
import org.briarproject.bramble.api.system.AndroidWakeLockFactory;
|
import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidWakeLockFactoryImpl implements AndroidWakeLockFactory {
|
class AndroidWakeLockManagerImpl implements AndroidWakeLockManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How often to replace the wake lock.
|
* How often to replace the wake lock.
|
||||||
@@ -36,17 +38,52 @@ class AndroidWakeLockFactoryImpl implements AndroidWakeLockFactory {
|
|||||||
private final SharedWakeLock sharedWakeLock;
|
private final SharedWakeLock sharedWakeLock;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AndroidWakeLockFactoryImpl(TaskScheduler scheduler, Application app) {
|
AndroidWakeLockManagerImpl(Application app,
|
||||||
|
ScheduledExecutorService scheduledExecutorService) {
|
||||||
PowerManager powerManager = (PowerManager)
|
PowerManager powerManager = (PowerManager)
|
||||||
requireNonNull(app.getSystemService(POWER_SERVICE));
|
requireNonNull(app.getSystemService(POWER_SERVICE));
|
||||||
String tag = getWakeLockTag(app);
|
String tag = getWakeLockTag(app);
|
||||||
sharedWakeLock = new RenewableWakeLock(powerManager, scheduler,
|
sharedWakeLock = new RenewableWakeLock(powerManager,
|
||||||
PARTIAL_WAKE_LOCK, tag, LOCK_DURATION_MS, SAFETY_MARGIN_MS);
|
scheduledExecutorService, PARTIAL_WAKE_LOCK, tag,
|
||||||
|
LOCK_DURATION_MS, SAFETY_MARGIN_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AndroidWakeLock createWakeLock() {
|
public AndroidWakeLock createWakeLock(String tag) {
|
||||||
return new AndroidWakeLockImpl(sharedWakeLock);
|
return new AndroidWakeLockImpl(sharedWakeLock, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWakefully(Runnable r, String tag) {
|
||||||
|
AndroidWakeLock wakeLock = createWakeLock(tag);
|
||||||
|
wakeLock.acquire();
|
||||||
|
try {
|
||||||
|
r.run();
|
||||||
|
} finally {
|
||||||
|
wakeLock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void executeWakefully(Runnable r, Executor executor, String tag) {
|
||||||
|
AndroidWakeLock wakeLock = createWakeLock(tag);
|
||||||
|
wakeLock.acquire();
|
||||||
|
try {
|
||||||
|
executor.execute(() -> {
|
||||||
|
try {
|
||||||
|
r.run();
|
||||||
|
} finally {
|
||||||
|
// Release the wake lock if the task throws an exception
|
||||||
|
wakeLock.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Release the wake lock if the executor throws an exception when
|
||||||
|
// we submit the task (in which case the release() call above won't
|
||||||
|
// happen)
|
||||||
|
wakeLock.release();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getWakeLockTag(Context ctx) {
|
private String getWakeLockTag(Context ctx) {
|
||||||
@@ -4,9 +4,9 @@ import android.os.PowerManager;
|
|||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -14,6 +14,7 @@ import javax.annotation.concurrent.GuardedBy;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
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.FINE;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
@@ -27,7 +28,7 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
getLogger(RenewableWakeLock.class.getName());
|
getLogger(RenewableWakeLock.class.getName());
|
||||||
|
|
||||||
private final PowerManager powerManager;
|
private final PowerManager powerManager;
|
||||||
private final TaskScheduler scheduler;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
private final int levelAndFlags;
|
private final int levelAndFlags;
|
||||||
private final String tag;
|
private final String tag;
|
||||||
private final long durationMs, safetyMarginMs;
|
private final long durationMs, safetyMarginMs;
|
||||||
@@ -44,11 +45,14 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private long acquired = 0;
|
private long acquired = 0;
|
||||||
|
|
||||||
RenewableWakeLock(PowerManager powerManager, TaskScheduler scheduler,
|
RenewableWakeLock(PowerManager powerManager,
|
||||||
int levelAndFlags, String tag, long durationMs,
|
ScheduledExecutorService scheduledExecutorService,
|
||||||
|
int levelAndFlags,
|
||||||
|
String tag,
|
||||||
|
long durationMs,
|
||||||
long safetyMarginMs) {
|
long safetyMarginMs) {
|
||||||
this.powerManager = powerManager;
|
this.powerManager = powerManager;
|
||||||
this.scheduler = scheduler;
|
this.scheduledExecutorService = scheduledExecutorService;
|
||||||
this.levelAndFlags = levelAndFlags;
|
this.levelAndFlags = levelAndFlags;
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.durationMs = durationMs;
|
this.durationMs = durationMs;
|
||||||
@@ -69,9 +73,11 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
// power management apps
|
// power management apps
|
||||||
wakeLock.setReferenceCounted(false);
|
wakeLock.setReferenceCounted(false);
|
||||||
wakeLock.acquire(durationMs + safetyMarginMs);
|
wakeLock.acquire(durationMs + safetyMarginMs);
|
||||||
future = scheduler.schedule(this::renew, durationMs,
|
future = scheduledExecutorService.schedule(this::renew,
|
||||||
MILLISECONDS);
|
durationMs, MILLISECONDS);
|
||||||
acquired = android.os.SystemClock.elapsedRealtime();
|
acquired = android.os.SystemClock.elapsedRealtime();
|
||||||
|
} else if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine("Wake lock " + tag + " has " + refCount + " holders");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,6 +89,9 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
LOG.info("Already released");
|
LOG.info("Already released");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine("Wake lock " + tag + " has " + refCount + " holders");
|
||||||
|
}
|
||||||
long now = android.os.SystemClock.elapsedRealtime();
|
long now = android.os.SystemClock.elapsedRealtime();
|
||||||
long expiry = acquired + durationMs + safetyMarginMs;
|
long expiry = acquired + durationMs + safetyMarginMs;
|
||||||
if (now > expiry && LOG.isLoggable(WARNING)) {
|
if (now > expiry && LOG.isLoggable(WARNING)) {
|
||||||
@@ -93,7 +102,8 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
wakeLock.setReferenceCounted(false);
|
wakeLock.setReferenceCounted(false);
|
||||||
wakeLock.acquire(durationMs + safetyMarginMs);
|
wakeLock.acquire(durationMs + safetyMarginMs);
|
||||||
oldWakeLock.release();
|
oldWakeLock.release();
|
||||||
future = scheduler.schedule(this::renew, durationMs, MILLISECONDS);
|
future = scheduledExecutorService.schedule(this::renew, durationMs,
|
||||||
|
MILLISECONDS);
|
||||||
acquired = now;
|
acquired = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,6 +121,8 @@ class RenewableWakeLock implements SharedWakeLock {
|
|||||||
requireNonNull(wakeLock).release();
|
requireNonNull(wakeLock).release();
|
||||||
wakeLock = null;
|
wakeLock = null;
|
||||||
acquired = 0;
|
acquired = 0;
|
||||||
|
} else if (LOG.isLoggable(FINE)) {
|
||||||
|
LOG.fine("Wake lock " + tag + " has " + refCount + " holders");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,27 @@ package org.briarproject.bramble.api.system;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service that can be used to schedule the execution of tasks.
|
* A service that can be used to schedule the execution of tasks.
|
||||||
* <p>
|
|
||||||
* The service should only be used for running tasks on other executors
|
|
||||||
* at scheduled times. No significant work should be run by the service itself.
|
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface TaskScheduler {
|
public interface TaskScheduler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link ScheduledExecutorService#schedule(Runnable, long, TimeUnit)}.
|
* Submits the given task to the given executor after the given delay.
|
||||||
*/
|
*/
|
||||||
Future<?> schedule(Runnable task, long delay, TimeUnit unit);
|
Future<?> schedule(Runnable task, Executor executor, long delay,
|
||||||
|
TimeUnit unit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}.
|
* Submits the given task to the given executor after the given delay,
|
||||||
|
* and then repeatedly with the given interval between executions
|
||||||
|
* (measured from the end of one execution to the beginning of the next).
|
||||||
*/
|
*/
|
||||||
Future<?> scheduleWithFixedDelay(Runnable task, long delay,
|
Future<?> scheduleWithFixedDelay(Runnable task, Executor executor,
|
||||||
long interval, TimeUnit unit);
|
long delay, long interval, TimeUnit unit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ class TimeoutMonitorImpl implements TimeoutMonitor {
|
|||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (streams.isEmpty()) {
|
if (streams.isEmpty()) {
|
||||||
task = scheduler.scheduleWithFixedDelay(this::checkTimeouts,
|
task = scheduler.scheduleWithFixedDelay(this::checkTimeouts,
|
||||||
CHECK_INTERVAL_MS, CHECK_INTERVAL_MS, MILLISECONDS);
|
ioExecutor, CHECK_INTERVAL_MS, CHECK_INTERVAL_MS,
|
||||||
|
MILLISECONDS);
|
||||||
}
|
}
|
||||||
streams.add(stream);
|
streams.add(stream);
|
||||||
}
|
}
|
||||||
@@ -73,23 +74,21 @@ class TimeoutMonitorImpl implements TimeoutMonitor {
|
|||||||
if (toCancel != null) toCancel.cancel(false);
|
if (toCancel != null) toCancel.cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scheduler
|
@IoExecutor
|
||||||
private void checkTimeouts() {
|
private void checkTimeouts() {
|
||||||
ioExecutor.execute(() -> {
|
List<TimeoutInputStream> snapshot;
|
||||||
List<TimeoutInputStream> snapshot;
|
synchronized (lock) {
|
||||||
synchronized (lock) {
|
snapshot = new ArrayList<>(streams);
|
||||||
snapshot = new ArrayList<>(streams);
|
}
|
||||||
}
|
for (TimeoutInputStream stream : snapshot) {
|
||||||
for (TimeoutInputStream stream : snapshot) {
|
if (stream.hasTimedOut()) {
|
||||||
if (stream.hasTimedOut()) {
|
LOG.info("Input stream has timed out");
|
||||||
LOG.info("Input stream has timed out");
|
try {
|
||||||
try {
|
stream.close();
|
||||||
stream.close();
|
} catch (IOException e) {
|
||||||
} catch (IOException e) {
|
logException(LOG, INFO, e);
|
||||||
logException(LOG, INFO, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class PollerImpl implements Poller, EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make this wakeful
|
||||||
private void connectToContact(ContactId c) {
|
private void connectToContact(ContactId c) {
|
||||||
for (SimplexPlugin s : pluginManager.getSimplexPlugins())
|
for (SimplexPlugin s : pluginManager.getSimplexPlugins())
|
||||||
if (s.shouldPoll()) connectToContact(c, s);
|
if (s.shouldPoll()) connectToContact(c, s);
|
||||||
@@ -189,8 +190,8 @@ class PollerImpl implements Poller, EventListener {
|
|||||||
// it will abort safely when it finds it's been replaced
|
// it will abort safely when it finds it's been replaced
|
||||||
if (scheduled != null) scheduled.future.cancel(false);
|
if (scheduled != null) scheduled.future.cancel(false);
|
||||||
PollTask task = new PollTask(p, due, randomiseNext);
|
PollTask task = new PollTask(p, due, randomiseNext);
|
||||||
Future<?> future = scheduler.schedule(() ->
|
Future<?> future = scheduler.schedule(task, ioExecutor, delay,
|
||||||
ioExecutor.execute(task), delay, MILLISECONDS);
|
MILLISECONDS);
|
||||||
tasks.put(t, new ScheduledPollTask(task, future));
|
tasks.put(t, new ScheduledPollTask(task, future));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -233,9 +234,9 @@ class PollerImpl implements Poller, EventListener {
|
|||||||
private class ScheduledPollTask {
|
private class ScheduledPollTask {
|
||||||
|
|
||||||
private final PollTask task;
|
private final PollTask task;
|
||||||
private final Future future;
|
private final Future<?> future;
|
||||||
|
|
||||||
private ScheduledPollTask(PollTask task, Future future) {
|
private ScheduledPollTask(PollTask task, Future<?> future) {
|
||||||
this.task = task;
|
this.task = task;
|
||||||
this.future = future;
|
this.future = future;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
throw new ServiceException(e);
|
throw new ServiceException(e);
|
||||||
}
|
}
|
||||||
scheduler.scheduleWithFixedDelay(this::poll, POLLING_INTERVAL_MS,
|
scheduler.scheduleWithFixedDelay(this::poll, worker,
|
||||||
POLLING_INTERVAL_MS, MILLISECONDS);
|
POLLING_INTERVAL_MS, POLLING_INTERVAL_MS, MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventExecutor
|
@EventExecutor
|
||||||
@@ -204,12 +204,10 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
|||||||
return plugin.createRendezvousEndpoint(k, cs.alice, h);
|
return plugin.createRendezvousEndpoint(k, cs.alice, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scheduler
|
// Worker
|
||||||
private void poll() {
|
private void poll() {
|
||||||
worker.execute(() -> {
|
removeExpiredPendingContacts();
|
||||||
removeExpiredPendingContacts();
|
for (PluginState ps : pluginStates.values()) poll(ps);
|
||||||
for (PluginState ps : pluginStates.values()) poll(ps);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Worker
|
// Worker
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.system;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -10,27 +11,30 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link TaskScheduler} that delegates all calls to a
|
* A {@link TaskScheduler} that uses a {@link ScheduledExecutorService}.
|
||||||
* {@link ScheduledExecutorService}.
|
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class TaskSchedulerImpl implements TaskScheduler {
|
class TaskSchedulerImpl implements TaskScheduler {
|
||||||
|
|
||||||
private final ScheduledExecutorService delegate;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
|
|
||||||
TaskSchedulerImpl(ScheduledExecutorService delegate) {
|
TaskSchedulerImpl(ScheduledExecutorService scheduledExecutorService) {
|
||||||
this.delegate = delegate;
|
this.scheduledExecutorService = scheduledExecutorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<?> schedule(Runnable task, long delay, TimeUnit unit) {
|
public Future<?> schedule(Runnable task, Executor executor, long delay,
|
||||||
return delegate.schedule(task, delay, unit);
|
TimeUnit unit) {
|
||||||
|
Runnable execute = () -> executor.execute(task);
|
||||||
|
return scheduledExecutorService.schedule(execute, delay, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<?> scheduleWithFixedDelay(Runnable task, long delay,
|
public Future<?> scheduleWithFixedDelay(Runnable task, Executor executor,
|
||||||
long interval, TimeUnit unit) {
|
long delay, long interval, TimeUnit unit) {
|
||||||
return delegate.scheduleWithFixedDelay(task, delay, interval, unit);
|
Runnable execute = () -> executor.execute(task);
|
||||||
|
return scheduledExecutorService.scheduleWithFixedDelay(execute, delay,
|
||||||
|
interval, unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.contact.PendingContactId;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.crypto.TransportCrypto;
|
import org.briarproject.bramble.api.crypto.TransportCrypto;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -198,17 +199,16 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
|||||||
|
|
||||||
private void scheduleKeyUpdate(long now) {
|
private void scheduleKeyUpdate(long now) {
|
||||||
long delay = timePeriodLength - now % timePeriodLength;
|
long delay = timePeriodLength - now % timePeriodLength;
|
||||||
scheduler.schedule(this::updateKeys, delay, MILLISECONDS);
|
scheduler.schedule(this::updateKeys, dbExecutor, delay, MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
private void updateKeys() {
|
private void updateKeys() {
|
||||||
dbExecutor.execute(() -> {
|
try {
|
||||||
try {
|
db.transaction(false, this::updateKeys);
|
||||||
db.transaction(false, this::updateKeys);
|
} catch (DbException e) {
|
||||||
} catch (DbException e) {
|
logException(LOG, WARNING, e);
|
||||||
logException(LOG, WARNING, e);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
with(ioExecutor), with((long) pollingInterval),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@@ -262,7 +263,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
with(ioExecutor), with((long) pollingInterval),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
// Second event
|
// Second event
|
||||||
// Get the plugin
|
// Get the plugin
|
||||||
@@ -304,7 +306,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
with(ioExecutor), with((long) pollingInterval),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
// Second event
|
// Second event
|
||||||
// Get the plugin
|
// Get the plugin
|
||||||
@@ -320,7 +323,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(now + 1));
|
will(returnValue(now + 1));
|
||||||
oneOf(future).cancel(false);
|
oneOf(future).cancel(false);
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) pollingInterval - 2), with(MILLISECONDS));
|
with(ioExecutor), with((long) pollingInterval - 2),
|
||||||
|
with(MILLISECONDS));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId,
|
||||||
@@ -345,8 +349,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
// Schedule a polling task immediately
|
// Schedule a polling task immediately
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)), with(0L),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(MILLISECONDS));
|
with(ioExecutor), with(0L), with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
will(new RunAction());
|
will(new RunAction());
|
||||||
// Running the polling task schedules the next polling task
|
// Running the polling task schedules the next polling task
|
||||||
@@ -357,7 +361,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) (pollingInterval * 0.5)), with(MILLISECONDS));
|
with(ioExecutor), with((long) (pollingInterval * 0.5)),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
// Get the transport properties and connected contacts
|
// Get the transport properties and connected contacts
|
||||||
oneOf(transportPropertyManager).getRemoteProperties(transportId);
|
oneOf(transportPropertyManager).getRemoteProperties(transportId);
|
||||||
@@ -388,8 +393,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
// Schedule a polling task immediately
|
// Schedule a polling task immediately
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)), with(0L),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(MILLISECONDS));
|
with(ioExecutor), with(0L), with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
will(new RunAction());
|
will(new RunAction());
|
||||||
// Running the polling task schedules the next polling task
|
// Running the polling task schedules the next polling task
|
||||||
@@ -400,7 +405,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) (pollingInterval * 0.5)), with(MILLISECONDS));
|
with(ioExecutor), with((long) (pollingInterval * 0.5)),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
// Get the transport properties and connected contacts
|
// Get the transport properties and connected contacts
|
||||||
oneOf(transportPropertyManager).getRemoteProperties(transportId);
|
oneOf(transportPropertyManager).getRemoteProperties(transportId);
|
||||||
@@ -429,8 +435,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
// Schedule a polling task immediately
|
// Schedule a polling task immediately
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)), with(0L),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(MILLISECONDS));
|
with(ioExecutor), with(0L), with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
// The plugin is deactivated before the task runs - cancel the task
|
// The plugin is deactivated before the task runs - cancel the task
|
||||||
oneOf(future).cancel(false);
|
oneOf(future).cancel(false);
|
||||||
@@ -454,7 +460,8 @@ public class PollerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(now));
|
will(returnValue(now));
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with((long) pollingInterval), with(MILLISECONDS));
|
with(ioExecutor), with((long) pollingInterval),
|
||||||
|
with(MILLISECONDS));
|
||||||
will(returnValue(future));
|
will(returnValue(future));
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
e.getPendingContactState() == OFFLINE)));
|
e.getPendingContactState() == OFFLINE)));
|
||||||
// Capture the poll task
|
// Capture the poll task
|
||||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||||
with(MILLISECONDS));
|
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||||
0));
|
0));
|
||||||
}});
|
}});
|
||||||
@@ -159,8 +159,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
e.getPendingContactState() == FAILED)));
|
e.getPendingContactState() == FAILED)));
|
||||||
// Schedule the poll task
|
// Schedule the poll task
|
||||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||||
with(MILLISECONDS));
|
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
rendezvousPoller.startService();
|
rendezvousPoller.startService();
|
||||||
@@ -468,8 +468,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
// Capture the poll task
|
// Capture the poll task
|
||||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||||
with(MILLISECONDS));
|
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||||
0));
|
0));
|
||||||
}});
|
}});
|
||||||
@@ -545,8 +545,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
|||||||
e.getPendingContactState() == OFFLINE)));
|
e.getPendingContactState() == OFFLINE)));
|
||||||
// Capture the poll task
|
// Capture the poll task
|
||||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||||
with(POLLING_INTERVAL_MS), with(POLLING_INTERVAL_MS),
|
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||||
with(MILLISECONDS));
|
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||||
0));
|
0));
|
||||||
}});
|
}});
|
||||||
|
|||||||
@@ -117,7 +117,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
|||||||
new TransportKeySet(keySetId, contactId, null, updated)));
|
new TransportKeySet(keySetId, contactId, null, updated)));
|
||||||
// Schedule a key update at the start of the next time period
|
// Schedule a key update at the start of the next time period
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(timePeriodLength - 1), with(MILLISECONDS));
|
with(dbExecutor), with(timePeriodLength - 1),
|
||||||
|
with(MILLISECONDS));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
transportKeyManager.start(txn);
|
transportKeyManager.start(txn);
|
||||||
@@ -420,9 +421,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
// Schedule a key update at the start of the next time period
|
// Schedule a key update at the start of the next time period
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(timePeriodLength), with(MILLISECONDS));
|
with(dbExecutor), with(timePeriodLength),
|
||||||
will(new RunAction());
|
with(MILLISECONDS));
|
||||||
oneOf(dbExecutor).execute(with(any(Runnable.class)));
|
|
||||||
will(new RunAction());
|
will(new RunAction());
|
||||||
// Start a transaction for updating keys
|
// Start a transaction for updating keys
|
||||||
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
@@ -445,7 +445,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
|||||||
new TransportKeySet(keySetId, contactId, null, updated)));
|
new TransportKeySet(keySetId, contactId, null, updated)));
|
||||||
// Schedule a key update at the start of the next time period
|
// Schedule a key update at the start of the next time period
|
||||||
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
oneOf(scheduler).schedule(with(any(Runnable.class)),
|
||||||
with(timePeriodLength), with(MILLISECONDS));
|
with(dbExecutor), with(timePeriodLength),
|
||||||
|
with(MILLISECONDS));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
transportKeyManager.start(txn);
|
transportKeyManager.start(txn);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ 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.AndroidWakeLockManager;
|
||||||
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;
|
||||||
@@ -135,17 +135,17 @@ public class AppModule {
|
|||||||
ResourceProvider resourceProvider,
|
ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider,
|
CircumventionProvider circumventionProvider,
|
||||||
BatteryManager batteryManager,
|
BatteryManager batteryManager,
|
||||||
AndroidWakeLockFactory wakeLockFactory,
|
AndroidWakeLockManager wakeLockManager,
|
||||||
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, androidExecutor, wakeLockFactory, appContext,
|
ioExecutor, androidExecutor, wakeLockManager, appContext,
|
||||||
random, eventBus, clock, timeoutMonitor, backoffFactory);
|
random, eventBus, clock, timeoutMonitor, backoffFactory);
|
||||||
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
|
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
|
||||||
appContext, networkManager, locationUtils, eventBus,
|
appContext, networkManager, locationUtils, eventBus,
|
||||||
torSocketFactory, backoffFactory, resourceProvider,
|
torSocketFactory, backoffFactory, resourceProvider,
|
||||||
circumventionProvider, batteryManager, wakeLockFactory, clock);
|
circumventionProvider, batteryManager, wakeLockManager, 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);
|
||||||
|
|||||||
@@ -146,9 +146,8 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook,
|
|||||||
private void startFeedExecutor() {
|
private void startFeedExecutor() {
|
||||||
if (fetcherStarted.getAndSet(true)) return;
|
if (fetcherStarted.getAndSet(true)) return;
|
||||||
LOG.info("Tor started, scheduling RSS feed fetcher");
|
LOG.info("Tor started, scheduling RSS feed fetcher");
|
||||||
Runnable fetcher = () -> ioExecutor.execute(this::fetchFeeds);
|
scheduler.scheduleWithFixedDelay(this::fetchFeeds, ioExecutor,
|
||||||
scheduler.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL,
|
FETCH_DELAY_INITIAL, FETCH_INTERVAL, FETCH_UNIT);
|
||||||
FETCH_INTERVAL, FETCH_UNIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -471,6 +470,7 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook,
|
|||||||
if (date == null) time = now;
|
if (date == null) time = now;
|
||||||
else time = Math.max(0, Math.min(date.getTime(), now));
|
else time = Math.max(0, Math.min(date.getTime(), now));
|
||||||
String text = getPostText(b.toString());
|
String text = getPostText(b.toString());
|
||||||
|
//noinspection TryWithIdenticalCatches
|
||||||
try {
|
try {
|
||||||
// create and store post
|
// create and store post
|
||||||
LocalAuthor localAuthor = feed.getLocalAuthor();
|
LocalAuthor localAuthor = feed.getLocalAuthor();
|
||||||
|
|||||||
Reference in New Issue
Block a user