Refactor wake lock to use existing ScheduledExecutorService.

This commit is contained in:
akwizgran
2017-10-11 15:39:22 +01:00
parent 98a0d09899
commit c089a099f0
3 changed files with 95 additions and 68 deletions

View File

@@ -36,7 +36,7 @@ import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.ScheduledExecutorServiceWakeLock;
import org.briarproject.bramble.util.RenewableWakeLock;
import org.briarproject.bramble.util.StringUtils;
import java.io.Closeable;
@@ -120,12 +120,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile;
private final RenewableWakeLock wakeLock;
private final AtomicReference<Future<?>> connectivityCheck =
new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false);
private final ScheduledExecutorServiceWakeLock scheduledExecutorServiceWakeLock;
private PowerManager.WakeLock wakeLock;
private volatile boolean running = false;
private volatile ServerSocket socket = null;
@@ -161,24 +159,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
// Don't execute more than one connection status check at a time
connectionStatusExecutor = new PoliteExecutor("TorPlugin",
ioExecutor, 1);
scheduledExecutorServiceWakeLock =
new ScheduledExecutorServiceWakeLock(appContext);
scheduledExecutorServiceWakeLock.setRunnable((Runnable) () -> {
LOG.info("Renewing wake lock");
wakeLock.release();
aquireWakeLock();
});
aquireWakeLock();
}
private void aquireWakeLock(){
LOG.info("Aquiring wake lock");
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
// This tag will prevent Huawei's powermanager from killing us.
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
wakeLock.setReferenceCounted(false);
scheduledExecutorServiceWakeLock.setAlarm(1800000, MILLISECONDS);
// This tag will prevent Huawei's power manager from killing us
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
"LocationManagerService", 30, MINUTES);
}
@Override
@@ -530,7 +515,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
}
wakeLock.release();
scheduledExecutorServiceWakeLock.cancelAlarm();
}
@Override

View File

@@ -0,0 +1,90 @@
package org.briarproject.bramble.util;
import android.os.PowerManager;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
public class RenewableWakeLock {
private static final Logger LOG =
Logger.getLogger(RenewableWakeLock.class.getName());
private final PowerManager powerManager;
private final ScheduledExecutorService scheduler;
private final int levelAndFlags;
private final String tag;
private final long duration;
private final TimeUnit timeUnit;
private final Runnable renewTask;
private final Object lock = new Object();
private PowerManager.WakeLock wakeLock; // Locking: lock
private ScheduledFuture future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager,
ScheduledExecutorService scheduler, int levelAndFlags, String tag,
long duration, TimeUnit timeUnit) {
this.powerManager = powerManager;
this.scheduler = scheduler;
this.levelAndFlags = levelAndFlags;
this.tag = tag;
this.duration = duration;
this.timeUnit = timeUnit;
renewTask = new Runnable() {
@Override
public void run() {
renew();
}
};
}
public void acquire() {
if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag );
synchronized (lock) {
if (wakeLock != null) {
LOG.info("Already acquired");
return;
}
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire();
future = scheduler.schedule(renewTask, duration, timeUnit);
}
}
private void renew() {
if (LOG.isLoggable(INFO)) LOG.info("Renewing wake lock " + tag );
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
PowerManager.WakeLock oldWakeLock = wakeLock;
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire();
oldWakeLock.release();
future = scheduler.schedule(renewTask, duration, timeUnit);
}
}
public void release() {
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag );
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
future.cancel(false);
future = null;
wakeLock.release();
wakeLock = null;
}
}
}

View File

@@ -1,47 +0,0 @@
package org.briarproject.bramble.util;
import android.content.Context;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorServiceWakeLock {
final Context appContext;
private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
};
private ScheduledExecutorService scheduledExecutorService = null; // Locking: this
private Runnable runnable;
public ScheduledExecutorServiceWakeLock(Context appContext) {
this.appContext = appContext;
}
public void setRunnable(Runnable r){
runnable = r;
}
public synchronized void setAlarm(long delay, TimeUnit unit) {
if(runnable == null)
return;
if (scheduledExecutorService == null)
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(THREAD_FACTORY);
scheduledExecutorService.schedule(runnable, delay, unit);
}
public synchronized void cancelAlarm() {
if (scheduledExecutorService == null) throw new IllegalStateException();
scheduledExecutorService.shutdownNow();
scheduledExecutorService = null;
}
}