From d55fb25a40f1dd70fe114aa91eee43cbcae4f5f3 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 9 Mar 2020 16:18:55 -0600 Subject: [PATCH] KernelModuleDisablerPreference: turn off tunnels before switching backend Signed-off-by: Jason A. Donenfeld --- .../android/model/TunnelManager.java | 2 +- .../KernelModuleDisablerPreference.java | 35 +++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ui/src/main/java/com/wireguard/android/model/TunnelManager.java b/ui/src/main/java/com/wireguard/android/model/TunnelManager.java index 4322b9e6..e370f8de 100644 --- a/ui/src/main/java/com/wireguard/android/model/TunnelManager.java +++ b/ui/src/main/java/com/wireguard/android/model/TunnelManager.java @@ -247,7 +247,7 @@ public final class TunnelManager extends BaseObservable { }); } - CompletionStage setTunnelState(final ObservableTunnel tunnel, final State state) { + public CompletionStage setTunnelState(final ObservableTunnel tunnel, final State state) { // Ensure the configuration is loaded before trying to use it. return tunnel.getConfigAsync().thenCompose(config -> Application.getAsyncWorker().supplyAsync(() -> Application.getBackend().setState(tunnel, state, config)) diff --git a/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java index b3d945bd..f991fb22 100644 --- a/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java +++ b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java @@ -7,14 +7,22 @@ package com.wireguard.android.preference; import android.content.Context; import android.content.Intent; +import android.os.SystemClock; import android.util.AttributeSet; import com.wireguard.android.Application; import com.wireguard.android.R; +import com.wireguard.android.backend.Tunnel; import com.wireguard.android.backend.WgQuickBackend; import com.wireguard.util.NonNullForAll; +import java.util.ArrayList; +import java.util.Collection; + import androidx.preference.Preference; +import java9.util.concurrent.CompletableFuture; +import java9.util.stream.Collectors; +import java9.util.stream.StreamSupport; @NonNullForAll public class KernelModuleDisablerPreference extends Preference { @@ -44,16 +52,23 @@ public class KernelModuleDisablerPreference extends Preference { setState(State.DISABLING); Application.getSharedPreferences().edit().putBoolean("disable_kernel_module", true).apply(); } - Application.getAsyncWorker().runAsync(() -> { - Thread.sleep(1000 * 5); - Intent i = getContext().getPackageManager().getLaunchIntentForPackage(getContext().getPackageName()); - if (i == null) - return; - i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Application.get().startActivity(i); - System.exit(0); - }); + final long start = SystemClock.elapsedRealtime(); + Application.getAsyncWorker().runAsync(() -> Application.getTunnelManager().getTunnels().thenApply(observableTunnels -> { + final Collection> c = StreamSupport.stream(observableTunnels.values()).map(t -> t.setState(Tunnel.State.DOWN).toCompletableFuture()).collect(Collectors.toCollection(ArrayList::new)); + return CompletableFuture.allOf(c.toArray(new CompletableFuture[0])).thenRun(() -> { + try { + Thread.sleep(Math.max(0, 1000 * 5 - (SystemClock.elapsedRealtime() - start))); + } catch (final Exception ignored) { + } + final Intent i = getContext().getPackageManager().getLaunchIntentForPackage(getContext().getPackageName()); + if (i == null) + return; + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Application.get().startActivity(i); + System.exit(0); + }); + }).join()); } private void setState(final State state) {