Fix circular dependency between scheduler and wake lock manager.

This commit is contained in:
akwizgran
2020-08-06 16:10:50 +01:00
parent e6c3f82fe2
commit af1a91c819
5 changed files with 42 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
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.AndroidWakeLockManager; import org.briarproject.bramble.api.system.AndroidWakeLockManager;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
@@ -8,6 +9,9 @@ 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(

View File

@@ -7,9 +7,7 @@ import org.briarproject.bramble.api.system.AlarmListener;
import org.briarproject.bramble.api.system.AndroidWakeLockManager; 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;
@@ -25,21 +23,12 @@ 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,
AndroidWakeLockManager wakeLockManager) { AndroidWakeLockManager wakeLockManager,
lifecycleManager.registerForShutdown(scheduledExecutorService); ScheduledExecutorService scheduledExecutorService) {
AndroidTaskScheduler scheduler = new AndroidTaskScheduler(app, AndroidTaskScheduler scheduler = new AndroidTaskScheduler(app,
wakeLockManager, scheduledExecutorService); wakeLockManager, scheduledExecutorService);
lifecycleManager.registerService(scheduler); lifecycleManager.registerService(scheduler);

View File

@@ -6,13 +6,12 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.PowerManager; import android.os.PowerManager;
import org.briarproject.bramble.api.event.EventExecutor;
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.AndroidWakeLockManager; import org.briarproject.bramble.api.system.AndroidWakeLockManager;
import org.briarproject.bramble.api.system.TaskScheduler;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
@@ -41,15 +40,14 @@ class AndroidWakeLockManagerImpl implements AndroidWakeLockManager {
private final SharedWakeLock sharedWakeLock; private final SharedWakeLock sharedWakeLock;
@Inject @Inject
AndroidWakeLockManagerImpl(TaskScheduler scheduler, AndroidWakeLockManagerImpl(Application app,
@EventExecutor Executor eventExecutor, ScheduledExecutorService scheduledExecutorService) {
Application app) {
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,
eventExecutor, PARTIAL_WAKE_LOCK, tag, LOCK_DURATION_MS, scheduledExecutorService, PARTIAL_WAKE_LOCK, tag,
SAFETY_MARGIN_MS); LOCK_DURATION_MS, SAFETY_MARGIN_MS);
} }
@Override @Override

View File

@@ -4,10 +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.Executor;
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;
@@ -28,8 +27,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 Executor eventExecutor;
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;
@@ -47,15 +45,13 @@ class RenewableWakeLock implements SharedWakeLock {
private long acquired = 0; private long acquired = 0;
RenewableWakeLock(PowerManager powerManager, RenewableWakeLock(PowerManager powerManager,
TaskScheduler scheduler, ScheduledExecutorService scheduledExecutorService,
Executor eventExecutor,
int levelAndFlags, int levelAndFlags,
String tag, String tag,
long durationMs, long durationMs,
long safetyMarginMs) { long safetyMarginMs) {
this.powerManager = powerManager; this.powerManager = powerManager;
this.scheduler = scheduler; this.scheduledExecutorService = scheduledExecutorService;
this.eventExecutor = eventExecutor;
this.levelAndFlags = levelAndFlags; this.levelAndFlags = levelAndFlags;
this.tag = tag; this.tag = tag;
this.durationMs = durationMs; this.durationMs = durationMs;
@@ -76,7 +72,7 @@ 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, eventExecutor, future = scheduledExecutorService.schedule(this::renew,
durationMs, MILLISECONDS); durationMs, MILLISECONDS);
acquired = android.os.SystemClock.elapsedRealtime(); acquired = android.os.SystemClock.elapsedRealtime();
} }
@@ -100,8 +96,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, eventExecutor, future = scheduledExecutorService.schedule(this::renew, durationMs,
durationMs, MILLISECONDS); MILLISECONDS);
acquired = now; acquired = now;
} }
} }

View File

@@ -17,23 +17,24 @@ import javax.annotation.concurrent.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, Executor executor, long delay, public Future<?> schedule(Runnable task, Executor executor, long delay,
TimeUnit unit) { TimeUnit unit) {
Runnable execute = () -> executor.execute(task); Runnable execute = () -> executor.execute(task);
return delegate.schedule(execute, delay, unit); return scheduledExecutorService.schedule(execute, delay, unit);
} }
@Override @Override
public Future<?> scheduleWithFixedDelay(Runnable task, Executor executor, public Future<?> scheduleWithFixedDelay(Runnable task, Executor executor,
long delay, long interval, TimeUnit unit) { long delay, long interval, TimeUnit unit) {
Runnable execute = () -> executor.execute(task); Runnable execute = () -> executor.execute(task);
return delegate.scheduleWithFixedDelay(execute, delay, interval, unit); return scheduledExecutorService.scheduleWithFixedDelay(execute, delay,
interval, unit);
} }
} }