global: Clean up Java

Address Java and Android lints.

Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
Samuel Holland 2018-04-30 11:37:52 -05:00
parent 8e4fb91a28
commit 843003f436
13 changed files with 237 additions and 215 deletions

View File

@ -49,7 +49,7 @@ public abstract class BaseActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (Application.getComponent().getBackendType() == GoBackend.class) { if (Application.getComponent().getBackendType() == GoBackend.class) {
Intent intent = GoBackend.VpnService.prepare(this); final Intent intent = GoBackend.VpnService.prepare(this);
if (intent != null) { if (intent != null) {
startActivityForResult(intent, 0); startActivityForResult(intent, 0);
} }

View File

@ -68,7 +68,7 @@ public class MainActivity extends BaseActivity {
fragment = fragment =
((TunnelListFragment) ((TunnelListFragment)
getSupportFragmentManager().getFragments().get(0)); getSupportFragmentManager().getFragments().get(0));
} catch (ClassCastException ignored) { } catch (final ClassCastException ignored) {
} }
if (fragment == null || !(fragment.collapseActionMenu())) { if (fragment == null || !(fragment.collapseActionMenu())) {
if (!moveToState(State.ofLayer(state.layer - 1))) if (!moveToState(State.ofLayer(state.layer - 1)))

View File

@ -17,28 +17,29 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Interface for changing application-global persistent settings. * Interface for changing application-global persistent settings.
*/ */
public class SettingsActivity extends AppCompatActivity { public class SettingsActivity extends AppCompatActivity {
private HashMap<Integer, PermissionRequestCallback> permissionRequestCallbacks = new HashMap<>(); private final Map<Integer, PermissionRequestCallback> permissionRequestCallbacks = new HashMap<>();
private int permissionRequestCounter = 0; private int permissionRequestCounter;
public synchronized void ensurePermissions(String[] permissions, PermissionRequestCallback cb) { public void ensurePermissions(final String[] permissions, final PermissionRequestCallback cb) {
List<String> needPermissions = new ArrayList<>(permissions.length); final List<String> needPermissions = new ArrayList<>(permissions.length);
for (final String permission : permissions) { for (final String permission : permissions) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
needPermissions.add(permission); needPermissions.add(permission);
} }
if (needPermissions.isEmpty()) { if (needPermissions.isEmpty()) {
int[] granted = new int[permissions.length]; final int[] granted = new int[permissions.length];
Arrays.fill(granted, PackageManager.PERMISSION_GRANTED); Arrays.fill(granted, PackageManager.PERMISSION_GRANTED);
cb.done(permissions, granted); cb.done(permissions, granted);
return; return;
} }
int idx = permissionRequestCounter++; final int idx = permissionRequestCounter++;
permissionRequestCallbacks.put(idx, cb); permissionRequestCallbacks.put(idx, cb);
ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), idx); ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), idx);
} }
@ -54,7 +55,7 @@ public class SettingsActivity extends AppCompatActivity {
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home: case android.R.id.home:
finish(); finish();
@ -65,7 +66,7 @@ public class SettingsActivity extends AppCompatActivity {
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
final PermissionRequestCallback f = permissionRequestCallbacks.get(requestCode); final PermissionRequestCallback f = permissionRequestCallbacks.get(requestCode);
if (f != null) { if (f != null) {
permissionRequestCallbacks.remove(requestCode); permissionRequestCallbacks.remove(requestCode);
@ -73,7 +74,6 @@ public class SettingsActivity extends AppCompatActivity {
} }
} }
@FunctionalInterface
public interface PermissionRequestCallback { public interface PermissionRequestCallback {
void done(String[] permissions, int[] grantResults); void done(String[] permissions, int[] grantResults);
} }

View File

@ -33,11 +33,11 @@ public final class GoBackend implements Backend {
System.loadLibrary("wg-go"); System.loadLibrary("wg-go");
} }
private Context context; private final Context context;
private Tunnel currentTunnel; private Tunnel currentTunnel;
private int currentTunnelHandle = -1; private int currentTunnelHandle = -1;
public GoBackend(Context context) { public GoBackend(final Context context) {
this.context = context; this.context = context;
} }
@ -108,14 +108,14 @@ public final class GoBackend implements Backend {
if (VpnService.prepare(context) != null) if (VpnService.prepare(context) != null)
throw new Exception("VPN service not authorized by user"); throw new Exception("VPN service not authorized by user");
VpnService service; final VpnService service;
if (!vpnService.isDone()) if (!vpnService.isDone())
startVpnService(); startVpnService();
try { try {
service = vpnService.get(2, TimeUnit.SECONDS); service = vpnService.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) { } catch (final TimeoutException e) {
throw new Exception("Unable to start Android VPN service"); throw new Exception("Unable to start Android VPN service", e);
} }
if (currentTunnelHandle != -1) { if (currentTunnelHandle != -1) {
@ -124,8 +124,9 @@ public final class GoBackend implements Backend {
} }
// Build config // Build config
Formatter fmt = new Formatter(new StringBuilder());
final Interface iface = config.getInterface(); final Interface iface = config.getInterface();
final String goConfig;
try (Formatter fmt = new Formatter(new StringBuilder())) {
fmt.format("replace_peers=true\n"); fmt.format("replace_peers=true\n");
if (iface.getPrivateKey() != null) if (iface.getPrivateKey() != null)
fmt.format("private_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(iface.getPrivateKey()))); fmt.format("private_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(iface.getPrivateKey())));
@ -144,9 +145,11 @@ public final class GoBackend implements Backend {
fmt.format("allowed_ip=%s\n", addr.toString()); fmt.format("allowed_ip=%s\n", addr.toString());
} }
} }
goConfig = fmt.toString();
}
// Create the vpn tunnel with android API // Create the vpn tunnel with android API
VpnService.Builder builder = service.getBuilder(); final VpnService.Builder builder = service.getBuilder();
builder.setSession(tunnel.getName()); builder.setSession(tunnel.getName());
for (final IPCidr addr : config.getInterface().getAddresses()) for (final IPCidr addr : config.getInterface().getAddresses())
@ -166,13 +169,13 @@ public final class GoBackend implements Backend {
builder.setMtu(mtu); builder.setMtu(mtu);
builder.setBlocking(true); builder.setBlocking(true);
ParcelFileDescriptor tun = builder.establish(); final ParcelFileDescriptor tun = builder.establish();
if (tun == null) if (tun == null)
throw new Exception("Unable to create tun device"); throw new Exception("Unable to create tun device");
currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), fmt.toString()); currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig);
if (currentTunnelHandle < 0) if (currentTunnelHandle < 0)
throw new Exception("Unable to turn tunnel on (wgTurnOn return " + currentTunnelHandle + ")"); throw new Exception("Unable to turn tunnel on (wgTurnOn return " + currentTunnelHandle + ')');
currentTunnel = tunnel; currentTunnel = tunnel;

View File

@ -105,14 +105,15 @@ public final class WgQuickBackend implements Backend {
} }
final String command = String.format("wg-quick %s '%s'", state.toString().toLowerCase(), tempFile.getAbsolutePath()); final String command = String.format("wg-quick %s '%s'", state.toString().toLowerCase(), tempFile.getAbsolutePath());
final int result = rootShell.run(null, command); final int result = rootShell.run(null, command);
// noinspection ResultOfMethodCallIgnored
tempFile.delete(); tempFile.delete();
if (result != 0) if (result != 0)
throw new Exception("Unable to configure tunnel (wg-quick returned " + result + ')'); throw new Exception("Unable to configure tunnel (wg-quick returned " + result + ')');
} }
public final static class WgQuickChangeReceiver extends BroadcastReceiver { public static final class WgQuickChangeReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(final Context context, final Intent intent) {
Log.d(TAG, "Refreshing tunnel states"); Log.d(TAG, "Refreshing tunnel states");
Application.getComponent().getTunnelManager().refreshTunnelStates(); Application.getComponent().getTunnelManager().refreshTunnelStates();
} }

View File

@ -109,10 +109,10 @@ public class TunnelEditorFragment extends BaseFragment {
public boolean onOptionsItemSelected(final MenuItem item) { public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_action_save: case R.id.menu_action_save:
Config newConfig = new Config(); final Config newConfig = new Config();
try { try {
binding.getConfig().commitData(newConfig); binding.getConfig().commitData(newConfig);
} catch (Exception e) { } catch (final Exception e) {
final String error = ExceptionLoggers.unwrap(e).getMessage(); final String error = ExceptionLoggers.unwrap(e).getMessage();
final String tunnelName = tunnel == null ? binding.getConfig().getName() : tunnel.getName(); final String tunnelName = tunnel == null ? binding.getConfig().getName() : tunnel.getName();
final String message = getString(R.string.config_save_error, tunnelName, error); final String message = getString(R.string.config_save_error, tunnelName, error);
@ -202,8 +202,8 @@ public class TunnelEditorFragment extends BaseFragment {
onSelectedTunnelChanged(null, getSelectedTunnel()); onSelectedTunnelChanged(null, getSelectedTunnel());
} else { } else {
tunnel = getSelectedTunnel(); tunnel = getSelectedTunnel();
Config.Observable config = savedInstanceState.getParcelable(KEY_LOCAL_CONFIG); final Config.Observable config = savedInstanceState.getParcelable(KEY_LOCAL_CONFIG);
String originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME); final String originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME);
if (tunnel != null && !tunnel.getName().equals(originalName)) if (tunnel != null && !tunnel.getName().equals(originalName))
onSelectedTunnelChanged(null, tunnel); onSelectedTunnelChanged(null, tunnel);
else else

View File

@ -43,6 +43,7 @@ import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@ -82,7 +83,7 @@ public class TunnelListFragment extends BaseFragment {
return; return;
final ContentResolver contentResolver = activity.getContentResolver(); final ContentResolver contentResolver = activity.getContentResolver();
final List<CompletableFuture<Tunnel>> futureTunnels = new ArrayList<>(); final Collection<CompletableFuture<Tunnel>> futureTunnels = new ArrayList<>();
final List<Throwable> throwables = new ArrayList<>(); final List<Throwable> throwables = new ArrayList<>();
asyncWorker.supplyAsync(() -> { asyncWorker.supplyAsync(() -> {
final String[] columns = {OpenableColumns.DISPLAY_NAME}; final String[] columns = {OpenableColumns.DISPLAY_NAME};
@ -106,7 +107,7 @@ public class TunnelListFragment extends BaseFragment {
throw new IllegalArgumentException("File must be .conf or .zip"); throw new IllegalArgumentException("File must be .conf or .zip");
if (isZip) { if (isZip) {
ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri)); try (ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri))) {
BufferedReader reader = new BufferedReader(new InputStreamReader(zip, StandardCharsets.UTF_8)); BufferedReader reader = new BufferedReader(new InputStreamReader(zip, StandardCharsets.UTF_8));
ZipEntry entry; ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) { while ((entry = zip.getNextEntry()) != null) {
@ -132,6 +133,7 @@ public class TunnelListFragment extends BaseFragment {
if (config != null) if (config != null)
futureTunnels.add(tunnelManager.create(name, config).toCompletableFuture()); futureTunnels.add(tunnelManager.create(name, config).toCompletableFuture());
} }
}
} else { } else {
futureTunnels.add(tunnelManager.create(name, Config.from(contentResolver.openInputStream(uri))).toCompletableFuture()); futureTunnels.add(tunnelManager.create(name, Config.from(contentResolver.openInputStream(uri))).toCompletableFuture());
} }
@ -146,15 +148,15 @@ public class TunnelListFragment extends BaseFragment {
return CompletableFuture.allOf(futureTunnels.toArray(new CompletableFuture[futureTunnels.size()])); return CompletableFuture.allOf(futureTunnels.toArray(new CompletableFuture[futureTunnels.size()]));
}).whenComplete((future, exception) -> { }).whenComplete((future, exception) -> {
if (exception != null) { if (exception != null) {
this.onTunnelImportFinished(Collections.emptyList(), Collections.singletonList(exception)); onTunnelImportFinished(Collections.emptyList(), Collections.singletonList(exception));
} else { } else {
future.whenComplete((ignored1, ignored2) -> { future.whenComplete((ignored1, ignored2) -> {
ArrayList<Tunnel> tunnels = new ArrayList<>(futureTunnels.size()); final List<Tunnel> tunnels = new ArrayList<>(futureTunnels.size());
for (CompletableFuture<Tunnel> futureTunnel : futureTunnels) { for (final CompletableFuture<Tunnel> futureTunnel : futureTunnels) {
Tunnel tunnel = null; Tunnel tunnel = null;
try { try {
tunnel = futureTunnel.getNow(null); tunnel = futureTunnel.getNow(null);
} catch (Exception e) { } catch (final Exception e) {
throwables.add(e); throwables.add(e);
} }
if (tunnel != null) if (tunnel != null)
@ -240,7 +242,7 @@ public class TunnelListFragment extends BaseFragment {
} }
} }
private void onTunnelImportFinished(final List<Tunnel> tunnels, final List<Throwable> throwables) { private void onTunnelImportFinished(final List<Tunnel> tunnels, final Collection<Throwable> throwables) {
String message = null; String message = null;
for (final Throwable throwable : throwables) { for (final Throwable throwable : throwables) {

View File

@ -22,6 +22,7 @@ import com.wireguard.config.Config;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -39,7 +40,7 @@ public class ZipExporterPreference extends Preference {
private final AsyncWorker asyncWorker; private final AsyncWorker asyncWorker;
private final TunnelManager tunnelManager; private final TunnelManager tunnelManager;
private String exportedFilePath = null; private String exportedFilePath;
@SuppressWarnings({"SameParameterValue", "WeakerAccess"}) @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
public ZipExporterPreference(final Context context, final AttributeSet attrs) { public ZipExporterPreference(final Context context, final AttributeSet attrs) {
@ -49,9 +50,19 @@ public class ZipExporterPreference extends Preference {
tunnelManager = applicationComponent.getTunnelManager(); tunnelManager = applicationComponent.getTunnelManager();
} }
private static SettingsActivity getPrefActivity(final Preference preference) {
final Context context = preference.getContext();
if (context instanceof ContextThemeWrapper) {
if (((ContextThemeWrapper) context).getBaseContext() instanceof SettingsActivity) {
return ((SettingsActivity) ((ContextThemeWrapper) context).getBaseContext());
}
}
return null;
}
private void exportZip() { private void exportZip() {
List<Tunnel> tunnels = new ArrayList<>(tunnelManager.getTunnels()); final List<Tunnel> tunnels = new ArrayList<>(tunnelManager.getTunnels());
List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size()); final List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size());
for (final Tunnel tunnel : tunnels) for (final Tunnel tunnel : tunnels)
futureConfigs.add(tunnel.getConfigAsync().toCompletableFuture()); futureConfigs.add(tunnel.getConfigAsync().toCompletableFuture());
if (futureConfigs.isEmpty()) { if (futureConfigs.isEmpty()) {
@ -65,9 +76,9 @@ public class ZipExporterPreference extends Preference {
throw exception; throw exception;
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
final File file = new File(path, "wireguard-export.zip"); final File file = new File(path, "wireguard-export.zip");
try { if (!path.mkdirs())
path.mkdirs(); throw new IOException("Cannot create output directory");
final ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(file)); try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(file))) {
for (int i = 0; i < futureConfigs.size(); ++i) { for (int i = 0; i < futureConfigs.size(); ++i) {
zip.putNextEntry(new ZipEntry(tunnels.get(i).getName() + ".conf")); zip.putNextEntry(new ZipEntry(tunnels.get(i).getName() + ".conf"));
zip.write(futureConfigs.get(i).getNow(null). zip.write(futureConfigs.get(i).getNow(null).
@ -76,6 +87,7 @@ public class ZipExporterPreference extends Preference {
zip.closeEntry(); zip.closeEntry();
zip.close(); zip.close();
} catch (Exception e) { } catch (Exception e) {
// noinspection ResultOfMethodCallIgnored
file.delete(); file.delete();
throw e; throw e;
} }
@ -84,7 +96,7 @@ public class ZipExporterPreference extends Preference {
}); });
} }
private void exportZipComplete(String filePath, Throwable throwable) { private void exportZipComplete(final String filePath, final Throwable throwable) {
if (throwable != null) { if (throwable != null) {
final String error = ExceptionLoggers.unwrap(throwable).getMessage(); final String error = ExceptionLoggers.unwrap(throwable).getMessage();
final String message = getContext().getString(R.string.export_error, error); final String message = getContext().getString(R.string.export_error, error);
@ -99,16 +111,6 @@ public class ZipExporterPreference extends Preference {
} }
} }
private SettingsActivity getPrefActivity(Preference preference) {
Context context = preference.getContext();
if (context instanceof ContextThemeWrapper) {
if (((ContextThemeWrapper) context).getBaseContext() instanceof SettingsActivity) {
return ((SettingsActivity) ((ContextThemeWrapper) context).getBaseContext());
}
}
return null;
}
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
if (exportedFilePath == null) if (exportedFilePath == null)

View File

@ -6,7 +6,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -28,9 +27,11 @@ enum Attribute {
PRIVATE_KEY("PrivateKey"), PRIVATE_KEY("PrivateKey"),
PUBLIC_KEY("PublicKey"); PUBLIC_KEY("PublicKey");
private static final String[] EMPTY_LIST = new String[0];
private static final Map<String, Attribute> KEY_MAP; private static final Map<String, Attribute> KEY_MAP;
private static final Pattern LIST_SEPARATOR_PATTERN = Pattern.compile("\\s*,\\s*");
private static final Method NUMERIC_ADDRESS_PARSER;
private static final Pattern SEPARATOR_PATTERN = Pattern.compile("\\s|="); private static final Pattern SEPARATOR_PATTERN = Pattern.compile("\\s|=");
private static Method parseNumericAddressMethod;
static { static {
KEY_MAP = new HashMap<>(Attribute.values().length); KEY_MAP = new HashMap<>(Attribute.values().length);
@ -41,8 +42,8 @@ enum Attribute {
static { static {
try { try {
parseNumericAddressMethod = InetAddress.class.getMethod("parseNumericAddress", new Class[]{String.class}); NUMERIC_ADDRESS_PARSER = InetAddress.class.getMethod("parseNumericAddress", String.class);
} catch (Exception e) { } catch (final Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -55,8 +56,8 @@ enum Attribute {
this.token = token; this.token = token;
} }
public static <T> String listToString(final List<T> list) { public static <T> String iterableToString(final Iterable<T> iterable) {
return TextUtils.join(", ", list); return TextUtils.join(", ", iterable);
} }
public static Attribute match(final CharSequence line) { public static Attribute match(final CharSequence line) {
@ -67,10 +68,10 @@ enum Attribute {
if (address == null || address.isEmpty()) if (address == null || address.isEmpty())
throw new IllegalArgumentException("Empty address"); throw new IllegalArgumentException("Empty address");
try { try {
return (InetAddress) parseNumericAddressMethod.invoke(null, new Object[]{address}); return (InetAddress) NUMERIC_ADDRESS_PARSER.invoke(null, address);
} catch (IllegalAccessException e) { } catch (final IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (InvocationTargetException e) { } catch (final InvocationTargetException e) {
if (e.getCause() instanceof IllegalArgumentException) if (e.getCause() instanceof IllegalArgumentException)
throw (IllegalArgumentException) e.getCause(); throw (IllegalArgumentException) e.getCause();
else else
@ -80,8 +81,8 @@ enum Attribute {
public static String[] stringToList(final String string) { public static String[] stringToList(final String string) {
if (string == null) if (string == null)
return new String[0]; return EMPTY_LIST;
return string.trim().split("\\s*,\\s*"); return LIST_SEPARATOR_PATTERN.split(string.trim());
} }
public String composeWith(final Object value) { public String composeWith(final Object value) {
@ -92,8 +93,8 @@ enum Attribute {
return String.format(Locale.getDefault(), "%s = %d%n", token, value); return String.format(Locale.getDefault(), "%s = %d%n", token, value);
} }
public <T> String composeWith(final List<T> value) { public <T> String composeWith(final Iterable<T> value) {
return String.format("%s = %s%n", token, listToString(value)); return String.format("%s = %s%n", token, iterableToString(value));
} }
public String parse(final CharSequence line) { public String parse(final CharSequence line) {

View File

@ -90,7 +90,7 @@ public class Config {
private Interface.Observable observableInterface; private Interface.Observable observableInterface;
private ObservableList<Peer.Observable> observablePeers; private ObservableList<Peer.Observable> observablePeers;
public Observable(Config parent, String name) { public Observable(final Config parent, final String name) {
this.name = name; this.name = name;
loadData(parent); loadData(parent);
} }
@ -102,11 +102,11 @@ public class Config {
in.readTypedList(observablePeers, Peer.Observable.CREATOR); in.readTypedList(observablePeers, Peer.Observable.CREATOR);
} }
public void commitData(Config parent) { public void commitData(final Config parent) {
this.observableInterface.commitData(parent.interfaceSection); observableInterface.commitData(parent.interfaceSection);
List<Peer> newPeers = new ArrayList<>(this.observablePeers.size()); final List<Peer> newPeers = new ArrayList<>(observablePeers.size());
for (Peer.Observable observablePeer : this.observablePeers) { for (final Peer.Observable observablePeer : observablePeers) {
Peer peer = new Peer(); final Peer peer = new Peer();
observablePeer.commitData(peer); observablePeer.commitData(peer);
newPeers.add(peer); newPeers.add(peer);
} }
@ -134,16 +134,16 @@ public class Config {
return observablePeers; return observablePeers;
} }
public void loadData(Config parent) { protected void loadData(final Config parent) {
this.observableInterface = new Interface.Observable(parent == null ? null : parent.interfaceSection); observableInterface = new Interface.Observable(parent == null ? null : parent.interfaceSection);
this.observablePeers = new ObservableArrayList<>(); observablePeers = new ObservableArrayList<>();
if (parent != null) { if (parent != null) {
for (Peer peer : parent.getPeers()) for (final Peer peer : parent.getPeers())
this.observablePeers.add(new Peer.Observable(peer)); observablePeers.add(new Peer.Observable(peer));
} }
} }
public void setName(String name) { public void setName(final String name) {
this.name = name; this.name = name;
notifyPropertyChanged(BR.name); notifyPropertyChanged(BR.name);
} }

View File

@ -6,17 +6,17 @@ import java.net.InetAddress;
import java.util.Locale; import java.util.Locale;
public class IPCidr { public class IPCidr {
private InetAddress address; private final InetAddress address;
private int cidr; private int cidr;
public IPCidr(String in) { public IPCidr(String in) {
cidr = -1; cidr = -1;
int slash = in.lastIndexOf('/'); final int slash = in.lastIndexOf('/');
if (slash != -1 && slash < in.length() - 1) { if (slash != -1 && slash < in.length() - 1) {
try { try {
cidr = Integer.parseInt(in.substring(slash + 1), 10); cidr = Integer.parseInt(in.substring(slash + 1), 10);
in = in.substring(0, slash); in = in.substring(0, slash);
} catch (Exception ignored) { } catch (final Exception ignored) {
} }
} }
address = Attribute.parseIPString(in); address = Attribute.parseIPString(in);

View File

@ -9,7 +9,7 @@ import com.wireguard.android.BR;
import com.wireguard.crypto.Keypair; import com.wireguard.crypto.Keypair;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.LinkedList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -17,30 +17,31 @@ import java.util.List;
*/ */
public class Interface { public class Interface {
private List<IPCidr> addressList; private final List<IPCidr> addressList;
private List<InetAddress> dnsList; private final List<InetAddress> dnsList;
private Keypair keypair; private Keypair keypair;
private int listenPort; private int listenPort;
private int mtu; private int mtu;
public Interface() { public Interface() {
addressList = new LinkedList<>(); addressList = new ArrayList<>();
dnsList = new LinkedList<>(); dnsList = new ArrayList<>();
} }
private void addAddresses(String[] addresses) { private void addAddresses(final String[] addresses) {
if (addresses != null && addresses.length > 0) { if (addresses != null && addresses.length > 0) {
for (final String addr : addresses) { for (final String addr : addresses) {
if (addr.isEmpty()) if (addr.isEmpty())
throw new IllegalArgumentException("Address is empty"); throw new IllegalArgumentException("Address is empty");
this.addressList.add(new IPCidr(addr)); addressList.add(new IPCidr(addr));
} }
} }
} }
private void addDnses(String[] dnses) { private void addDnses(final String[] dnses) {
if (dnses != null && dnses.length > 0) { if (dnses != null && dnses.length > 0) {
for (final String dns : dnses) { for (final String dns : dnses) {
this.dnsList.add(Attribute.parseIPString(dns)); dnsList.add(Attribute.parseIPString(dns));
} }
} }
} }
@ -48,7 +49,7 @@ public class Interface {
private String getAddressString() { private String getAddressString() {
if (addressList.isEmpty()) if (addressList.isEmpty())
return null; return null;
return Attribute.listToString(addressList); return Attribute.iterableToString(addressList);
} }
public IPCidr[] getAddresses() { public IPCidr[] getAddresses() {
@ -58,11 +59,11 @@ public class Interface {
private String getDnsString() { private String getDnsString() {
if (dnsList.isEmpty()) if (dnsList.isEmpty())
return null; return null;
return Attribute.listToString(getDnsStrings()); return Attribute.iterableToString(getDnsStrings());
} }
private List<String> getDnsStrings() { private List<String> getDnsStrings() {
List<String> strings = new LinkedList<>(); final List<String> strings = new ArrayList<>();
for (final InetAddress addr : dnsList) for (final InetAddress addr : dnsList)
strings.add(addr.getHostAddress()); strings.add(addr.getHostAddress());
return strings; return strings;
@ -106,31 +107,38 @@ public class Interface {
public void parse(final String line) { public void parse(final String line) {
final Attribute key = Attribute.match(line); final Attribute key = Attribute.match(line);
if (key == Attribute.ADDRESS) switch (key) {
case ADDRESS:
addAddresses(key.parseList(line)); addAddresses(key.parseList(line));
else if (key == Attribute.DNS) break;
case DNS:
addDnses(key.parseList(line)); addDnses(key.parseList(line));
else if (key == Attribute.LISTEN_PORT) break;
case LISTEN_PORT:
setListenPortString(key.parse(line)); setListenPortString(key.parse(line));
else if (key == Attribute.MTU) break;
case MTU:
setMtuString(key.parse(line)); setMtuString(key.parse(line));
else if (key == Attribute.PRIVATE_KEY) break;
case PRIVATE_KEY:
setPrivateKey(key.parse(line)); setPrivateKey(key.parse(line));
else break;
default:
throw new IllegalArgumentException(line); throw new IllegalArgumentException(line);
} }
}
private void setAddressString(final String addressString) { private void setAddressString(final String addressString) {
this.addressList.clear(); addressList.clear();
addAddresses(Attribute.stringToList(addressString)); addAddresses(Attribute.stringToList(addressString));
} }
private void setDnsString(final String dnsString) { private void setDnsString(final String dnsString) {
this.dnsList.clear(); dnsList.clear();
addDnses(Attribute.stringToList(dnsString)); addDnses(Attribute.stringToList(dnsString));
} }
private void setListenPort(int listenPort) { private void setListenPort(final int listenPort) {
this.listenPort = listenPort; this.listenPort = listenPort;
} }
@ -141,7 +149,7 @@ public class Interface {
setListenPort(0); setListenPort(0);
} }
private void setMtu(int mtu) { private void setMtu(final int mtu) {
this.mtu = mtu; this.mtu = mtu;
} }
@ -155,10 +163,7 @@ public class Interface {
private void setPrivateKey(String privateKey) { private void setPrivateKey(String privateKey) {
if (privateKey != null && privateKey.isEmpty()) if (privateKey != null && privateKey.isEmpty())
privateKey = null; privateKey = null;
if (privateKey == null) keypair = privateKey == null ? null : new Keypair(privateKey);
keypair = null;
else
keypair = new Keypair(privateKey);
} }
@Override @Override
@ -196,7 +201,7 @@ public class Interface {
private String privateKey; private String privateKey;
private String publicKey; private String publicKey;
public Observable(Interface parent) { public Observable(final Interface parent) {
if (parent != null) if (parent != null)
loadData(parent); loadData(parent);
} }
@ -210,12 +215,12 @@ public class Interface {
mtu = in.readString(); mtu = in.readString();
} }
public void commitData(Interface parent) { public void commitData(final Interface parent) {
parent.setAddressString(this.addresses); parent.setAddressString(addresses);
parent.setDnsString(this.dnses); parent.setDnsString(dnses);
parent.setPrivateKey(this.privateKey); parent.setPrivateKey(privateKey);
parent.setListenPortString(this.listenPort); parent.setListenPortString(listenPort);
parent.setMtuString(this.mtu); parent.setMtuString(mtu);
loadData(parent); loadData(parent);
notifyChange(); notifyChange();
} }
@ -226,7 +231,7 @@ public class Interface {
} }
public void generateKeypair() { public void generateKeypair() {
Keypair keypair = new Keypair(); final Keypair keypair = new Keypair();
privateKey = keypair.getPrivateKey(); privateKey = keypair.getPrivateKey();
publicKey = keypair.getPublicKey(); publicKey = keypair.getPublicKey();
notifyPropertyChanged(BR.privateKey); notifyPropertyChanged(BR.privateKey);
@ -263,42 +268,42 @@ public class Interface {
return publicKey; return publicKey;
} }
public void loadData(Interface parent) { protected void loadData(final Interface parent) {
this.addresses = parent.getAddressString(); addresses = parent.getAddressString();
this.dnses = parent.getDnsString(); dnses = parent.getDnsString();
this.publicKey = parent.getPublicKey(); publicKey = parent.getPublicKey();
this.privateKey = parent.getPrivateKey(); privateKey = parent.getPrivateKey();
this.listenPort = parent.getListenPortString(); listenPort = parent.getListenPortString();
this.mtu = parent.getMtuString(); mtu = parent.getMtuString();
} }
public void setAddresses(String addresses) { public void setAddresses(final String addresses) {
this.addresses = addresses; this.addresses = addresses;
notifyPropertyChanged(BR.addresses); notifyPropertyChanged(BR.addresses);
} }
public void setDnses(String dnses) { public void setDnses(final String dnses) {
this.dnses = dnses; this.dnses = dnses;
notifyPropertyChanged(BR.dnses); notifyPropertyChanged(BR.dnses);
} }
public void setListenPort(String listenPort) { public void setListenPort(final String listenPort) {
this.listenPort = listenPort; this.listenPort = listenPort;
notifyPropertyChanged(BR.listenPort); notifyPropertyChanged(BR.listenPort);
} }
public void setMtu(String mtu) { public void setMtu(final String mtu) {
this.mtu = mtu; this.mtu = mtu;
notifyPropertyChanged(BR.mtu); notifyPropertyChanged(BR.mtu);
} }
public void setPrivateKey(String privateKey) { public void setPrivateKey(final String privateKey) {
this.privateKey = privateKey; this.privateKey = privateKey;
try { try {
this.publicKey = new Keypair(privateKey).getPublicKey(); publicKey = new Keypair(privateKey).getPublicKey();
} catch (IllegalArgumentException ignored) { } catch (final IllegalArgumentException ignored) {
this.publicKey = ""; publicKey = "";
} }
notifyPropertyChanged(BR.privateKey); notifyPropertyChanged(BR.privateKey);

View File

@ -13,7 +13,7 @@ import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.LinkedList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -22,19 +22,20 @@ import java.util.Locale;
*/ */
public class Peer { public class Peer {
private List<IPCidr> allowedIPsList; private final List<IPCidr> allowedIPsList;
private InetSocketAddress endpoint; private InetSocketAddress endpoint;
private int persistentKeepalive; private int persistentKeepalive;
private String preSharedKey; private String preSharedKey;
private String publicKey; private String publicKey;
public Peer() { public Peer() {
allowedIPsList = new LinkedList<>(); allowedIPsList = new ArrayList<>();
} }
private void addAllowedIPs(String[] allowedIPs) { private void addAllowedIPs(final String[] allowedIPs) {
if (allowedIPs != null && allowedIPs.length > 0) { if (allowedIPs != null && allowedIPs.length > 0) {
for (final String allowedIP : allowedIPs) { for (final String allowedIP : allowedIPs) {
this.allowedIPsList.add(new IPCidr(allowedIP)); allowedIPsList.add(new IPCidr(allowedIP));
} }
} }
} }
@ -46,7 +47,7 @@ public class Peer {
private String getAllowedIPsString() { private String getAllowedIPsString() {
if (allowedIPsList.isEmpty()) if (allowedIPsList.isEmpty())
return null; return null;
return Attribute.listToString(allowedIPsList); return Attribute.iterableToString(allowedIPsList);
} }
public InetSocketAddress getEndpoint() { public InetSocketAddress getEndpoint() {
@ -97,38 +98,45 @@ public class Peer {
public void parse(final String line) { public void parse(final String line) {
final Attribute key = Attribute.match(line); final Attribute key = Attribute.match(line);
if (key == Attribute.ALLOWED_IPS) switch (key) {
case ALLOWED_IPS:
addAllowedIPs(key.parseList(line)); addAllowedIPs(key.parseList(line));
else if (key == Attribute.ENDPOINT) break;
case ENDPOINT:
setEndpointString(key.parse(line)); setEndpointString(key.parse(line));
else if (key == Attribute.PERSISTENT_KEEPALIVE) break;
case PERSISTENT_KEEPALIVE:
setPersistentKeepaliveString(key.parse(line)); setPersistentKeepaliveString(key.parse(line));
else if (key == Attribute.PRESHARED_KEY) break;
case PRESHARED_KEY:
setPreSharedKey(key.parse(line)); setPreSharedKey(key.parse(line));
else if (key == Attribute.PUBLIC_KEY) break;
case PUBLIC_KEY:
setPublicKey(key.parse(line)); setPublicKey(key.parse(line));
else break;
default:
throw new IllegalArgumentException(line); throw new IllegalArgumentException(line);
} }
}
private void setAllowedIPsString(final String allowedIPsString) { private void setAllowedIPsString(final String allowedIPsString) {
this.allowedIPsList.clear(); allowedIPsList.clear();
addAllowedIPs(Attribute.stringToList(allowedIPsString)); addAllowedIPs(Attribute.stringToList(allowedIPsString));
} }
private void setEndpoint(InetSocketAddress endpoint) { private void setEndpoint(final InetSocketAddress endpoint) {
this.endpoint = endpoint; this.endpoint = endpoint;
} }
private void setEndpointString(final String endpoint) { private void setEndpointString(final String endpoint) {
if (endpoint != null && !endpoint.isEmpty()) { if (endpoint != null && !endpoint.isEmpty()) {
InetSocketAddress constructedEndpoint; final InetSocketAddress constructedEndpoint;
if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1) if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1)
throw new IllegalArgumentException("Forbidden characters in endpoint"); throw new IllegalArgumentException("Forbidden characters in endpoint");
URI uri; final URI uri;
try { try {
uri = new URI("wg://" + endpoint); uri = new URI("wg://" + endpoint);
} catch (URISyntaxException e) { } catch (final URISyntaxException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
constructedEndpoint = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort()); constructedEndpoint = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort());
@ -137,11 +145,11 @@ public class Peer {
setEndpoint(null); setEndpoint(null);
} }
private void setPersistentKeepalive(int persistentKeepalive) { private void setPersistentKeepalive(final int persistentKeepalive) {
this.persistentKeepalive = persistentKeepalive; this.persistentKeepalive = persistentKeepalive;
} }
private void setPersistentKeepaliveString(String persistentKeepalive) { private void setPersistentKeepaliveString(final String persistentKeepalive) {
if (persistentKeepalive != null && !persistentKeepalive.isEmpty()) if (persistentKeepalive != null && !persistentKeepalive.isEmpty())
setPersistentKeepalive(Integer.parseInt(persistentKeepalive, 10)); setPersistentKeepalive(Integer.parseInt(persistentKeepalive, 10));
else else
@ -198,7 +206,7 @@ public class Peer {
private String preSharedKey; private String preSharedKey;
private String publicKey; private String publicKey;
public Observable(Peer parent) { public Observable(final Peer parent) {
loadData(parent); loadData(parent);
} }
@ -214,12 +222,12 @@ public class Peer {
return new Observable(new Peer()); return new Observable(new Peer());
} }
public void commitData(Peer parent) { public void commitData(final Peer parent) {
parent.setAllowedIPsString(this.allowedIPs); parent.setAllowedIPsString(allowedIPs);
parent.setEndpointString(this.endpoint); parent.setEndpointString(endpoint);
parent.setPersistentKeepaliveString(this.persistentKeepalive); parent.setPersistentKeepaliveString(persistentKeepalive);
parent.setPreSharedKey(this.preSharedKey); parent.setPreSharedKey(preSharedKey);
parent.setPublicKey(this.publicKey); parent.setPublicKey(publicKey);
if (parent.getPublicKey() == null) if (parent.getPublicKey() == null)
throw new IllegalArgumentException("Peer public key may not be empty"); throw new IllegalArgumentException("Peer public key may not be empty");
loadData(parent); loadData(parent);
@ -256,35 +264,35 @@ public class Peer {
return publicKey; return publicKey;
} }
public void loadData(Peer parent) { protected void loadData(final Peer parent) {
this.allowedIPs = parent.getAllowedIPsString(); allowedIPs = parent.getAllowedIPsString();
this.endpoint = parent.getEndpointString(); endpoint = parent.getEndpointString();
this.persistentKeepalive = parent.getPersistentKeepaliveString(); persistentKeepalive = parent.getPersistentKeepaliveString();
this.preSharedKey = parent.getPreSharedKey(); preSharedKey = parent.getPreSharedKey();
this.publicKey = parent.getPublicKey(); publicKey = parent.getPublicKey();
} }
public void setAllowedIPs(String allowedIPs) { public void setAllowedIPs(final String allowedIPs) {
this.allowedIPs = allowedIPs; this.allowedIPs = allowedIPs;
notifyPropertyChanged(BR.allowedIPs); notifyPropertyChanged(BR.allowedIPs);
} }
public void setEndpoint(String endpoint) { public void setEndpoint(final String endpoint) {
this.endpoint = endpoint; this.endpoint = endpoint;
notifyPropertyChanged(BR.endpoint); notifyPropertyChanged(BR.endpoint);
} }
public void setPersistentKeepalive(String persistentKeepalive) { public void setPersistentKeepalive(final String persistentKeepalive) {
this.persistentKeepalive = persistentKeepalive; this.persistentKeepalive = persistentKeepalive;
notifyPropertyChanged(BR.persistentKeepalive); notifyPropertyChanged(BR.persistentKeepalive);
} }
public void setPreSharedKey(String preSharedKey) { public void setPreSharedKey(final String preSharedKey) {
this.preSharedKey = preSharedKey; this.preSharedKey = preSharedKey;
notifyPropertyChanged(BR.preSharedKey); notifyPropertyChanged(BR.preSharedKey);
} }
public void setPublicKey(String publicKey) { public void setPublicKey(final String publicKey) {
this.publicKey = publicKey; this.publicKey = publicKey;
notifyPropertyChanged(BR.publicKey); notifyPropertyChanged(BR.publicKey);
} }