aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEric Kuck <eric@bluelinelabs.com>2018-07-25 19:30:34 -0500
committerJason A. Donenfeld <Jason@zx2c4.com>2018-07-26 05:17:43 +0200
commit9652fe99df68db5c483ea8e170f6e09f06a5e0d1 (patch)
treed88fa5ef4fa4e53d605e6bce9d788960a80642de
parentApplication: use proper completablefuture for backend (diff)
downloadwireguard-android-9652fe99df68db5c483ea8e170f6e09f06a5e0d1.tar.xz
wireguard-android-9652fe99df68db5c483ea8e170f6e09f06a5e0d1.zip
TunnelDetailFragment now restores state correctly after process death
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--app/src/main/java/com/wireguard/android/activity/BaseActivity.java13
-rw-r--r--app/src/main/java/com/wireguard/android/backend/GoBackend.java11
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java36
-rw-r--r--app/src/main/java/com/wireguard/android/model/TunnelManager.java18
-rw-r--r--app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java5
-rw-r--r--app/src/main/java/com/wireguard/util/KeyedList.java4
-rw-r--r--app/src/main/java/com/wireguard/util/SortedKeyedList.java4
7 files changed, 57 insertions, 34 deletions
diff --git a/app/src/main/java/com/wireguard/android/activity/BaseActivity.java b/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
index 51357d89..57c70367 100644
--- a/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
@@ -13,7 +13,6 @@ import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.model.Tunnel;
-import com.wireguard.android.model.TunnelManager;
import java.util.Objects;
@@ -39,15 +38,17 @@ public abstract class BaseActivity extends ThemeChangeAwareActivity {
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
// Restore the saved tunnel if there is one; otherwise grab it from the arguments.
- String savedTunnelName = null;
+ final String savedTunnelName;
if (savedInstanceState != null)
savedTunnelName = savedInstanceState.getString(KEY_SELECTED_TUNNEL);
else if (getIntent() != null)
savedTunnelName = getIntent().getStringExtra(KEY_SELECTED_TUNNEL);
- if (savedTunnelName != null) {
- final TunnelManager tunnelManager = Application.getTunnelManager();
- selectedTunnel = tunnelManager.getTunnels().get(savedTunnelName);
- }
+ else
+ savedTunnelName = null;
+
+ if (savedTunnelName != null)
+ Application.getTunnelManager().getTunnels()
+ .thenAccept(tunnels -> setSelectedTunnel(tunnels.get(savedTunnelName)));
// The selected tunnel must be set before the superclass method recreates fragments.
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/wireguard/android/backend/GoBackend.java b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
index a075913f..605f00eb 100644
--- a/app/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -240,10 +240,13 @@ public final class GoBackend implements Backend {
@Override
public void onDestroy() {
- for (final Tunnel tunnel : Application.getTunnelManager().getTunnels()) {
- if (tunnel != null && tunnel.getState() != State.DOWN)
- tunnel.setState(State.DOWN);
- }
+ Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
+ for (final Tunnel tunnel : tunnels) {
+ if (tunnel != null && tunnel.getState() != State.DOWN)
+ tunnel.setState(State.DOWN);
+ }
+ });
+
vpnService = vpnService.newIncompleteFuture();
super.onDestroy();
}
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
index e2291f9c..7258f0a0 100644
--- a/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
@@ -313,7 +313,7 @@ public class TunnelListFragment extends BaseFragment {
}
binding.setFragment(this);
- binding.setTunnels(Application.getTunnelManager().getTunnels());
+ Application.getTunnelManager().getTunnels().thenAccept(binding::setTunnels);
binding.setRowConfigurationHandler((ObservableKeyedRecyclerViewAdapter.RowConfigurationHandler<TunnelListItemBinding, Tunnel>) (binding, tunnel, position) -> {
binding.setFragment(this);
binding.getRoot().setOnClickListener(clicked -> {
@@ -341,25 +341,29 @@ public class TunnelListFragment extends BaseFragment {
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_delete:
- final Collection<Tunnel> tunnelsToDelete = new ArrayList<>();
- for (final Integer position : checkedItems) {
- tunnelsToDelete.add(Application.getTunnelManager().getTunnels().get(position));
- }
-
- final CompletableFuture[] futures = StreamSupport.stream(tunnelsToDelete)
- .map(Tunnel::delete)
- .toArray(CompletableFuture[]::new);
- CompletableFuture.allOf(futures)
- .thenApply(x -> futures.length)
- .whenComplete(TunnelListFragment.this::onTunnelDeletionFinished);
-
+ final Iterable<Integer> copyCheckedItems = new HashSet<>(checkedItems);
+ Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
+ final Collection<Tunnel> tunnelsToDelete = new ArrayList<>();
+ for (final Integer position : copyCheckedItems)
+ tunnelsToDelete.add(tunnels.get(position));
+
+ final CompletableFuture[] futures = StreamSupport.stream(tunnelsToDelete)
+ .map(Tunnel::delete)
+ .toArray(CompletableFuture[]::new);
+ CompletableFuture.allOf(futures)
+ .thenApply(x -> futures.length)
+ .whenComplete(TunnelListFragment.this::onTunnelDeletionFinished);
+
+ });
checkedItems.clear();
mode.finish();
return true;
case R.id.menu_action_select_all:
- for (int i = 0; i < Application.getTunnelManager().getTunnels().size(); ++i) {
- setItemChecked(i, true);
- }
+ Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
+ for (int i = 0; i < tunnels.size(); ++i) {
+ setItemChecked(i, true);
+ }
+ });
return true;
default:
return false;
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 f7b18c07..0032724e 100644
--- a/app/src/main/java/com/wireguard/android/model/TunnelManager.java
+++ b/app/src/main/java/com/wireguard/android/model/TunnelManager.java
@@ -19,7 +19,6 @@ import com.wireguard.android.configStore.ConfigStore;
import com.wireguard.android.model.Tunnel.State;
import com.wireguard.android.model.Tunnel.Statistics;
import com.wireguard.android.util.ExceptionLoggers;
-import com.wireguard.android.util.ObservableKeyedList;
import com.wireguard.android.util.ObservableSortedKeyedArrayList;
import com.wireguard.android.util.ObservableSortedKeyedList;
import com.wireguard.config.Config;
@@ -47,6 +46,7 @@ public final class TunnelManager extends BaseObservable {
private static final String KEY_RUNNING_TUNNELS = "enabled_configs";
private final ConfigStore configStore;
+ private final CompletableFuture<ObservableSortedKeyedList<String, Tunnel>> completableTunnels = new CompletableFuture<>();
private final ObservableSortedKeyedList<String, Tunnel> tunnels = new ObservableSortedKeyedArrayList<>(COMPARATOR);
@Nullable private Tunnel lastUsedTunnel;
private boolean haveLoaded;
@@ -121,8 +121,8 @@ public final class TunnelManager extends BaseObservable {
.thenApply(tunnel::onStatisticsChanged);
}
- public ObservableKeyedList<String, Tunnel> getTunnels() {
- return tunnels;
+ public CompletableFuture<ObservableSortedKeyedList<String, Tunnel>> getTunnels() {
+ return completableTunnels;
}
public void onCreate() {
@@ -152,6 +152,8 @@ public final class TunnelManager extends BaseObservable {
f.completeExceptionally(t);
}
});
+
+ completableTunnels.complete(tunnels);
}
public void refreshTunnelStates() {
@@ -285,10 +287,12 @@ public final class TunnelManager extends BaseObservable {
final String tunnelName = intent.getStringExtra("tunnel");
if (tunnelName == null)
return;
- final Tunnel tunnel = manager.getTunnels().get(tunnelName);
- if (tunnel == null)
- return;
- manager.setTunnelState(tunnel, state);
+ manager.getTunnels().thenAccept(tunnels -> {
+ final Tunnel tunnel = tunnels.get(tunnelName);
+ if (tunnel == null)
+ return;
+ manager.setTunnelState(tunnel, state);
+ });
}
}
}
diff --git a/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java b/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
index a1477214..140cffa3 100644
--- a/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
@@ -48,7 +48,10 @@ public class ZipExporterPreference extends Preference {
}
private void exportZip() {
- final List<Tunnel> tunnels = new ArrayList<>(Application.getTunnelManager().getTunnels());
+ Application.getTunnelManager().getTunnels().thenAccept(this::exportZip);
+ }
+
+ private void exportZip(final List<Tunnel> tunnels) {
final List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size());
for (final Tunnel tunnel : tunnels)
futureConfigs.add(tunnel.getConfigAsync().toCompletableFuture());
diff --git a/app/src/main/java/com/wireguard/util/KeyedList.java b/app/src/main/java/com/wireguard/util/KeyedList.java
index c4ee975e..aab8ff21 100644
--- a/app/src/main/java/com/wireguard/util/KeyedList.java
+++ b/app/src/main/java/com/wireguard/util/KeyedList.java
@@ -5,6 +5,8 @@
package com.wireguard.util;
+import android.support.annotation.Nullable;
+
import java.util.Collection;
import java.util.List;
@@ -18,8 +20,10 @@ public interface KeyedList<K, E extends Keyed<? extends K>> extends List<E> {
boolean containsKey(K key);
+ @Nullable
E get(K key);
+ @Nullable
E getLast(K key);
int indexOfKey(K key);
diff --git a/app/src/main/java/com/wireguard/util/SortedKeyedList.java b/app/src/main/java/com/wireguard/util/SortedKeyedList.java
index f166cd92..a57e9739 100644
--- a/app/src/main/java/com/wireguard/util/SortedKeyedList.java
+++ b/app/src/main/java/com/wireguard/util/SortedKeyedList.java
@@ -5,6 +5,8 @@
package com.wireguard.util;
+import android.support.annotation.Nullable;
+
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
@@ -17,10 +19,12 @@ import java.util.Set;
public interface SortedKeyedList<K, E extends Keyed<? extends K>> extends KeyedList<K, E> {
Comparator<? super K> comparator();
+ @Nullable
K firstKey();
Set<K> keySet();
+ @Nullable
K lastKey();
Collection<E> values();