global: Clean up Java
Address Java and Android lints. Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
@@ -49,7 +49,7 @@ public abstract class BaseActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Application.getComponent().getBackendType() == GoBackend.class) {
|
||||
Intent intent = GoBackend.VpnService.prepare(this);
|
||||
final Intent intent = GoBackend.VpnService.prepare(this);
|
||||
if (intent != null) {
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class MainActivity extends BaseActivity {
|
||||
fragment =
|
||||
((TunnelListFragment)
|
||||
getSupportFragmentManager().getFragments().get(0));
|
||||
} catch (ClassCastException ignored) {
|
||||
} catch (final ClassCastException ignored) {
|
||||
}
|
||||
if (fragment == null || !(fragment.collapseActionMenu())) {
|
||||
if (!moveToState(State.ofLayer(state.layer - 1)))
|
||||
|
||||
@@ -17,28 +17,29 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface for changing application-global persistent settings.
|
||||
*/
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
private HashMap<Integer, PermissionRequestCallback> permissionRequestCallbacks = new HashMap<>();
|
||||
private int permissionRequestCounter = 0;
|
||||
private final Map<Integer, PermissionRequestCallback> permissionRequestCallbacks = new HashMap<>();
|
||||
private int permissionRequestCounter;
|
||||
|
||||
public synchronized void ensurePermissions(String[] permissions, PermissionRequestCallback cb) {
|
||||
List<String> needPermissions = new ArrayList<>(permissions.length);
|
||||
public void ensurePermissions(final String[] permissions, final PermissionRequestCallback cb) {
|
||||
final List<String> needPermissions = new ArrayList<>(permissions.length);
|
||||
for (final String permission : permissions) {
|
||||
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
|
||||
needPermissions.add(permission);
|
||||
}
|
||||
if (needPermissions.isEmpty()) {
|
||||
int[] granted = new int[permissions.length];
|
||||
final int[] granted = new int[permissions.length];
|
||||
Arrays.fill(granted, PackageManager.PERMISSION_GRANTED);
|
||||
cb.done(permissions, granted);
|
||||
return;
|
||||
}
|
||||
int idx = permissionRequestCounter++;
|
||||
final int idx = permissionRequestCounter++;
|
||||
permissionRequestCallbacks.put(idx, cb);
|
||||
ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), idx);
|
||||
}
|
||||
@@ -54,7 +55,7 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
@@ -65,7 +66,7 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
@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);
|
||||
if (f != null) {
|
||||
permissionRequestCallbacks.remove(requestCode);
|
||||
@@ -73,7 +74,6 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PermissionRequestCallback {
|
||||
void done(String[] permissions, int[] grantResults);
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ public final class GoBackend implements Backend {
|
||||
System.loadLibrary("wg-go");
|
||||
}
|
||||
|
||||
private Context context;
|
||||
private final Context context;
|
||||
private Tunnel currentTunnel;
|
||||
private int currentTunnelHandle = -1;
|
||||
|
||||
public GoBackend(Context context) {
|
||||
public GoBackend(final Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@@ -108,14 +108,14 @@ public final class GoBackend implements Backend {
|
||||
if (VpnService.prepare(context) != null)
|
||||
throw new Exception("VPN service not authorized by user");
|
||||
|
||||
VpnService service;
|
||||
final VpnService service;
|
||||
if (!vpnService.isDone())
|
||||
startVpnService();
|
||||
|
||||
try {
|
||||
service = vpnService.get(2, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
throw new Exception("Unable to start Android VPN service");
|
||||
} catch (final TimeoutException e) {
|
||||
throw new Exception("Unable to start Android VPN service", e);
|
||||
}
|
||||
|
||||
if (currentTunnelHandle != -1) {
|
||||
@@ -124,29 +124,32 @@ public final class GoBackend implements Backend {
|
||||
}
|
||||
|
||||
// Build config
|
||||
Formatter fmt = new Formatter(new StringBuilder());
|
||||
final Interface iface = config.getInterface();
|
||||
fmt.format("replace_peers=true\n");
|
||||
if (iface.getPrivateKey() != null)
|
||||
fmt.format("private_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(iface.getPrivateKey())));
|
||||
if (iface.getListenPort() != 0)
|
||||
fmt.format("listen_port=%d\n", config.getInterface().getListenPort());
|
||||
for (final Peer peer : config.getPeers()) {
|
||||
if (peer.getPublicKey() != null)
|
||||
fmt.format("public_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(peer.getPublicKey())));
|
||||
if (peer.getPreSharedKey() != null)
|
||||
fmt.format("preshared_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(peer.getPreSharedKey())));
|
||||
if (peer.getEndpoint() != null)
|
||||
fmt.format("endpoint=%s\n", peer.getResolvedEndpointString());
|
||||
if (peer.getPersistentKeepalive() != 0)
|
||||
fmt.format("persistent_keepalive_interval=%d\n", peer.getPersistentKeepalive());
|
||||
for (final IPCidr addr : peer.getAllowedIPs()) {
|
||||
fmt.format("allowed_ip=%s\n", addr.toString());
|
||||
final String goConfig;
|
||||
try (Formatter fmt = new Formatter(new StringBuilder())) {
|
||||
fmt.format("replace_peers=true\n");
|
||||
if (iface.getPrivateKey() != null)
|
||||
fmt.format("private_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(iface.getPrivateKey())));
|
||||
if (iface.getListenPort() != 0)
|
||||
fmt.format("listen_port=%d\n", config.getInterface().getListenPort());
|
||||
for (final Peer peer : config.getPeers()) {
|
||||
if (peer.getPublicKey() != null)
|
||||
fmt.format("public_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(peer.getPublicKey())));
|
||||
if (peer.getPreSharedKey() != null)
|
||||
fmt.format("preshared_key=%s\n", KeyEncoding.keyToHex(KeyEncoding.keyFromBase64(peer.getPreSharedKey())));
|
||||
if (peer.getEndpoint() != null)
|
||||
fmt.format("endpoint=%s\n", peer.getResolvedEndpointString());
|
||||
if (peer.getPersistentKeepalive() != 0)
|
||||
fmt.format("persistent_keepalive_interval=%d\n", peer.getPersistentKeepalive());
|
||||
for (final IPCidr addr : peer.getAllowedIPs()) {
|
||||
fmt.format("allowed_ip=%s\n", addr.toString());
|
||||
}
|
||||
}
|
||||
goConfig = fmt.toString();
|
||||
}
|
||||
|
||||
// Create the vpn tunnel with android API
|
||||
VpnService.Builder builder = service.getBuilder();
|
||||
final VpnService.Builder builder = service.getBuilder();
|
||||
builder.setSession(tunnel.getName());
|
||||
|
||||
for (final IPCidr addr : config.getInterface().getAddresses())
|
||||
@@ -166,13 +169,13 @@ public final class GoBackend implements Backend {
|
||||
builder.setMtu(mtu);
|
||||
|
||||
builder.setBlocking(true);
|
||||
ParcelFileDescriptor tun = builder.establish();
|
||||
final ParcelFileDescriptor tun = builder.establish();
|
||||
if (tun == null)
|
||||
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)
|
||||
throw new Exception("Unable to turn tunnel on (wgTurnOn return " + currentTunnelHandle + ")");
|
||||
throw new Exception("Unable to turn tunnel on (wgTurnOn return " + currentTunnelHandle + ')');
|
||||
|
||||
currentTunnel = tunnel;
|
||||
|
||||
|
||||
@@ -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 int result = rootShell.run(null, command);
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
tempFile.delete();
|
||||
if (result != 0)
|
||||
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
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
Log.d(TAG, "Refreshing tunnel states");
|
||||
Application.getComponent().getTunnelManager().refreshTunnelStates();
|
||||
}
|
||||
|
||||
@@ -109,10 +109,10 @@ public class TunnelEditorFragment extends BaseFragment {
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_action_save:
|
||||
Config newConfig = new Config();
|
||||
final Config newConfig = new Config();
|
||||
try {
|
||||
binding.getConfig().commitData(newConfig);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
final String error = ExceptionLoggers.unwrap(e).getMessage();
|
||||
final String tunnelName = tunnel == null ? binding.getConfig().getName() : tunnel.getName();
|
||||
final String message = getString(R.string.config_save_error, tunnelName, error);
|
||||
@@ -202,8 +202,8 @@ public class TunnelEditorFragment extends BaseFragment {
|
||||
onSelectedTunnelChanged(null, getSelectedTunnel());
|
||||
} else {
|
||||
tunnel = getSelectedTunnel();
|
||||
Config.Observable config = savedInstanceState.getParcelable(KEY_LOCAL_CONFIG);
|
||||
String originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME);
|
||||
final Config.Observable config = savedInstanceState.getParcelable(KEY_LOCAL_CONFIG);
|
||||
final String originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME);
|
||||
if (tunnel != null && !tunnel.getName().equals(originalName))
|
||||
onSelectedTunnelChanged(null, tunnel);
|
||||
else
|
||||
|
||||
@@ -43,6 +43,7 @@ import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
@@ -82,7 +83,7 @@ public class TunnelListFragment extends BaseFragment {
|
||||
return;
|
||||
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<>();
|
||||
asyncWorker.supplyAsync(() -> {
|
||||
final String[] columns = {OpenableColumns.DISPLAY_NAME};
|
||||
@@ -106,31 +107,32 @@ public class TunnelListFragment extends BaseFragment {
|
||||
throw new IllegalArgumentException("File must be .conf or .zip");
|
||||
|
||||
if (isZip) {
|
||||
ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(zip, StandardCharsets.UTF_8));
|
||||
ZipEntry entry;
|
||||
while ((entry = zip.getNextEntry()) != null) {
|
||||
if (entry.isDirectory())
|
||||
continue;
|
||||
name = entry.getName();
|
||||
idx = name.lastIndexOf('/');
|
||||
if (idx >= 0) {
|
||||
if (idx >= name.length() - 1)
|
||||
try (ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri))) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(zip, StandardCharsets.UTF_8));
|
||||
ZipEntry entry;
|
||||
while ((entry = zip.getNextEntry()) != null) {
|
||||
if (entry.isDirectory())
|
||||
continue;
|
||||
name = name.substring(name.lastIndexOf('/') + 1);
|
||||
name = entry.getName();
|
||||
idx = name.lastIndexOf('/');
|
||||
if (idx >= 0) {
|
||||
if (idx >= name.length() - 1)
|
||||
continue;
|
||||
name = name.substring(name.lastIndexOf('/') + 1);
|
||||
}
|
||||
if (name.toLowerCase().endsWith(".conf"))
|
||||
name = name.substring(0, name.length() - ".conf".length());
|
||||
else
|
||||
continue;
|
||||
Config config = null;
|
||||
try {
|
||||
config = Config.from(reader);
|
||||
} catch (Exception e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
if (config != null)
|
||||
futureTunnels.add(tunnelManager.create(name, config).toCompletableFuture());
|
||||
}
|
||||
if (name.toLowerCase().endsWith(".conf"))
|
||||
name = name.substring(0, name.length() - ".conf".length());
|
||||
else
|
||||
continue;
|
||||
Config config = null;
|
||||
try {
|
||||
config = Config.from(reader);
|
||||
} catch (Exception e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
if (config != null)
|
||||
futureTunnels.add(tunnelManager.create(name, config).toCompletableFuture());
|
||||
}
|
||||
} else {
|
||||
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()]));
|
||||
}).whenComplete((future, exception) -> {
|
||||
if (exception != null) {
|
||||
this.onTunnelImportFinished(Collections.emptyList(), Collections.singletonList(exception));
|
||||
onTunnelImportFinished(Collections.emptyList(), Collections.singletonList(exception));
|
||||
} else {
|
||||
future.whenComplete((ignored1, ignored2) -> {
|
||||
ArrayList<Tunnel> tunnels = new ArrayList<>(futureTunnels.size());
|
||||
for (CompletableFuture<Tunnel> futureTunnel : futureTunnels) {
|
||||
final List<Tunnel> tunnels = new ArrayList<>(futureTunnels.size());
|
||||
for (final CompletableFuture<Tunnel> futureTunnel : futureTunnels) {
|
||||
Tunnel tunnel = null;
|
||||
try {
|
||||
tunnel = futureTunnel.getNow(null);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
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;
|
||||
|
||||
for (final Throwable throwable : throwables) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.wireguard.config.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -39,7 +40,7 @@ public class ZipExporterPreference extends Preference {
|
||||
|
||||
private final AsyncWorker asyncWorker;
|
||||
private final TunnelManager tunnelManager;
|
||||
private String exportedFilePath = null;
|
||||
private String exportedFilePath;
|
||||
|
||||
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
|
||||
public ZipExporterPreference(final Context context, final AttributeSet attrs) {
|
||||
@@ -49,9 +50,19 @@ public class ZipExporterPreference extends Preference {
|
||||
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() {
|
||||
List<Tunnel> tunnels = new ArrayList<>(tunnelManager.getTunnels());
|
||||
List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size());
|
||||
final List<Tunnel> tunnels = new ArrayList<>(tunnelManager.getTunnels());
|
||||
final List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size());
|
||||
for (final Tunnel tunnel : tunnels)
|
||||
futureConfigs.add(tunnel.getConfigAsync().toCompletableFuture());
|
||||
if (futureConfigs.isEmpty()) {
|
||||
@@ -65,9 +76,9 @@ public class ZipExporterPreference extends Preference {
|
||||
throw exception;
|
||||
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
final File file = new File(path, "wireguard-export.zip");
|
||||
try {
|
||||
path.mkdirs();
|
||||
final ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(file));
|
||||
if (!path.mkdirs())
|
||||
throw new IOException("Cannot create output directory");
|
||||
try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(file))) {
|
||||
for (int i = 0; i < futureConfigs.size(); ++i) {
|
||||
zip.putNextEntry(new ZipEntry(tunnels.get(i).getName() + ".conf"));
|
||||
zip.write(futureConfigs.get(i).getNow(null).
|
||||
@@ -76,6 +87,7 @@ public class ZipExporterPreference extends Preference {
|
||||
zip.closeEntry();
|
||||
zip.close();
|
||||
} catch (Exception e) {
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
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) {
|
||||
final String error = ExceptionLoggers.unwrap(throwable).getMessage();
|
||||
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
|
||||
public CharSequence getSummary() {
|
||||
if (exportedFilePath == null)
|
||||
|
||||
Reference in New Issue
Block a user