diff options
author | cyBerta <cyberta@riseup.net> | 2021-11-05 02:38:26 +0100 |
---|---|---|
committer | cyBerta <cyberta@riseup.net> | 2021-11-05 02:38:26 +0100 |
commit | 88b7dc2eb3dcbec8d1e637096867c15211818677 (patch) | |
tree | 739dd893e230ca9362b126bbb8fd47e78bfee5ea /app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | |
parent | d27af3b17d6636de8b2755090b6fe6329531f639 (diff) |
Ensure tor state is set to OFF after snowflake completely stopped.
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java')
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index f4f0ff11..eca0f555 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -9,7 +9,12 @@ import androidx.annotation.Nullable; import org.torproject.jni.TorService; import java.util.Observable; +import java.util.Observer; import java.util.Vector; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import se.leap.bitmaskclient.R; @@ -17,21 +22,34 @@ public class TorStatusObservable extends Observable { private static final String TAG = TorStatusObservable.class.getSimpleName(); + public interface StatusCondition { + boolean met(); + } + public enum TorStatus { ON, OFF, STARTING, - STOPPING, - // UNKOWN + STOPPING + } + + public enum SnowflakeStatus { + ON, + OFF } + // indicates if the user has cancelled Tor, the actual TorStatus can still be different until + // the TorService has sent the shutdown signal private boolean cancelled = false; public static final String LOG_TAG_TOR = "[TOR]"; public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; + public static final String SNOWFLAKE_STARTED = "--- Starting Snowflake Client ---"; + public static final String SNOWFLAKE_STOPPED = "---- SnowflakeConn: end collecting snowflakes ---"; private static TorStatusObservable instance; private TorStatus status = TorStatus.OFF; + private SnowflakeStatus snowflakeStatus = SnowflakeStatus.OFF; private final TorNotificationManager torNotificationManager; private String lastError; private String lastTorLog; @@ -55,13 +73,50 @@ public class TorStatusObservable extends Observable { return getInstance().status; } + public static SnowflakeStatus getSnowflakeStatus() { + return getInstance().snowflakeStatus; + } + + /** + * Waits on the current Thread until a certain tor/snowflake status has been reached + * @param condition defines when wait should be interrupted + * @param timeout Timout in seconds + * @throws InterruptedException if thread was interrupted while waiting + * @throws TimeoutException thrown if timeout was reached + */ + public static void waitUntil(StatusCondition condition, int timeout) throws InterruptedException, TimeoutException { + CountDownLatch countDownLatch = new CountDownLatch(1); + final AtomicBoolean conditionMet = new AtomicBoolean(false); + Observer observer = (o, arg) -> { + if (condition.met()) { + countDownLatch.countDown(); + conditionMet.set(true); + } + }; + if (condition.met()) { + // no need to wait + return; + } + getInstance().addObserver(observer); + countDownLatch.await(timeout, TimeUnit.SECONDS); + getInstance().deleteObserver(observer); + if (!conditionMet.get()) { + throw new TimeoutException("Status condition not met within " + timeout + "s."); + } + } + public static void logSnowflakeMessage(Context context, String message) { - Log.d(LOG_TAG_SNOWFLAKE, message); addLog(message); getInstance().lastSnowflakeLog = message; if (getInstance().status != TorStatus.OFF) { getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getBootstrapProgress()); } + //TODO: implement proper state signalling in IPtProxy + if (SNOWFLAKE_STARTED.equals(message)) { + getInstance().snowflakeStatus = SnowflakeStatus.ON; + } else if (SNOWFLAKE_STOPPED.equals(message)) { + getInstance().snowflakeStatus = SnowflakeStatus.OFF; + } instance.setChanged(); instance.notifyObservers(); } @@ -206,7 +261,7 @@ public class TorStatusObservable extends Observable { getInstance().notifyObservers(); Intent intent = new Intent(context, TorService.class); - boolean stopped = context.stopService(intent); + context.stopService(intent); } public static boolean isCancelled() { |