Convert the list of tunnels to a KeyedObservableList
Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
parent
c73287f64b
commit
ff0bb081a0
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
}
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<String, Tunnel>" />
|
||||
</data>
|
||||
|
||||
<com.commonsware.cwac.crossport.design.widget.CoordinatorLayout
|
||||
|
@ -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<String, Tunnel>" />
|
||||
|
||||
<variable
|
||||
name="key"
|
||||
|
Loading…
Reference in New Issue
Block a user