Skip to content
Snippets Groups Projects
Verified Commit c089a099 authored by akwizgran's avatar akwizgran
Browse files

Refactor wake lock to use existing ScheduledExecutorService.

parent 98a0d098
No related branches found
No related tags found
No related merge requests found
...@@ -36,7 +36,7 @@ import org.briarproject.bramble.api.settings.Settings; ...@@ -36,7 +36,7 @@ import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.IoUtils; 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 org.briarproject.bramble.util.StringUtils;
import java.io.Closeable; import java.io.Closeable;
...@@ -120,12 +120,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { ...@@ -120,12 +120,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final ConnectionStatus connectionStatus; private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile; private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile; private final File doneFile, cookieFile;
private final RenewableWakeLock wakeLock;
private final AtomicReference<Future<?>> connectivityCheck = private final AtomicReference<Future<?>> connectivityCheck =
new AtomicReference<>(); new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
private final ScheduledExecutorServiceWakeLock scheduledExecutorServiceWakeLock;
private PowerManager.WakeLock wakeLock;
private volatile boolean running = false; private volatile boolean running = false;
private volatile ServerSocket socket = null; private volatile ServerSocket socket = null;
...@@ -161,24 +159,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { ...@@ -161,24 +159,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
// Don't execute more than one connection status check at a time // Don't execute more than one connection status check at a time
connectionStatusExecutor = new PoliteExecutor("TorPlugin", connectionStatusExecutor = new PoliteExecutor("TorPlugin",
ioExecutor, 1); 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) PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE); appContext.getSystemService(POWER_SERVICE);
// This tag will prevent Huawei's powermanager from killing us. // This tag will prevent Huawei's power manager from killing us
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService"); wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
wakeLock.setReferenceCounted(false); "LocationManagerService", 30, MINUTES);
scheduledExecutorServiceWakeLock.setAlarm(1800000, MILLISECONDS);
} }
@Override @Override
...@@ -530,7 +515,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { ...@@ -530,7 +515,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
} }
wakeLock.release(); wakeLock.release();
scheduledExecutorServiceWakeLock.cancelAlarm();
} }
@Override @Override
......
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;
}
}
}
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment