diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java index 52b2a293d2a53759940e3902dd5b0e35e7c4809f..c62aac754f3102e7652bcd6414bf6ed7fc0d2d81 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/AndroidPluginModule.java @@ -13,6 +13,7 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.reporting.DevReporter; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; import org.briarproject.bramble.plugin.tor.TorPluginFactory; @@ -22,6 +23,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import javax.net.SocketFactory; @@ -33,6 +35,7 @@ public class AndroidPluginModule { @Provides PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor, + @Scheduler ScheduledExecutorService scheduler, AndroidExecutor androidExecutor, SecureRandom random, SocketFactory torSocketFactory, BackoffFactory backoffFactory, Application app, LocationUtils locationUtils, DevReporter reporter, @@ -41,9 +44,9 @@ public class AndroidPluginModule { DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, appContext, random, eventBus, backoffFactory); - DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext, - locationUtils, reporter, eventBus, torSocketFactory, - backoffFactory); + DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler, + appContext, locationUtils, reporter, eventBus, + torSocketFactory, backoffFactory); DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, backoffFactory, appContext); Collection<DuplexPluginFactory> duplex = diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index ce6d5cdf081e2f9aea229bbf0b4a9dcfbaf1d65d..67e48d3da0865ad1aa7c3bbd72855092bf289b9f 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -11,8 +11,6 @@ import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.FileObserver; -import android.os.Handler; -import android.os.Looper; import android.os.PowerManager; import net.freehaven.tor.control.EventHandler; @@ -61,7 +59,10 @@ import java.util.Map.Entry; import java.util.Scanner; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; @@ -82,6 +83,7 @@ import static android.os.Build.VERSION.SDK_INT; import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS; @@ -110,6 +112,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { Logger.getLogger(TorPlugin.class.getName()); private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; private final Context appContext; private final LocationUtils locationUtils; private final DevReporter reporter; @@ -123,7 +126,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final File doneFile, cookieFile; private final PowerManager.WakeLock wakeLock; private final Lock connectionStatusLock; - private final Handler handler; + private final AtomicReference<Future<?>> connectivityCheck = + new AtomicReference<>(); private final AtomicBoolean used = new AtomicBoolean(false); private volatile boolean running = false; @@ -132,12 +136,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private volatile TorControlConnection controlConnection = null; private volatile BroadcastReceiver networkStateReceiver = null; - TorPlugin(Executor ioExecutor, Context appContext, - LocationUtils locationUtils, DevReporter reporter, - SocketFactory torSocketFactory, Backoff backoff, - DuplexPluginCallback callback, String architecture, int maxLatency, - int maxIdleTime) { + TorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler, + Context appContext, LocationUtils locationUtils, + DevReporter reporter, SocketFactory torSocketFactory, + Backoff backoff, DuplexPluginCallback callback, + String architecture, int maxLatency, int maxIdleTime) { this.ioExecutor = ioExecutor; + this.scheduler = scheduler; this.appContext = appContext; this.locationUtils = locationUtils; this.reporter = reporter; @@ -163,7 +168,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService"); wakeLock.setReferenceCounted(false); connectionStatusLock = new ReentrantLock(); - handler = new Handler(Looper.getMainLooper()); } @Override @@ -216,11 +220,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (LOG.isLoggable(INFO)) { Scanner stdout = new Scanner(torProcess.getInputStream()); Scanner stderr = new Scanner(torProcess.getErrorStream()); - while (stdout.hasNextLine() || stderr.hasNextLine()){ - if(stdout.hasNextLine()) { + while (stdout.hasNextLine() || stderr.hasNextLine()) { + if (stdout.hasNextLine()) { LOG.info(stdout.nextLine()); } - if(stderr.hasNextLine()){ + if (stderr.hasNextLine()) { LOG.info(stderr.nextLine()); } } @@ -743,6 +747,14 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } } + private void scheduleConnectionStatusUpdate() { + Future<?> newConnectivityCheck = + scheduler.schedule(this::updateConnectionStatus, 1, MINUTES); + Future<?> oldConnectivityCheck = + connectivityCheck.getAndSet(newConnectivityCheck); + if (oldConnectivityCheck != null) oldConnectivityCheck.cancel(false); + } + private class NetworkStateReceiver extends BroadcastReceiver { @Override @@ -750,16 +762,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (!running) return; String action = i.getAction(); if (LOG.isLoggable(INFO)) LOG.info("Received broadcast " + action); - if (CONNECTIVITY_ACTION.equals(action)) { - updateConnectionStatus(); - } else if (ACTION_SCREEN_ON.equals(action) + updateConnectionStatus(); + if (ACTION_SCREEN_ON.equals(action) || ACTION_SCREEN_OFF.equals(action)) { - // Update connection status after 1 minute - handler.postDelayed(TorPlugin.this::updateConnectionStatus, - 60 * 1000); - } else if (SDK_INT >= 23 - && ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) { - updateConnectionStatus(); + scheduleConnectionStatusUpdate(); } } } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java index 2f479d4ef8a147b755c9b3f0a17fe83359dfdbc9..4ad1e8f3ac6255b55ac8b7a357a93001b5b7d04d 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.util.AndroidUtils; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Logger; import javax.annotation.concurrent.Immutable; @@ -36,6 +37,7 @@ public class TorPluginFactory implements DuplexPluginFactory { private static final double BACKOFF_BASE = 1.2; private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; private final Context appContext; private final LocationUtils locationUtils; private final DevReporter reporter; @@ -43,11 +45,13 @@ public class TorPluginFactory implements DuplexPluginFactory { private final SocketFactory torSocketFactory; private final BackoffFactory backoffFactory; - public TorPluginFactory(Executor ioExecutor, Context appContext, + public TorPluginFactory(Executor ioExecutor, + ScheduledExecutorService scheduler, Context appContext, LocationUtils locationUtils, DevReporter reporter, EventBus eventBus, SocketFactory torSocketFactory, BackoffFactory backoffFactory) { this.ioExecutor = ioExecutor; + this.scheduler = scheduler; this.appContext = appContext; this.locationUtils = locationUtils; this.reporter = reporter; @@ -89,9 +93,9 @@ public class TorPluginFactory implements DuplexPluginFactory { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); - TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils, - reporter, torSocketFactory, backoff, callback, architecture, - MAX_LATENCY, MAX_IDLE_TIME); + TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext, + locationUtils, reporter, torSocketFactory, backoff, callback, + architecture, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; }