aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSamuel Holland <samuel@sholland.org>2018-01-06 04:04:42 -0600
committerSamuel Holland <samuel@sholland.org>2018-01-06 04:09:30 -0600
commit7434587b62a74c0d85a1e5204b38040dc9e992eb (patch)
treec89495b5eeaaa381aa292ed150420cb533495085
parentdatabinding: Add an adapter for the KeyedObservableList (diff)
downloadwireguard-android-7434587b62a74c0d85a1e5204b38040dc9e992eb.tar.xz
wireguard-android-7434587b62a74c0d85a1e5204b38040dc9e992eb.zip
Convert the list of tunnels to a KeyedObservableList
Signed-off-by: Samuel Holland <samuel@sholland.org>
-rw-r--r--app/src/main/java/com/wireguard/android/QuickTileService.java47
-rw-r--r--app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java15
-rw-r--r--app/src/main/java/com/wireguard/android/model/Tunnel.java13
-rw-r--r--app/src/main/java/com/wireguard/android/model/TunnelCollection.java10
-rw-r--r--app/src/main/java/com/wireguard/android/model/TunnelManager.java13
-rw-r--r--app/src/main/java/com/wireguard/android/preference/TunnelListPreference.java12
-rw-r--r--app/src/main/res/layout/tunnel_list_fragment.xml4
-rw-r--r--app/src/main/res/layout/tunnel_list_item.xml4
8 files changed, 73 insertions, 45 deletions
diff --git a/app/src/main/java/com/wireguard/android/QuickTileService.java b/app/src/main/java/com/wireguard/android/QuickTileService.java
index 9de4322a..10563b6e 100644
--- a/app/src/main/java/com/wireguard/android/QuickTileService.java
+++ b/app/src/main/java/com/wireguard/android/QuickTileService.java
@@ -6,7 +6,8 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.databinding.Observable;
import android.databinding.Observable.OnPropertyChangedCallback;
-import android.databinding.ObservableMap.OnMapChangedCallback;
+import android.databinding.ObservableList;
+import android.databinding.ObservableList.OnListChangedCallback;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.service.quicksettings.Tile;
@@ -19,8 +20,8 @@ import com.wireguard.android.activity.MainActivity;
import com.wireguard.android.activity.SettingsActivity;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.model.Tunnel.State;
-import com.wireguard.android.model.TunnelCollection;
import com.wireguard.android.model.TunnelManager;
+import com.wireguard.android.util.KeyedObservableList;
import java.util.Objects;
@@ -33,9 +34,8 @@ import java.util.Objects;
@TargetApi(Build.VERSION_CODES.N)
public class QuickTileService extends TileService implements OnSharedPreferenceChangeListener {
private static final String TAG = QuickTileService.class.getSimpleName();
-
+ private final OnTunnelListChangedCallback listCallback = new OnTunnelListChangedCallback();
private final OnTunnelStateChangedCallback tunnelCallback = new OnTunnelStateChangedCallback();
- private final OnTunnelMapChangedCallback tunnelMapCallback = new OnTunnelMapChangedCallback();
private SharedPreferences preferences;
private Tunnel tunnel;
private TunnelManager tunnelManager;
@@ -75,7 +75,7 @@ public class QuickTileService extends TileService implements OnSharedPreferenceC
@Override
public void onStartListening() {
preferences.registerOnSharedPreferenceChangeListener(this);
- tunnelManager.getTunnels().addOnMapChangedCallback(tunnelMapCallback);
+ tunnelManager.getTunnels().addOnListChangedCallback(listCallback);
if (tunnel != null)
tunnel.addOnPropertyChangedCallback(tunnelCallback);
updateTile();
@@ -84,7 +84,7 @@ public class QuickTileService extends TileService implements OnSharedPreferenceC
@Override
public void onStopListening() {
preferences.unregisterOnSharedPreferenceChangeListener(this);
- tunnelManager.getTunnels().removeOnMapChangedCallback(tunnelMapCallback);
+ tunnelManager.getTunnels().removeOnListChangedCallback(listCallback);
if (tunnel != null)
tunnel.removeOnPropertyChangedCallback(tunnelCallback);
}
@@ -104,7 +104,7 @@ public class QuickTileService extends TileService implements OnSharedPreferenceC
final String currentName = tunnel != null ? tunnel.getName() : null;
final String newName = preferences.getString(TunnelManager.KEY_PRIMARY_TUNNEL, null);
if (!Objects.equals(currentName, newName)) {
- final TunnelCollection tunnels = tunnelManager.getTunnels();
+ final KeyedObservableList<String, Tunnel> tunnels = tunnelManager.getTunnels();
final Tunnel newTunnel = newName != null ? tunnels.get(newName) : null;
if (tunnel != null)
tunnel.removeOnPropertyChangedCallback(tunnelCallback);
@@ -134,12 +134,35 @@ public class QuickTileService extends TileService implements OnSharedPreferenceC
tile.updateTile();
}
- private final class OnTunnelMapChangedCallback
- extends OnMapChangedCallback<TunnelCollection, String, Tunnel> {
+ private final class OnTunnelListChangedCallback
+ extends OnListChangedCallback<ObservableList<Tunnel>> {
@Override
- public void onMapChanged(final TunnelCollection sender, final String key) {
- if (!key.equals(preferences.getString(TunnelManager.KEY_PRIMARY_TUNNEL, null)))
- return;
+ public void onChanged(final ObservableList<Tunnel> sender) {
+ updateTile();
+ }
+
+ @Override
+ public void onItemRangeChanged(final ObservableList<Tunnel> sender,
+ final int positionStart, final int itemCount) {
+ updateTile();
+ }
+
+ @Override
+ public void onItemRangeInserted(final ObservableList<Tunnel> sender,
+ final int positionStart, final int itemCount) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onItemRangeMoved(final ObservableList<Tunnel> sender,
+ final int fromPosition, final int toPosition,
+ final int itemCount) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onItemRangeRemoved(final ObservableList<Tunnel> sender,
+ final int positionStart, final int itemCount) {
updateTile();
}
}
diff --git a/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java b/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java
index 072a9fdc..121c292b 100644
--- a/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java
+++ b/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java
@@ -10,6 +10,8 @@ import android.widget.ListView;
import android.widget.TextView;
import com.wireguard.android.R;
+import com.wireguard.android.util.Keyed;
+import com.wireguard.android.util.KeyedObservableList;
import com.wireguard.android.widget.ToggleSwitch;
import org.threeten.bp.Instant;
@@ -63,14 +65,15 @@ public final class BindingAdapters {
}
@BindingAdapter({"items", "layout"})
- public static <T> void setItems(final ListView view,
- final ObservableList<T> oldList, final int oldLayoutId,
- final ObservableList<T> newList, final int newLayoutId) {
+ public static <K, E extends Keyed<? extends K>>
+ void setItems(final ListView view,
+ final KeyedObservableList<K, E> oldList, final int oldLayoutId,
+ final KeyedObservableList<K, E> newList, final int newLayoutId) {
if (oldList == newList && oldLayoutId == newLayoutId)
return;
// The ListAdapter interface is not generic, so this cannot be checked.
- @SuppressWarnings("unchecked")
- ObservableListAdapter<T> adapter = (ObservableListAdapter<T>) view.getAdapter();
+ @SuppressWarnings("unchecked") KeyedObservableListAdapter<K, E> adapter =
+ (KeyedObservableListAdapter<K, E>) view.getAdapter();
// If the layout changes, any existing adapter must be replaced.
if (adapter != null && oldList != null && oldLayoutId != newLayoutId) {
adapter.setList(null);
@@ -80,7 +83,7 @@ public final class BindingAdapters {
if (newList == null || newLayoutId == 0)
return;
if (adapter == null) {
- adapter = new ObservableListAdapter<>(view.getContext(), newLayoutId, newList);
+ adapter = new KeyedObservableListAdapter<>(view.getContext(), newLayoutId, newList);
view.setAdapter(adapter);
}
// Either the list changed, or this is an entirely new listener because the layout changed.
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 b196eaa5..25bb46df 100644
--- a/app/src/main/java/com/wireguard/android/model/Tunnel.java
+++ b/app/src/main/java/com/wireguard/android/model/Tunnel.java
@@ -9,6 +9,7 @@ import com.wireguard.android.BR;
import com.wireguard.android.backend.Backend;
import com.wireguard.android.configStore.ConfigStore;
import com.wireguard.android.util.ExceptionLoggers;
+import com.wireguard.android.util.Keyed;
import com.wireguard.config.Config;
import org.threeten.bp.Instant;
@@ -23,7 +24,7 @@ import java9.util.concurrent.CompletionStage;
* Encapsulates the volatile and nonvolatile state of a WireGuard tunnel.
*/
-public class Tunnel extends BaseObservable implements Comparable<Tunnel> {
+public class Tunnel extends BaseObservable implements Keyed<String> {
public static final int NAME_MAX_LENGTH = 16;
private static final Pattern NAME_PATTERN = Pattern.compile("[a-zA-Z0-9_=+.-]{1,16}");
private static final String TAG = Tunnel.class.getSimpleName();
@@ -48,11 +49,6 @@ public class Tunnel extends BaseObservable implements Comparable<Tunnel> {
return name != null && NAME_PATTERN.matcher(name).matches();
}
- @Override
- public int compareTo(@NonNull final Tunnel tunnel) {
- return name.compareTo(tunnel.name);
- }
-
@Bindable
public Config getConfig() {
if (config == null)
@@ -66,6 +62,11 @@ public class Tunnel extends BaseObservable implements Comparable<Tunnel> {
return CompletableFuture.completedFuture(config);
}
+ @Override
+ public String getKey() {
+ return name;
+ }
+
@Bindable
public Instant getLastStateChange() {
return lastStateChange;
diff --git a/app/src/main/java/com/wireguard/android/model/TunnelCollection.java b/app/src/main/java/com/wireguard/android/model/TunnelCollection.java
deleted file mode 100644
index 38b5165a..00000000
--- a/app/src/main/java/com/wireguard/android/model/TunnelCollection.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.wireguard.android.model;
-
-import com.wireguard.android.databinding.ObservableTreeMap;
-
-/**
- * Created by samuel on 12/19/17.
- */
-
-public class TunnelCollection extends ObservableTreeMap<String, Tunnel> {
-}
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 b6f6819d..53322ab4 100644
--- a/app/src/main/java/com/wireguard/android/model/TunnelManager.java
+++ b/app/src/main/java/com/wireguard/android/model/TunnelManager.java
@@ -8,6 +8,8 @@ import com.wireguard.android.backend.Backend;
import com.wireguard.android.configStore.ConfigStore;
import com.wireguard.android.model.Tunnel.State;
import com.wireguard.android.util.ExceptionLoggers;
+import com.wireguard.android.util.KeyedObservableList;
+import com.wireguard.android.util.SortedKeyedObservableArrayList;
import com.wireguard.config.Config;
import java.util.Collections;
@@ -35,7 +37,8 @@ public final class TunnelManager {
private final Backend backend;
private final ConfigStore configStore;
private final SharedPreferences preferences;
- private final TunnelCollection tunnels = new TunnelCollection();
+ private final KeyedObservableList<String, Tunnel> tunnels =
+ new SortedKeyedObservableArrayList<>();
@Inject
public TunnelManager(final Backend backend, final ConfigStore configStore,
@@ -47,7 +50,7 @@ public final class TunnelManager {
private Tunnel add(final String name, final Config config) {
final Tunnel tunnel = new Tunnel(backend, configStore, name, config);
- tunnels.put(name, tunnel);
+ tunnels.add(tunnel);
return tunnel;
}
@@ -71,13 +74,13 @@ public final class TunnelManager {
return backend.setState(tunnel, State.DOWN)
.thenCompose(x -> configStore.delete(tunnel.getName()))
.thenAccept(x -> {
- tunnels.remove(tunnel.getName());
+ tunnels.remove(tunnel);
if (tunnel.getName().equals(preferences.getString(KEY_PRIMARY_TUNNEL, null)))
preferences.edit().remove(KEY_PRIMARY_TUNNEL).apply();
});
}
- public TunnelCollection getTunnels() {
+ public KeyedObservableList<String, Tunnel> getTunnels() {
return tunnels;
}
@@ -105,7 +108,7 @@ public final class TunnelManager {
}
public CompletionStage<Void> saveState() {
- final Set<String> runningTunnels = StreamSupport.stream(tunnels.values())
+ final Set<String> runningTunnels = StreamSupport.stream(tunnels)
.filter(tunnel -> tunnel.getState() == State.UP)
.map(Tunnel::getName)
.collect(Collectors.toUnmodifiableSet());
diff --git a/app/src/main/java/com/wireguard/android/preference/TunnelListPreference.java b/app/src/main/java/com/wireguard/android/preference/TunnelListPreference.java
index 541afa28..eefd9912 100644
--- a/app/src/main/java/com/wireguard/android/preference/TunnelListPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/TunnelListPreference.java
@@ -5,19 +5,23 @@ import android.preference.ListPreference;
import android.util.AttributeSet;
import com.wireguard.android.Application;
+import com.wireguard.android.model.Tunnel;
+import com.wireguard.android.model.TunnelManager;
-import java.util.Set;
+import java9.util.stream.StreamSupport;
/**
- * ListPreference that is automatically filled with the list of configurations.
+ * ListPreference that is automatically filled with the list of tunnels.
*/
public class TunnelListPreference extends ListPreference {
public TunnelListPreference(final Context context, final AttributeSet attrs,
final int defStyleAttr, final int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- final Set<String> entrySet = Application.getComponent().getTunnelManager().getTunnels().keySet();
- final CharSequence[] entries = entrySet.toArray(new CharSequence[entrySet.size()]);
+ final TunnelManager tunnelManager = Application.getComponent().getTunnelManager();
+ final CharSequence[] entries = StreamSupport.stream(tunnelManager.getTunnels())
+ .map(Tunnel::getName)
+ .toArray(String[]::new);
setEntries(entries);
setEntryValues(entries);
}
diff --git a/app/src/main/res/layout/tunnel_list_fragment.xml b/app/src/main/res/layout/tunnel_list_fragment.xml
index e4923d54..fa489840 100644
--- a/app/src/main/res/layout/tunnel_list_fragment.xml
+++ b/app/src/main/res/layout/tunnel_list_fragment.xml
@@ -4,13 +4,15 @@
<data>
+ <import type="com.wireguard.android.model.Tunnel" />
+
<variable
name="fragment"
type="com.wireguard.android.fragment.TunnelListFragment" />
<variable
name="tunnels"
- type="com.wireguard.android.model.TunnelCollection" />
+ type="com.wireguard.android.util.KeyedObservableList&lt;String, Tunnel&gt;" />
</data>
<com.commonsware.cwac.crossport.design.widget.CoordinatorLayout
diff --git a/app/src/main/res/layout/tunnel_list_item.xml b/app/src/main/res/layout/tunnel_list_item.xml
index c8706546..8ae0dd23 100644
--- a/app/src/main/res/layout/tunnel_list_item.xml
+++ b/app/src/main/res/layout/tunnel_list_item.xml
@@ -4,11 +4,13 @@
<data>
+ <import type="com.wireguard.android.model.Tunnel" />
+
<import type="com.wireguard.android.model.Tunnel.State" />
<variable
name="collection"
- type="com.wireguard.android.model.TunnelCollection" />
+ type="com.wireguard.android.util.KeyedObservableList&lt;String, Tunnel&gt;" />
<variable
name="key"