Tunnel: move state change into interface

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2020-03-09 04:32:51 -06:00
parent 3c2fa15dc2
commit d9e9dd04af
6 changed files with 23 additions and 65 deletions

View File

@ -60,22 +60,4 @@ public interface Backend {
* @return The updated state of the tunnel. * @return The updated state of the tunnel.
*/ */
Tunnel.State setState(Tunnel tunnel, Tunnel.State state, @Nullable Config config) throws Exception; Tunnel.State setState(Tunnel tunnel, Tunnel.State state, @Nullable Config config) throws Exception;
interface TunnelStateChangeNotificationReceiver {
void tunnelStateChange(Tunnel tunnel, Tunnel.State state);
}
/**
* Register a state change notification callback.
*
* @param receiver The receiver object to receive the notification.
*/
void registerStateChangeNotification(TunnelStateChangeNotificationReceiver receiver);
/**
* Unregister a state change notification callback.
*
* @param receiver The receiver object to no longer receive the notification.
*/
void unregisterStateChangeNotification(TunnelStateChangeNotificationReceiver receiver);
} }

View File

@ -5,7 +5,6 @@
package com.wireguard.android.backend; package com.wireguard.android.backend;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
@ -25,7 +24,6 @@ import com.wireguard.crypto.KeyFormatException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -48,8 +46,6 @@ public final class GoBackend implements Backend {
@Nullable private Config currentConfig; @Nullable private Config currentConfig;
private int currentTunnelHandle = -1; private int currentTunnelHandle = -1;
private final Set<TunnelStateChangeNotificationReceiver> notifiers = new HashSet<>();
public GoBackend(final Context context) { public GoBackend(final Context context) {
SharedLibraryLoader.loadSharedLibrary(context, "wg-go"); SharedLibraryLoader.loadSharedLibrary(context, "wg-go");
this.context = context; this.context = context;
@ -240,8 +236,7 @@ public final class GoBackend implements Backend {
currentConfig = null; currentConfig = null;
} }
for (final TunnelStateChangeNotificationReceiver notifier : notifiers) tunnel.onStateChange(state);
notifier.tunnelStateChange(tunnel, state);
} }
private void startVpnService() { private void startVpnService() {
@ -249,16 +244,6 @@ public final class GoBackend implements Backend {
context.startService(new Intent(context, VpnService.class)); context.startService(new Intent(context, VpnService.class));
} }
@Override
public void registerStateChangeNotification(final TunnelStateChangeNotificationReceiver receiver) {
notifiers.add(receiver);
}
@Override
public void unregisterStateChangeNotification(final TunnelStateChangeNotificationReceiver receiver) {
notifiers.remove(receiver);
}
public static class VpnService extends android.net.VpnService { public static class VpnService extends android.net.VpnService {
@Nullable private GoBackend owner; @Nullable private GoBackend owner;
@ -286,8 +271,7 @@ public final class GoBackend implements Backend {
owner.currentTunnel = null; owner.currentTunnel = null;
owner.currentTunnelHandle = -1; owner.currentTunnelHandle = -1;
owner.currentConfig = null; owner.currentConfig = null;
for (final TunnelStateChangeNotificationReceiver notifier : owner.notifiers) tunnel.onStateChange(State.DOWN);
notifier.tunnelStateChange(tunnel, State.DOWN);
} }
} }
vpnService = vpnService.newIncompleteFuture(); vpnService = vpnService.newIncompleteFuture();

View File

@ -29,5 +29,18 @@ public interface Tunnel {
return !NAME_PATTERN.matcher(name).matches(); return !NAME_PATTERN.matcher(name).matches();
} }
/**
* Get the name of the tunnel, which should always pass the !isNameInvalid test.
*
* @return The name of the tunnel.
*/
String getName(); String getName();
/**
* React to a change in state of the tunnel. Should only be directly called by Backend.
*
* @param newState The new state of the tunnel.
* @return The new state of the tunnel.
*/
void onStateChange(State newState);
} }

View File

@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -45,7 +44,6 @@ public final class WgQuickBackend implements Backend {
private final ToolsInstaller toolsInstaller; private final ToolsInstaller toolsInstaller;
private final File localTemporaryDir; private final File localTemporaryDir;
private final Map<Tunnel, Config> runningConfigs = new HashMap<>(); private final Map<Tunnel, Config> runningConfigs = new HashMap<>();
private final Set<TunnelStateChangeNotificationReceiver> notifiers = new HashSet<>();
public WgQuickBackend(final Context context, final RootShell rootShell, final ToolsInstaller toolsInstaller) { public WgQuickBackend(final Context context, final RootShell rootShell, final ToolsInstaller toolsInstaller) {
localTemporaryDir = new File(context.getCacheDir(), "tmp"); localTemporaryDir = new File(context.getCacheDir(), "tmp");
@ -155,17 +153,6 @@ public final class WgQuickBackend implements Backend {
else else
runningConfigs.remove(tunnel); runningConfigs.remove(tunnel);
for (final TunnelStateChangeNotificationReceiver notifier : notifiers) tunnel.onStateChange(state);
notifier.tunnelStateChange(tunnel, state);
}
@Override
public void registerStateChangeNotification(final TunnelStateChangeNotificationReceiver receiver) {
notifiers.add(receiver);
}
@Override
public void unregisterStateChangeNotification(final TunnelStateChangeNotificationReceiver receiver) {
notifiers.remove(receiver);
} }
} }

View File

@ -96,7 +96,7 @@ public class ObservableTunnel extends BaseObservable implements Keyed<String>, T
return config; return config;
} }
public String onNameChanged(final String name) { String onNameChanged(final String name) {
this.name = name; this.name = name;
notifyPropertyChanged(BR.name); notifyPropertyChanged(BR.name);
return name; return name;
@ -110,6 +110,11 @@ public class ObservableTunnel extends BaseObservable implements Keyed<String>, T
return state; return state;
} }
@Override
public void onStateChange(final State newState) {
onStateChanged(state);
}
@Nullable @Nullable
Statistics onStatisticsChanged(@Nullable final Statistics statistics) { Statistics onStatisticsChanged(@Nullable final Statistics statistics) {
this.statistics = statistics; this.statistics = statistics;

View File

@ -15,7 +15,6 @@ import androidx.annotation.Nullable;
import com.wireguard.android.Application; import com.wireguard.android.Application;
import com.wireguard.android.BR; import com.wireguard.android.BR;
import com.wireguard.android.R; import com.wireguard.android.R;
import com.wireguard.android.backend.Backend.TunnelStateChangeNotificationReceiver;
import com.wireguard.android.configStore.ConfigStore; import com.wireguard.android.configStore.ConfigStore;
import com.wireguard.android.backend.Tunnel; import com.wireguard.android.backend.Tunnel;
import com.wireguard.android.backend.Tunnel.State; import com.wireguard.android.backend.Tunnel.State;
@ -40,7 +39,7 @@ import java9.util.stream.StreamSupport;
* Maintains and mediates changes to the set of available WireGuard tunnels, * Maintains and mediates changes to the set of available WireGuard tunnels,
*/ */
public final class TunnelManager extends BaseObservable implements TunnelStateChangeNotificationReceiver { public final class TunnelManager extends BaseObservable {
private static final Comparator<String> COMPARATOR = Comparators.<String>thenComparing( private static final Comparator<String> COMPARATOR = Comparators.<String>thenComparing(
String.CASE_INSENSITIVE_ORDER, Comparators.naturalOrder()); String.CASE_INSENSITIVE_ORDER, Comparators.naturalOrder());
private static final String KEY_LAST_USED_TUNNEL = "last_used_tunnel"; private static final String KEY_LAST_USED_TUNNEL = "last_used_tunnel";
@ -57,13 +56,6 @@ public final class TunnelManager extends BaseObservable implements TunnelStateCh
public TunnelManager(final ConfigStore configStore) { public TunnelManager(final ConfigStore configStore) {
this.configStore = configStore; this.configStore = configStore;
Application.getBackendAsync().thenAccept(backend -> backend.registerStateChangeNotification(this));
}
@Override
protected void finalize() throws Throwable {
Application.getBackendAsync().thenAccept(backend -> backend.unregisterStateChangeNotification(this));
super.finalize();
} }
static CompletionStage<State> getTunnelState(final ObservableTunnel tunnel) { static CompletionStage<State> getTunnelState(final ObservableTunnel tunnel) {
@ -266,11 +258,6 @@ public final class TunnelManager extends BaseObservable implements TunnelStateCh
}); });
} }
@Override
public void tunnelStateChange(final Tunnel tunnel, final State state) {
((ObservableTunnel)tunnel).onStateChanged(state);
}
public static final class IntentReceiver extends BroadcastReceiver { public static final class IntentReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(final Context context, @Nullable final Intent intent) { public void onReceive(final Context context, @Nullable final Intent intent) {