mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 22:59:54 +01:00
Merge branch '992-refresh-wake-lock' into 'master'
Renew the wake lock every minute to avoid wake lock killers See merge request akwizgran/briar!827
This commit is contained in:
@@ -36,6 +36,7 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
|
|||||||
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.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
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;
|
||||||
@@ -103,6 +104,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
private static final int COOKIE_TIMEOUT_MS = 3000;
|
private static final int COOKIE_TIMEOUT_MS = 3000;
|
||||||
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
||||||
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
|
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
|
||||||
|
// This tag may prevent Huawei's power manager from killing us
|
||||||
|
private static final String WAKE_LOCK_TAG = "LocationManagerService";
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(TorPlugin.class.getName());
|
Logger.getLogger(TorPlugin.class.getName());
|
||||||
|
|
||||||
@@ -119,7 +122,7 @@ 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 PowerManager.WakeLock wakeLock;
|
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);
|
||||||
@@ -156,14 +159,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
configFile = new File(torDirectory, "torrc");
|
configFile = new File(torDirectory, "torrc");
|
||||||
doneFile = new File(torDirectory, "done");
|
doneFile = new File(torDirectory, "done");
|
||||||
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
||||||
Object o = appContext.getSystemService(POWER_SERVICE);
|
|
||||||
PowerManager pm = (PowerManager) o;
|
|
||||||
// This tag will prevent Huawei's powermanager from killing us.
|
|
||||||
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
|
|
||||||
wakeLock.setReferenceCounted(false);
|
|
||||||
// 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);
|
||||||
|
PowerManager pm = (PowerManager)
|
||||||
|
appContext.getSystemService(POWER_SERVICE);
|
||||||
|
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
||||||
|
WAKE_LOCK_TAG, 1, MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package org.briarproject.bramble.util;
|
||||||
|
|
||||||
|
import android.os.PowerManager;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
|
||||||
|
@ThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
public class RenewableWakeLock {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(RenewableWakeLock.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically release the lock this many milliseconds after it's due
|
||||||
|
* to have been replaced and released.
|
||||||
|
*/
|
||||||
|
private static final int SAFETY_MARGIN_MS = 10_000;
|
||||||
|
|
||||||
|
private final PowerManager powerManager;
|
||||||
|
private final ScheduledExecutorService scheduler;
|
||||||
|
private final int levelAndFlags;
|
||||||
|
private final String tag;
|
||||||
|
private final long durationMs;
|
||||||
|
private final Runnable renewTask;
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
@Nullable
|
||||||
|
private PowerManager.WakeLock wakeLock; // Locking: lock
|
||||||
|
@Nullable
|
||||||
|
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;
|
||||||
|
durationMs = MILLISECONDS.convert(duration, timeUnit);
|
||||||
|
renewTask = this::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(durationMs + SAFETY_MARGIN_MS);
|
||||||
|
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(durationMs + SAFETY_MARGIN_MS);
|
||||||
|
oldWakeLock.release();
|
||||||
|
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void release() {
|
||||||
|
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag);
|
||||||
|
synchronized (lock) {
|
||||||
|
if (wakeLock == null) {
|
||||||
|
LOG.info("Already released");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (future == null) throw new AssertionError();
|
||||||
|
future.cancel(false);
|
||||||
|
future = null;
|
||||||
|
wakeLock.release();
|
||||||
|
wakeLock = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user