diff options
11 files changed, 382 insertions, 147 deletions
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java index e236da71..5592c28a 100644 --- a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java +++ b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java @@ -10,6 +10,7 @@ import android.view.ViewGroup; import com.wireguard.android.R; import com.wireguard.android.databinding.TunnelDetailFragmentBinding; import com.wireguard.android.model.Tunnel; +import com.wireguard.config.Config; /** * Fragment that shows details about a specific tunnel. @@ -18,6 +19,7 @@ import com.wireguard.android.model.Tunnel; public class TunnelDetailFragment extends BaseFragment { private TunnelDetailFragmentBinding binding; private boolean isViewStateRestored; + private String originalName; @Override public void onCreate(final Bundle savedInstanceState) { @@ -45,16 +47,34 @@ public class TunnelDetailFragment extends BaseFragment { super.onDestroyView(); } + private void onConfigLoaded(Config config) { + binding.setConfig(new Config.Observable(config, originalName)); + } + @Override public void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) { - if (binding != null && isViewStateRestored) + if (binding != null && isViewStateRestored) { binding.setTunnel(newTunnel); + if (newTunnel == null) + binding.setConfig(null); + else { + originalName = newTunnel.getName(); + newTunnel.getConfigAsync().thenAccept(this::onConfigLoaded); + } + } } @Override public void onViewStateRestored(final Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); - binding.setTunnel(getSelectedTunnel()); + Tunnel tunnel = getSelectedTunnel(); + binding.setTunnel(tunnel); + if (tunnel == null) + binding.setConfig(null); + else { + originalName = tunnel.getName(); + tunnel.getConfigAsync().thenAccept(this::onConfigLoaded); + } isViewStateRestored = true; } } diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java index fdb5fc20..f3316490 100644 --- a/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java +++ b/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java @@ -2,7 +2,6 @@ package com.wireguard.android.fragment; import android.app.Activity; import android.content.Context; -import android.databinding.ObservableField; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -31,11 +30,9 @@ import com.wireguard.config.Config; public class TunnelEditorFragment extends BaseFragment { private static final String KEY_LOCAL_CONFIG = "local_config"; - private static final String KEY_LOCAL_NAME = "local_name"; private static final String KEY_ORIGINAL_NAME = "original_name"; private static final String TAG = "WireGuard/" + TunnelEditorFragment.class.getSimpleName(); - private final ObservableField<String> localName = new ObservableField<>(""); private TunnelEditorFragmentBinding binding; private boolean isViewStateRestored; private Config localConfig = new Config(); @@ -56,7 +53,7 @@ public class TunnelEditorFragment extends BaseFragment { private void onConfigLoaded(final Config config) { localConfig = copyParcelable(config); if (binding != null && isViewStateRestored) - binding.setConfig(localConfig); + binding.setConfig(new Config.Observable(localConfig, originalName)); } private void onConfigSaved(@SuppressWarnings("unused") final Config config, @@ -82,20 +79,17 @@ public class TunnelEditorFragment extends BaseFragment { super.onCreate(savedInstanceState); if (savedInstanceState != null) { localConfig = savedInstanceState.getParcelable(KEY_LOCAL_CONFIG); - localName.set(savedInstanceState.getString(KEY_LOCAL_NAME)); originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME); } // Erase the remains of creating or editing a different tunnel. if (getSelectedTunnel() != null && !getSelectedTunnel().getName().equals(originalName)) { // The config must be loaded asynchronously since it's not an observable property. localConfig = null; - getSelectedTunnel().getConfigAsync().thenAccept(this::onConfigLoaded); originalName = getSelectedTunnel().getName(); - localName.set(originalName); + getSelectedTunnel().getConfigAsync().thenAccept(this::onConfigLoaded); } else if (getSelectedTunnel() == null && originalName != null) { localConfig = new Config(); originalName = null; - localName.set(""); } localTunnel = getSelectedTunnel(); setHasOptionsMenu(true); @@ -147,14 +141,26 @@ public class TunnelEditorFragment extends BaseFragment { switch (item.getItemId()) { case R.id.menu_action_save: final Tunnel selectedTunnel = getSelectedTunnel(); + if (localConfig != null) { + try { + binding.getConfig().commitData(localConfig); + } catch (Exception e) { + final String error = ExceptionLoggers.unwrap(e).getMessage(); + final String message = getString(R.string.config_save_error, localTunnel.getName(), error); + Log.e(TAG, message, e); + final CoordinatorLayout container = binding.mainContainer; + Snackbar.make(container, error, Snackbar.LENGTH_LONG).show(); + return false; + } + } if (selectedTunnel == null) { - Log.d(TAG, "Attempting to create new tunnel " + localName.get()); + Log.d(TAG, "Attempting to create new tunnel " + binding.getConfig().getName()); final TunnelManager manager = Application.getComponent().getTunnelManager(); - manager.create(localName.get(), localConfig) + manager.create(binding.getConfig().getName(), localConfig) .whenComplete(this::onTunnelCreated); - } else if (!selectedTunnel.getName().equals(localName.get())) { - Log.d(TAG, "Attempting to rename tunnel to " + localName.get()); - selectedTunnel.setName(localName.get()) + } else if (!selectedTunnel.getName().equals(binding.getConfig().getName())) { + Log.d(TAG, "Attempting to rename tunnel to " + binding.getConfig().getName()); + selectedTunnel.setName(binding.getConfig().getName()) .whenComplete(this::onTunnelRenamed); } else if (localConfig != null) { Log.d(TAG, "Attempting to save config of " + selectedTunnel.getName()); @@ -170,7 +176,6 @@ public class TunnelEditorFragment extends BaseFragment { @Override public void onSaveInstanceState(final Bundle outState) { outState.putParcelable(KEY_LOCAL_CONFIG, localConfig); - outState.putString(KEY_LOCAL_NAME, localName.get()); outState.putString(KEY_ORIGINAL_NAME, originalName); super.onSaveInstanceState(outState); } @@ -181,15 +186,13 @@ public class TunnelEditorFragment extends BaseFragment { if (newTunnel != null) { // The config must be loaded asynchronously since it's not an observable property. localConfig = null; - newTunnel.getConfigAsync().thenAccept(this::onConfigLoaded); originalName = newTunnel.getName(); - localName.set(originalName); + newTunnel.getConfigAsync().thenAccept(this::onConfigLoaded); } else { localConfig = new Config(); if (binding != null && isViewStateRestored) - binding.setConfig(localConfig); + binding.setConfig(new Config.Observable(localConfig, "")); originalName = null; - localName.set(""); } localTunnel = newTunnel; } @@ -234,8 +237,9 @@ public class TunnelEditorFragment extends BaseFragment { @Override public void onViewStateRestored(final Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); - binding.setConfig(localConfig); - binding.setName(localName); + if (localConfig == null) + localConfig = new Config(); + binding.setConfig(new Config.Observable(localConfig, originalName)); isViewStateRestored = true; } } diff --git a/app/src/main/java/com/wireguard/config/Attribute.java b/app/src/main/java/com/wireguard/config/Attribute.java index c98588b2..695caeda 100644 --- a/app/src/main/java/com/wireguard/config/Attribute.java +++ b/app/src/main/java/com/wireguard/config/Attribute.java @@ -54,6 +54,8 @@ enum Attribute { } public static String[] stringToList(final String string) { + if (string == null) + return new String[0]; return string.trim().split("\\s*,\\s*"); } diff --git a/app/src/main/java/com/wireguard/config/Config.java b/app/src/main/java/com/wireguard/config/Config.java index a3341d5f..e4731a0c 100644 --- a/app/src/main/java/com/wireguard/config/Config.java +++ b/app/src/main/java/com/wireguard/config/Config.java @@ -1,6 +1,9 @@ package com.wireguard.config; +import com.android.databinding.library.baseAdapters.BR; + import android.databinding.BaseObservable; +import android.databinding.Bindable; import android.databinding.ObservableArrayList; import android.databinding.ObservableList; import android.os.Parcel; @@ -11,12 +14,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; /** * Represents a wg-quick configuration file, its name, and its connection state. */ -public class Config extends BaseObservable implements Parcelable { +public class Config implements Parcelable { public static final Creator<Config> CREATOR = new Creator<Config>() { @Override public Config createFromParcel(final Parcel in) { @@ -29,8 +34,59 @@ public class Config extends BaseObservable implements Parcelable { } }; + public static class Observable extends BaseObservable { + private String name; + private Interface.Observable observableInterface; + private ObservableList<Peer.Observable> observablePeers; + + + public Observable(Config parent, String name) { + this.name = name; + loadData(parent); + } + + public void loadData(Config parent) { + this.observableInterface = new Interface.Observable(parent.interfaceSection); + this.observablePeers = new ObservableArrayList<>(); + for (Peer peer : parent.getPeers()) + this.observablePeers.add(new Peer.Observable(peer)); + } + + public void commitData(Config parent) { + this.observableInterface.commitData(parent.interfaceSection); + List<Peer> newPeers = new ArrayList<>(this.observablePeers.size()); + for (Peer.Observable observablePeer : this.observablePeers) { + Peer peer = new Peer(); + observablePeer.commitData(peer); + newPeers.add(peer); + } + parent.peers = newPeers; + notifyChange(); + } + + @Bindable + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + notifyPropertyChanged(BR.name); + } + + @Bindable + public Interface.Observable getInterfaceSection() { + return observableInterface; + } + + @Bindable + public ObservableList<Peer.Observable> getPeers() { + return observablePeers; + } + } + private final Interface interfaceSection; - private final ObservableList<Peer> peers = new ObservableArrayList<>(); + private List<Peer> peers = new ArrayList<>(); public Config() { interfaceSection = new Interface(); @@ -83,7 +139,7 @@ public class Config extends BaseObservable implements Parcelable { return interfaceSection; } - public ObservableList<Peer> getPeers() { + public List<Peer> getPeers() { return peers; } diff --git a/app/src/main/java/com/wireguard/config/IPCidr.java b/app/src/main/java/com/wireguard/config/IPCidr.java index 07fccad4..aeb5fb36 100644 --- a/app/src/main/java/com/wireguard/config/IPCidr.java +++ b/app/src/main/java/com/wireguard/config/IPCidr.java @@ -6,7 +6,6 @@ import android.os.Parcelable; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.UnknownHostException; public class IPCidr implements Parcelable { InetAddress address; diff --git a/app/src/main/java/com/wireguard/config/Interface.java b/app/src/main/java/com/wireguard/config/Interface.java index 03121072..2ed2b4e6 100644 --- a/app/src/main/java/com/wireguard/config/Interface.java +++ b/app/src/main/java/com/wireguard/config/Interface.java @@ -10,7 +10,6 @@ import com.wireguard.crypto.KeyEncoding; import com.wireguard.crypto.Keypair; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.LinkedList; import java.util.List; @@ -18,7 +17,7 @@ import java.util.List; * Represents the configuration for a WireGuard interface (an [Interface] block). */ -public class Interface extends BaseObservable implements Parcelable { +public class Interface implements Parcelable { public static final Creator<Interface> CREATOR = new Creator<Interface>() { @Override public Interface createFromParcel(final Parcel in) { @@ -31,12 +30,114 @@ public class Interface extends BaseObservable implements Parcelable { } }; + public static class Observable extends BaseObservable { + private String addresses; + private String dnses; + private String publicKey; + private String privateKey; + private String listenPort; + private String mtu; + + public Observable(Interface parent) { + loadData(parent); + } + + public void loadData(Interface parent) { + this.addresses = parent.getAddressString(); + this.dnses = parent.getDnsString(); + this.publicKey = parent.getPublicKey(); + this.privateKey = parent.getPrivateKey(); + this.listenPort = parent.getListenPortString(); + this.mtu = parent.getMtuString(); + } + + public void commitData(Interface parent) { + parent.setAddressString(this.addresses); + parent.setDnsString(this.dnses); + parent.setPrivateKey(this.privateKey); + parent.setListenPortString(this.listenPort); + parent.setMtuString(this.mtu); + loadData(parent); + notifyChange(); + } + + @Bindable + public String getAddresses() { + return addresses; + } + + public void setAddresses(String addresses) { + this.addresses = addresses; + notifyPropertyChanged(BR.addresses); + } + + @Bindable + public String getDnses() { + return dnses; + } + + public void setDnses(String dnses) { + this.dnses = dnses; + notifyPropertyChanged(BR.dnses); + } + + @Bindable + public String getPublicKey() { + return publicKey; + } + + @Bindable + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + + try { + this.publicKey = new Keypair(privateKey).getPublicKey(); + } catch (IllegalArgumentException ignored) { + this.publicKey = ""; + } + + notifyPropertyChanged(BR.privateKey); + notifyPropertyChanged(BR.publicKey); + } + + public void generateKeypair() { + Keypair keypair = new Keypair(); + privateKey = keypair.getPrivateKey(); + publicKey = keypair.getPublicKey(); + notifyPropertyChanged(BR.privateKey); + notifyPropertyChanged(BR.publicKey); + } + + @Bindable + public String getListenPort() { + return listenPort; + } + + public void setListenPort(String listenPort) { + this.listenPort = listenPort; + notifyPropertyChanged(BR.listenPort); + } + + @Bindable + public String getMtu() { + return mtu; + } + + public void setMtu(String mtu) { + this.mtu = mtu; + notifyPropertyChanged(BR.mtu); + } + } + private List<IPCidr> addressList; private List<InetAddress> dnsList; private Keypair keypair; private int listenPort; private int mtu; - private String privateKey; public Interface() { addressList = new LinkedList<>(); @@ -63,76 +164,63 @@ public class Interface extends BaseObservable implements Parcelable { return 0; } - public void generateKeypair() { - keypair = new Keypair(); - privateKey = keypair.getPrivateKey(); - notifyPropertyChanged(BR.privateKey); - notifyPropertyChanged(BR.publicKey); - } - - @Bindable - public String getAddressString() { + private String getAddressString() { if (addressList.isEmpty()) return null; return Attribute.listToString(addressList); } - @Bindable public IPCidr[] getAddresses() { return addressList.toArray(new IPCidr[addressList.size()]); } - public List<String> getDnsStrings() { + private List<String> getDnsStrings() { List<String> strings = new LinkedList<>(); for (final InetAddress addr : dnsList) strings.add(addr.getHostAddress()); return strings; } - @Bindable - public String getDnsString() { + private String getDnsString() { if (dnsList.isEmpty()) return null; return Attribute.listToString(getDnsStrings()); } - @Bindable public InetAddress[] getDnses() { return dnsList.toArray(new InetAddress[dnsList.size()]); } - @Bindable public int getListenPort() { return listenPort; } - @Bindable - public String getListenPortString() { + private String getListenPortString() { if (listenPort == 0) return null; return new Integer(listenPort).toString(); } - @Bindable public int getMtu() { return mtu; } - @Bindable - public String getMtuString() { + private String getMtuString() { if (mtu == 0) return null; return new Integer(mtu).toString(); } - @Bindable public String getPrivateKey() { - return privateKey; + if (keypair == null) + return null; + return keypair.getPrivateKey(); } - @Bindable public String getPublicKey() { - return keypair != null ? keypair.getPublicKey() : null; + if (keypair == null) + return null; + return keypair.getPublicKey(); } public void parse(final String line) { @@ -151,7 +239,7 @@ public class Interface extends BaseObservable implements Parcelable { throw new IllegalArgumentException(line); } - public void addAddresses(String[] addresses) { + private void addAddresses(String[] addresses) { if (addresses != null && addresses.length > 0) { for (final String addr : addresses) { if (addr.isEmpty()) @@ -159,74 +247,55 @@ public class Interface extends BaseObservable implements Parcelable { this.addressList.add(new IPCidr(addr)); } } - notifyPropertyChanged(BR.addresses); - notifyPropertyChanged(BR.addressString); - } - public void setAddressString(final String addressString) { + private void setAddressString(final String addressString) { this.addressList.clear(); addAddresses(Attribute.stringToList(addressString)); } - public void addDnses(String[] dnses) { + private void addDnses(String[] dnses) { if (dnses != null && dnses.length > 0) { for (final String dns : dnses) { this.dnsList.add(Attribute.parseIPString(dns)); } } - notifyPropertyChanged(BR.dnses); - notifyPropertyChanged(BR.dnsString); - } - public void setDnsString(final String dnsString) { + private void setDnsString(final String dnsString) { this.dnsList.clear(); addDnses(Attribute.stringToList(dnsString)); } - public void setListenPort(int listenPort) { + private void setListenPort(int listenPort) { this.listenPort = listenPort; - notifyPropertyChanged(BR.listenPort); - notifyPropertyChanged(BR.listenPortString); } - public void setListenPortString(final String port) { + private void setListenPortString(final String port) { if (port != null && !port.isEmpty()) setListenPort(Integer.parseInt(port, 10)); else setListenPort(0); } - public void setMtu(int mtu) { + private void setMtu(int mtu) { this.mtu = mtu; - notifyPropertyChanged(BR.mtu); - notifyPropertyChanged(BR.mtuString); } - public void setMtuString(final String mtu) { + private void setMtuString(final String mtu) { if (mtu != null && !mtu.isEmpty()) setMtu(Integer.parseInt(mtu, 10)); else setMtu(0); } - public void setPrivateKey(String privateKey) { + private void setPrivateKey(String privateKey) { if (privateKey != null && privateKey.isEmpty()) privateKey = null; - this.privateKey = privateKey; - if (privateKey != null && privateKey.length() == KeyEncoding.KEY_LENGTH_BASE64) { - try { - keypair = new Keypair(privateKey); - } catch (final IllegalArgumentException e) { - keypair = null; - throw e; - } - } else { + if (privateKey == null) keypair = null; - } - notifyPropertyChanged(BR.privateKey); - notifyPropertyChanged(BR.publicKey); + else + keypair = new Keypair(privateKey); } @Override @@ -240,8 +309,8 @@ public class Interface extends BaseObservable implements Parcelable { sb.append(Attribute.LISTEN_PORT.composeWith(listenPort)); if (mtu != 0) sb.append(Attribute.MTU.composeWith(mtu)); - if (privateKey != null) - sb.append(Attribute.PRIVATE_KEY.composeWith(privateKey)); + if (keypair != null) + sb.append(Attribute.PRIVATE_KEY.composeWith(keypair.getPrivateKey())); return sb.toString(); } @@ -253,6 +322,6 @@ public class Interface extends BaseObservable implements Parcelable { dest.writeByteArray(addr.getAddress()); dest.writeInt(listenPort); dest.writeInt(mtu); - dest.writeString(privateKey); + dest.writeString(keypair == null ? "" : keypair.getPrivateKey()); } } diff --git a/app/src/main/java/com/wireguard/config/Peer.java b/app/src/main/java/com/wireguard/config/Peer.java index 9895f447..5c506b36 100644 --- a/app/src/main/java/com/wireguard/config/Peer.java +++ b/app/src/main/java/com/wireguard/config/Peer.java @@ -6,6 +6,7 @@ import android.os.Parcel; import android.os.Parcelable; import com.android.databinding.library.baseAdapters.BR; +import com.wireguard.crypto.KeyEncoding; import java.net.Inet6Address; import java.net.InetSocketAddress; @@ -19,7 +20,7 @@ import java.util.List; * Represents the configuration for a WireGuard peer (a [Peer] block). */ -public class Peer extends BaseObservable implements Parcelable { +public class Peer implements Parcelable { public static final Creator<Peer> CREATOR = new Creator<Peer>() { @Override public Peer createFromParcel(final Parcel in) { @@ -32,6 +33,92 @@ public class Peer extends BaseObservable implements Parcelable { } }; + public static class Observable extends BaseObservable { + private String allowedIPs; + private String endpoint; + private String persistentKeepalive; + private String preSharedKey; + private String publicKey; + + + public Observable(Peer parent) { + loadData(parent); + } + public static Observable newInstance() { + return new Observable(new Peer()); + } + + public void loadData(Peer parent) { + this.allowedIPs = parent.getAllowedIPsString(); + this.endpoint = parent.getEndpointString(); + this.persistentKeepalive = parent.getPersistentKeepaliveString(); + this.preSharedKey = parent.getPreSharedKey(); + this.publicKey = parent.getPublicKey(); + } + + public void commitData(Peer parent) { + parent.setAllowedIPsString(this.allowedIPs); + parent.setEndpointString(this.endpoint); + parent.setPersistentKeepaliveString(this.persistentKeepalive); + parent.setPreSharedKey(this.preSharedKey); + parent.setPublicKey(this.publicKey); + if (parent.getPublicKey() == null) + throw new IllegalArgumentException("Peer public key may not be empty"); + loadData(parent); + notifyChange(); + } + + @Bindable + public String getAllowedIPs() { + return allowedIPs; + } + + public void setAllowedIPs(String allowedIPs) { + this.allowedIPs = allowedIPs; + notifyPropertyChanged(BR.allowedIPs); + } + + @Bindable + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + notifyPropertyChanged(BR.endpoint); + } + + @Bindable + public String getPersistentKeepalive() { + return persistentKeepalive; + } + + public void setPersistentKeepalive(String persistentKeepalive) { + this.persistentKeepalive = persistentKeepalive; + notifyPropertyChanged(BR.persistentKeepalive); + } + + @Bindable + public String getPreSharedKey() { + return preSharedKey; + } + + public void setPreSharedKey(String preSharedKey) { + this.preSharedKey = preSharedKey; + notifyPropertyChanged(BR.preSharedKey); + } + + @Bindable + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + notifyPropertyChanged(BR.publicKey); + } + } + private List<IPCidr> allowedIPsList; private InetSocketAddress endpoint; private int persistentKeepalive; @@ -57,35 +144,27 @@ public class Peer extends BaseObservable implements Parcelable { publicKey = null; } - public static Peer newInstance() { - return new Peer(); - } - @Override public int describeContents() { return 0; } - @Bindable - public String getAllowedIPsString() { + private String getAllowedIPsString() { if (allowedIPsList.isEmpty()) return null; return Attribute.listToString(allowedIPsList); } - @Bindable public IPCidr[] getAllowedIPs() { return allowedIPsList.toArray(new IPCidr[allowedIPsList.size()]); } - @Bindable public InetSocketAddress getEndpoint() { return endpoint; } - @Bindable - public String getEndpointString() { + private String getEndpointString() { if (endpoint == null) return null; return String.format("%s:%d", endpoint.getHostString(), endpoint.getPort()); @@ -103,24 +182,20 @@ public class Peer extends BaseObservable implements Parcelable { return String.format("%s:%d", endpoint.getAddress().getHostAddress(), endpoint.getPort()); } - @Bindable public int getPersistentKeepalive() { return persistentKeepalive; } - @Bindable - public String getPersistentKeepaliveString() { + private String getPersistentKeepaliveString() { if (persistentKeepalive == 0) return null; return new Integer(persistentKeepalive).toString(); } - @Bindable public String getPreSharedKey() { return preSharedKey; } - @Bindable public String getPublicKey() { return publicKey; } @@ -141,28 +216,24 @@ public class Peer extends BaseObservable implements Parcelable { throw new IllegalArgumentException(line); } - public void addAllowedIPs(String[] allowedIPs) { + private void addAllowedIPs(String[] allowedIPs) { if (allowedIPs != null && allowedIPs.length > 0) { for (final String allowedIP : allowedIPs) { this.allowedIPsList.add(new IPCidr(allowedIP)); } } - notifyPropertyChanged(BR.allowedIPs); - notifyPropertyChanged(BR.allowedIPsString); } - public void setAllowedIPsString(final String allowedIPsString) { + private void setAllowedIPsString(final String allowedIPsString) { this.allowedIPsList.clear(); addAllowedIPs(Attribute.stringToList(allowedIPsString)); } - public void setEndpoint(InetSocketAddress endpoint) { + private void setEndpoint(InetSocketAddress endpoint) { this.endpoint = endpoint; - notifyPropertyChanged(BR.endpoint); - notifyPropertyChanged(BR.endpointString); } - public void setEndpointString(final String endpoint) { + private void setEndpointString(final String endpoint) { if (endpoint != null && !endpoint.isEmpty()) { InetSocketAddress constructedEndpoint; if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1) @@ -179,31 +250,31 @@ public class Peer extends BaseObservable implements Parcelable { setEndpoint(null); } - public void setPersistentKeepalive(int persistentKeepalive) { + private void setPersistentKeepalive(int persistentKeepalive) { this.persistentKeepalive = persistentKeepalive; - notifyPropertyChanged(BR.persistentKeepalive); - notifyPropertyChanged(BR.persistentKeepaliveString); } - public void setPersistentKeepaliveString(String persistentKeepalive) { + private void setPersistentKeepaliveString(String persistentKeepalive) { if (persistentKeepalive != null && !persistentKeepalive.isEmpty()) setPersistentKeepalive(Integer.parseInt(persistentKeepalive, 10)); else setPersistentKeepalive(0); } - public void setPreSharedKey(String preSharedKey) { + private void setPreSharedKey(String preSharedKey) { if (preSharedKey != null && preSharedKey.isEmpty()) preSharedKey = null; + if (preSharedKey != null) + KeyEncoding.keyFromBase64(preSharedKey); this.preSharedKey = preSharedKey; - notifyPropertyChanged(BR.preSharedKey); } - public void setPublicKey(String publicKey) { + private void setPublicKey(String publicKey) { if (publicKey != null && publicKey.isEmpty()) publicKey = null; + if (publicKey != null) + KeyEncoding.keyFromBase64(publicKey); this.publicKey = publicKey; - notifyPropertyChanged(BR.publicKey); } @Override diff --git a/app/src/main/res/layout/tunnel_detail_fragment.xml b/app/src/main/res/layout/tunnel_detail_fragment.xml index 900d08ed..971d8784 100644 --- a/app/src/main/res/layout/tunnel_detail_fragment.xml +++ b/app/src/main/res/layout/tunnel_detail_fragment.xml @@ -14,6 +14,10 @@ <variable name="tunnel" type="com.wireguard.android.model.Tunnel" /> + + <variable + name="config" + type="com.wireguard.config.Config.Observable" /> </data> <ScrollView @@ -92,7 +96,25 @@ android:ellipsize="end" android:maxLines="1" android:onClick="@{ClipboardUtils::copyTextView}" - android:text="@{tunnel.config.interface.publicKey}" /> + android:text="@{config.interfaceSection.publicKey}" /> + + <TextView + android:id="@+id/addresses_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/public_key_text" + android:layout_marginTop="8dp" + android:labelFor="@+id/addresses_text" + android:text="@string/addresses" /> + + <TextView + android:id="@+id/addresses_text" + style="?android:attr/textAppearanceMedium" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/addresses_label" + android:contentDescription="@string/addresses" + android:text="@{config.interfaceSection.addresses}" /> </RelativeLayout> <LinearLayout @@ -101,7 +123,7 @@ android:layout_marginBottom="4dp" android:divider="@null" android:orientation="vertical" - app:items="@{tunnel.config.peers}" + app:items="@{config.peers}" app:layout="@{@layout/tunnel_detail_peer}" tools:ignore="UselessLeaf" /> </LinearLayout> diff --git a/app/src/main/res/layout/tunnel_detail_peer.xml b/app/src/main/res/layout/tunnel_detail_peer.xml index bde89390..d2240e31 100644 --- a/app/src/main/res/layout/tunnel_detail_peer.xml +++ b/app/src/main/res/layout/tunnel_detail_peer.xml @@ -6,12 +6,8 @@ <import type="com.wireguard.android.util.ClipboardUtils" /> <variable - name="collection" - type="android.databinding.ObservableList<com.wireguard.config.Peer>" /> - - <variable name="item" - type="com.wireguard.config.Peer" /> + type="com.wireguard.config.Peer.Observable" /> </data> <RelativeLayout @@ -69,7 +65,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/allowed_ips_label" - android:text="@{item.allowedIPsString}" /> + android:text="@{item.allowedIPs}" /> <TextView android:id="@+id/endpoint_label" @@ -86,6 +82,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/endpoint_label" - android:text="@{item.endpointString}" /> + android:text="@{item.endpoint}" /> </RelativeLayout> </layout> diff --git a/app/src/main/res/layout/tunnel_editor_fragment.xml b/app/src/main/res/layout/tunnel_editor_fragment.xml index 0d278bcb..4d56ee3e 100644 --- a/app/src/main/res/layout/tunnel_editor_fragment.xml +++ b/app/src/main/res/layout/tunnel_editor_fragment.xml @@ -15,11 +15,7 @@ <variable name="config" - type="com.wireguard.config.Config" /> - - <variable - name="name" - type="android.databinding.ObservableField<String>" /> + type="com.wireguard.config.Config.Observable" /> </data> <com.commonsware.cwac.crossport.design.widget.CoordinatorLayout @@ -71,7 +67,7 @@ android:layout_height="wrap_content" android:layout_below="@+id/interface_name_label" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={name}" + android:text="@={config.name}" app:filter="@{NameInputFilter.newInstance()}" /> <TextView @@ -91,7 +87,7 @@ android:layout_toStartOf="@+id/generate_private_key_button" android:contentDescription="@string/public_key_description" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={config.interface.privateKey}" + android:text="@={config.interfaceSection.privateKey}" app:filter="@{KeyInputFilter.newInstance()}" /> <Button @@ -101,7 +97,7 @@ android:layout_alignBottom="@id/private_key_text" android:layout_alignParentEnd="true" android:layout_below="@+id/private_key_label" - android:onClick="@{() -> config.interface.generateKeypair()}" + android:onClick="@{() -> config.interfaceSection.generateKeypair()}" android:text="@string/generate" /> <TextView @@ -124,7 +120,7 @@ android:maxLines="1" android:contentDescription="@string/public_key_description" android:onClick="@{ClipboardUtils::copyTextView}" - android:text="@{config.interface.publicKey}" /> + android:text="@{config.interfaceSection.publicKey}" /> <TextView android:id="@+id/addresses_label" @@ -144,7 +140,7 @@ android:layout_below="@+id/addresses_label" android:layout_toStartOf="@+id/listen_port_text" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={config.interface.addressString}" /> + android:text="@={config.interfaceSection.addresses}" /> <TextView android:id="@+id/listen_port_label" @@ -165,7 +161,7 @@ android:layout_alignStart="@+id/generate_private_key_button" android:hint="@string/hint_random" android:inputType="number" - android:text="@={config.interface.listenPortString}" + android:text="@={config.interfaceSection.listenPort}" android:textAlignment="center" /> <TextView @@ -186,7 +182,7 @@ android:layout_below="@+id/dns_servers_label" android:layout_toStartOf="@+id/mtu_text" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={config.interface.dnsString}" /> + android:text="@={config.interfaceSection.dnses}" /> <TextView android:id="@+id/mtu_label" @@ -207,7 +203,7 @@ android:layout_alignStart="@+id/generate_private_key_button" android:hint="@string/hint_automatic" android:inputType="number" - android:text="@={config.interface.mtuString}" + android:text="@={config.interfaceSection.mtu}" android:textAlignment="center" /> </RelativeLayout> @@ -226,7 +222,7 @@ android:layout_marginBottom="4dp" android:layout_marginEnd="4dp" android:layout_marginStart="4dp" - android:onClick="@{() -> config.peers.add(Peer.newInstance())}" + android:onClick="@{() -> config.peers.add(Peer.Observable.newInstance())}" android:text="@string/add_peer" /> </LinearLayout> </ScrollView> diff --git a/app/src/main/res/layout/tunnel_editor_peer.xml b/app/src/main/res/layout/tunnel_editor_peer.xml index cc5fe933..b6caab8a 100644 --- a/app/src/main/res/layout/tunnel_editor_peer.xml +++ b/app/src/main/res/layout/tunnel_editor_peer.xml @@ -8,11 +8,11 @@ <variable name="collection" - type="android.databinding.ObservableList<com.wireguard.config.Peer>" /> + type="android.databinding.ObservableList<com.wireguard.config.Peer.Observable>" /> <variable name="item" - type="com.wireguard.config.Peer" /> + type="com.wireguard.config.Peer.Observable" /> </data> <RelativeLayout @@ -96,7 +96,7 @@ android:layout_height="wrap_content" android:layout_below="@+id/allowed_ips_label" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={item.allowedIPsString}" /> + android:text="@={item.allowedIPs}" /> <TextView android:id="@+id/endpoint_label" @@ -116,7 +116,7 @@ android:layout_below="@+id/endpoint_label" android:layout_toStartOf="@+id/persistent_keepalive_text" android:inputType="textNoSuggestions|textVisiblePassword" - android:text="@={item.endpointString}" /> + android:text="@={item.endpoint}" /> <TextView android:id="@+id/persistent_keepalive_label" @@ -136,7 +136,7 @@ android:layout_alignStart="@+id/persistent_keepalive_label" android:hint="@string/hint_optional" android:inputType="number" - android:text="@={item.persistentKeepaliveString}" + android:text="@={item.persistentKeepalive}" android:textAlignment="center" /> </RelativeLayout> </layout> |