diff --git a/app/src/main/java/com/wireguard/android/model/Tunnel.java b/app/src/main/java/com/wireguard/android/model/Tunnel.java index e61ea095..9cdcf71f 100644 --- a/app/src/main/java/com/wireguard/android/model/Tunnel.java +++ b/app/src/main/java/com/wireguard/android/model/Tunnel.java @@ -112,6 +112,12 @@ public class Tunnel extends BaseObservable implements Keyed { notifyPropertyChanged(BR.statistics); } + public CompletionStage rename(@NonNull final String name) { + if (!name.equals(this.name)) + return manager.rename(this, name); + return CompletableFuture.completedFuture(this); + } + public CompletionStage setConfig(@NonNull final Config config) { if (!config.equals(this.config)) return manager.setTunnelConfig(this, config); diff --git a/app/src/main/java/com/wireguard/android/model/TunnelManager.java b/app/src/main/java/com/wireguard/android/model/TunnelManager.java index beed16fe..b0e6ead2 100644 --- a/app/src/main/java/com/wireguard/android/model/TunnelManager.java +++ b/app/src/main/java/com/wireguard/android/model/TunnelManager.java @@ -120,6 +120,32 @@ public final class TunnelManager { addToList(name, null, running.contains(name) ? State.UP : State.DOWN); } + CompletionStage rename(final Tunnel tunnel, final String name) { + if (!Tunnel.isNameValid(name)) + return CompletableFuture.failedFuture(new IllegalArgumentException("Invalid name")); + if (tunnels.containsKey(name)) { + final String message = "Tunnel " + name + " already exists"; + return CompletableFuture.failedFuture(new IllegalArgumentException(message)); + } + final State originalState = tunnel.getState(); + return asyncWorker.supplyAsync(() -> { + backend.setState(tunnel, State.DOWN); + final Config newConfig = configStore.create(name, tunnel.getConfig()); + final Tunnel newTunnel = new Tunnel(this, name, newConfig, State.DOWN); + if (originalState == State.UP) { + backend.setState(newTunnel, originalState); + newTunnel.onStateChanged(originalState); + } + configStore.delete(tunnel.getName()); + return newTunnel; + }).whenComplete((newTunnel, e) -> { + if (e != null) + return; + tunnels.remove(tunnel); + tunnels.add(newTunnel); + }); + } + public CompletionStage restoreState() { if (!preferences.getBoolean(KEY_RESTORE_ON_BOOT, false)) return CompletableFuture.completedFuture(null);