Localize exception messages
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
e1965f121c
commit
9de711a4f5
@ -57,7 +57,7 @@ public interface Backend {
|
|||||||
*
|
*
|
||||||
* @return Type name
|
* @return Type name
|
||||||
*/
|
*/
|
||||||
String getTypeName();
|
String getTypePrettyName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine version of underlying backend.
|
* Determine version of underlying backend.
|
||||||
|
@ -14,6 +14,7 @@ import android.support.v4.util.ArraySet;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.wireguard.android.Application;
|
import com.wireguard.android.Application;
|
||||||
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.activity.MainActivity;
|
import com.wireguard.android.activity.MainActivity;
|
||||||
import com.wireguard.android.model.Tunnel;
|
import com.wireguard.android.model.Tunnel;
|
||||||
import com.wireguard.android.model.Tunnel.State;
|
import com.wireguard.android.model.Tunnel.State;
|
||||||
@ -26,6 +27,7 @@ import com.wireguard.config.Peer;
|
|||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -93,8 +95,8 @@ public final class GoBackend implements Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName() {
|
public String getTypePrettyName() {
|
||||||
return "Go userspace";
|
return context.getResources().getString(R.string.type_name_go_userspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -110,7 +112,7 @@ public final class GoBackend implements Backend {
|
|||||||
if (state == originalState)
|
if (state == originalState)
|
||||||
return originalState;
|
return originalState;
|
||||||
if (state == State.UP && currentTunnel != null)
|
if (state == State.UP && currentTunnel != null)
|
||||||
throw new IllegalStateException("Only one userspace tunnel can run at a time");
|
throw new IllegalStateException(context.getResources().getString(R.string.multiple_tunnels_error));
|
||||||
Log.d(TAG, "Changing tunnel " + tunnel.getName() + " to state " + state);
|
Log.d(TAG, "Changing tunnel " + tunnel.getName() + " to state " + state);
|
||||||
setStateInternal(tunnel, tunnel.getConfig(), state);
|
setStateInternal(tunnel, tunnel.getConfig(), state);
|
||||||
return getState(tunnel);
|
return getState(tunnel);
|
||||||
@ -122,10 +124,10 @@ public final class GoBackend implements Backend {
|
|||||||
if (state == State.UP) {
|
if (state == State.UP) {
|
||||||
Log.i(TAG, "Bringing tunnel up");
|
Log.i(TAG, "Bringing tunnel up");
|
||||||
|
|
||||||
Objects.requireNonNull(config, "Trying to bring up a tunnel with no config");
|
Objects.requireNonNull(config, context.getResources().getString(R.string.no_config_error));
|
||||||
|
|
||||||
if (VpnService.prepare(context) != null)
|
if (VpnService.prepare(context) != null)
|
||||||
throw new Exception("VPN service not authorized by user");
|
throw new Exception(context.getResources().getString(R.string.vpn_not_authed_error));
|
||||||
|
|
||||||
final VpnService service;
|
final VpnService service;
|
||||||
if (!vpnService.isDone())
|
if (!vpnService.isDone())
|
||||||
@ -134,7 +136,7 @@ public final class GoBackend implements Backend {
|
|||||||
try {
|
try {
|
||||||
service = vpnService.get(2, TimeUnit.SECONDS);
|
service = vpnService.get(2, TimeUnit.SECONDS);
|
||||||
} catch (final TimeoutException e) {
|
} catch (final TimeoutException e) {
|
||||||
throw new Exception("Unable to start Android VPN service", e);
|
throw new Exception(context.getResources().getString(R.string.vpn_start_error), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTunnelHandle != -1) {
|
if (currentTunnelHandle != -1) {
|
||||||
@ -172,12 +174,12 @@ public final class GoBackend implements Backend {
|
|||||||
builder.setBlocking(true);
|
builder.setBlocking(true);
|
||||||
try (final ParcelFileDescriptor tun = builder.establish()) {
|
try (final ParcelFileDescriptor tun = builder.establish()) {
|
||||||
if (tun == null)
|
if (tun == null)
|
||||||
throw new Exception("Unable to create tun device");
|
throw new Exception(context.getResources().getString(R.string.tun_create_error));
|
||||||
Log.d(TAG, "Go backend v" + wgVersion());
|
Log.d(TAG, "Go backend v" + wgVersion());
|
||||||
currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig);
|
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(String.format(Locale.getDefault(), context.getResources().getString(R.string.tunnel_on_error), currentTunnelHandle));
|
||||||
|
|
||||||
currentTunnel = tunnel;
|
currentTunnel = tunnel;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import android.support.annotation.Nullable;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.wireguard.android.Application;
|
import com.wireguard.android.Application;
|
||||||
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.model.Tunnel;
|
import com.wireguard.android.model.Tunnel;
|
||||||
import com.wireguard.android.model.Tunnel.State;
|
import com.wireguard.android.model.Tunnel.State;
|
||||||
import com.wireguard.android.model.Tunnel.Statistics;
|
import com.wireguard.android.model.Tunnel.Statistics;
|
||||||
@ -36,9 +37,11 @@ public final class WgQuickBackend implements Backend {
|
|||||||
private static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName();
|
private static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName();
|
||||||
|
|
||||||
private final File localTemporaryDir;
|
private final File localTemporaryDir;
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
public WgQuickBackend(final Context context) {
|
public WgQuickBackend(final Context context) {
|
||||||
localTemporaryDir = new File(context.getCacheDir(), "tmp");
|
localTemporaryDir = new File(context.getCacheDir(), "tmp");
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -84,8 +87,8 @@ public final class WgQuickBackend implements Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName() {
|
public String getTypePrettyName() {
|
||||||
return "Kernel module";
|
return context.getResources().getString(R.string.type_name_kernel_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -93,7 +96,7 @@ public final class WgQuickBackend implements Backend {
|
|||||||
final List<String> output = new ArrayList<>();
|
final List<String> output = new ArrayList<>();
|
||||||
if (Application.getRootShell()
|
if (Application.getRootShell()
|
||||||
.run(output, "cat /sys/module/wireguard/version") != 0 || output.isEmpty())
|
.run(output, "cat /sys/module/wireguard/version") != 0 || output.isEmpty())
|
||||||
throw new Exception("Unable to determine kernel module version");
|
throw new Exception(context.getResources().getString(R.string.module_version_error));
|
||||||
return output.get(0);
|
return output.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +128,6 @@ public final class WgQuickBackend implements Backend {
|
|||||||
// noinspection ResultOfMethodCallIgnored
|
// 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(context.getResources().getString(R.string.tunnel_config_error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package com.wireguard.android.configStore;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.config.Config;
|
import com.wireguard.config.Config;
|
||||||
import com.wireguard.config.ParseException;
|
import com.wireguard.config.ParseException;
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import java9.util.stream.Collectors;
|
import java9.util.stream.Collectors;
|
||||||
@ -40,7 +42,8 @@ public final class FileConfigStore implements ConfigStore {
|
|||||||
Log.d(TAG, "Creating configuration for tunnel " + name);
|
Log.d(TAG, "Creating configuration for tunnel " + name);
|
||||||
final File file = fileFor(name);
|
final File file = fileFor(name);
|
||||||
if (!file.createNewFile())
|
if (!file.createNewFile())
|
||||||
throw new IOException("Configuration file " + file.getName() + " already exists");
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.config_file_exists_error), file.getName()));
|
||||||
try (final FileOutputStream stream = new FileOutputStream(file, false)) {
|
try (final FileOutputStream stream = new FileOutputStream(file, false)) {
|
||||||
stream.write(config.toWgQuickString().getBytes(StandardCharsets.UTF_8));
|
stream.write(config.toWgQuickString().getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
@ -52,7 +55,8 @@ public final class FileConfigStore implements ConfigStore {
|
|||||||
Log.d(TAG, "Deleting configuration for tunnel " + name);
|
Log.d(TAG, "Deleting configuration for tunnel " + name);
|
||||||
final File file = fileFor(name);
|
final File file = fileFor(name);
|
||||||
if (!file.delete())
|
if (!file.delete())
|
||||||
throw new IOException("Cannot delete configuration file " + file.getName());
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.config_delete_error), file.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -80,11 +84,13 @@ public final class FileConfigStore implements ConfigStore {
|
|||||||
final File file = fileFor(name);
|
final File file = fileFor(name);
|
||||||
final File replacementFile = fileFor(replacement);
|
final File replacementFile = fileFor(replacement);
|
||||||
if (!replacementFile.createNewFile())
|
if (!replacementFile.createNewFile())
|
||||||
throw new IOException("Configuration for " + replacement + " already exists");
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.config_exists_error), replacement));
|
||||||
if (!file.renameTo(replacementFile)) {
|
if (!file.renameTo(replacementFile)) {
|
||||||
if (!replacementFile.delete())
|
if (!replacementFile.delete())
|
||||||
Log.w(TAG, "Couldn't delete marker file for new name " + replacement);
|
Log.w(TAG, "Couldn't delete marker file for new name " + replacement);
|
||||||
throw new IOException("Cannot rename configuration file " + file.getName());
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.config_rename_error), file.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +99,8 @@ public final class FileConfigStore implements ConfigStore {
|
|||||||
Log.d(TAG, "Saving configuration for tunnel " + name);
|
Log.d(TAG, "Saving configuration for tunnel " + name);
|
||||||
final File file = fileFor(name);
|
final File file = fileFor(name);
|
||||||
if (!file.isFile())
|
if (!file.isFile())
|
||||||
throw new FileNotFoundException("Configuration file " + file.getName() + " not found");
|
throw new FileNotFoundException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.config_not_found_error), file.getName()));
|
||||||
try (final FileOutputStream stream = new FileOutputStream(file, false)) {
|
try (final FileOutputStream stream = new FileOutputStream(file, false)) {
|
||||||
stream.write(config.toWgQuickString().getBytes(StandardCharsets.UTF_8));
|
stream.write(config.toWgQuickString().getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.wireguard.config.ParseException;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ConfigNamingDialogFragment extends DialogFragment {
|
public class ConfigNamingDialogFragment extends DialogFragment {
|
||||||
@ -68,7 +69,8 @@ public class ConfigNamingDialogFragment extends DialogFragment {
|
|||||||
try {
|
try {
|
||||||
config = Config.parse(new ByteArrayInputStream(getArguments().getString(KEY_CONFIG_TEXT).getBytes(StandardCharsets.UTF_8)));
|
config = Config.parse(new ByteArrayInputStream(getArguments().getString(KEY_CONFIG_TEXT).getBytes(StandardCharsets.UTF_8)));
|
||||||
} catch (final IOException | ParseException exception) {
|
} catch (final IOException | ParseException exception) {
|
||||||
throw new RuntimeException("Invalid config passed to " + getClass().getSimpleName(), exception);
|
throw new RuntimeException(String.format(Locale.getDefault(),
|
||||||
|
getResources().getString(R.string.invalid_config_error), getClass().getSimpleName()), exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +115,15 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
int idx = name.lastIndexOf('/');
|
int idx = name.lastIndexOf('/');
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
if (idx >= name.length() - 1)
|
if (idx >= name.length() - 1)
|
||||||
throw new IllegalArgumentException("Illegal file name: " + name);
|
throw new IllegalArgumentException(String.format(Locale.getDefault(),
|
||||||
|
getResources().getString(R.string.illegal_filename_error), name));
|
||||||
name = name.substring(idx + 1);
|
name = name.substring(idx + 1);
|
||||||
}
|
}
|
||||||
boolean isZip = name.toLowerCase(Locale.ENGLISH).endsWith(".zip");
|
boolean isZip = name.toLowerCase(Locale.ENGLISH).endsWith(".zip");
|
||||||
if (name.toLowerCase(Locale.ENGLISH).endsWith(".conf"))
|
if (name.toLowerCase(Locale.ENGLISH).endsWith(".conf"))
|
||||||
name = name.substring(0, name.length() - ".conf".length());
|
name = name.substring(0, name.length() - ".conf".length());
|
||||||
else if (!isZip)
|
else if (!isZip)
|
||||||
throw new IllegalArgumentException("File must be .conf or .zip");
|
throw new IllegalArgumentException(getResources().getString(R.string.bad_extension_error));
|
||||||
|
|
||||||
if (isZip) {
|
if (isZip) {
|
||||||
try (ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri));
|
try (ZipInputStream zip = new ZipInputStream(contentResolver.openInputStream(uri));
|
||||||
@ -161,7 +162,7 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
if (throwables.size() == 1)
|
if (throwables.size() == 1)
|
||||||
throw throwables.get(0);
|
throw throwables.get(0);
|
||||||
else if (throwables.isEmpty())
|
else if (throwables.isEmpty())
|
||||||
throw new IllegalArgumentException("No configurations found");
|
throw new IllegalArgumentException(getResources().getString(R.string.no_configs_error));
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompletableFuture.allOf(futureTunnels.toArray(new CompletableFuture[futureTunnels.size()]));
|
return CompletableFuture.allOf(futureTunnels.toArray(new CompletableFuture[futureTunnels.size()]));
|
||||||
|
@ -44,7 +44,8 @@ public class LogExporterPreference extends Preference {
|
|||||||
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
final File file = new File(path, "wireguard-log.txt");
|
final File file = new File(path, "wireguard-log.txt");
|
||||||
if (!path.isDirectory() && !path.mkdirs())
|
if (!path.isDirectory() && !path.mkdirs())
|
||||||
throw new IOException("Cannot create output directory");
|
throw new IOException(
|
||||||
|
getContext().getResources().getString(R.string.create_output_dir_error));
|
||||||
|
|
||||||
/* We would like to simply run `builder.redirectOutput(file);`, but this is API 26.
|
/* We would like to simply run `builder.redirectOutput(file);`, but this is API 26.
|
||||||
* Instead we have to do this dance, since logcat appends.
|
* Instead we have to do this dance, since logcat appends.
|
||||||
|
@ -26,11 +26,11 @@ public class VersionPreference extends Preference {
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
Application.getBackendAsync().thenAccept(backend -> {
|
Application.getBackendAsync().thenAccept(backend -> {
|
||||||
versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypeName().toLowerCase(Locale.ENGLISH));
|
versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypePrettyName().toLowerCase(Locale.ENGLISH));
|
||||||
Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
|
Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
|
||||||
versionSummary = exception == null
|
versionSummary = exception == null
|
||||||
? getContext().getString(R.string.version_summary, backend.getTypeName(), version)
|
? getContext().getString(R.string.version_summary, backend.getTypePrettyName(), version)
|
||||||
: getContext().getString(R.string.version_summary_unknown, backend.getTypeName().toLowerCase(Locale.ENGLISH));
|
: getContext().getString(R.string.version_summary_unknown, backend.getTypePrettyName().toLowerCase(Locale.ENGLISH));
|
||||||
notifyChanged();
|
notifyChanged();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,8 @@ public class ZipExporterPreference extends Preference {
|
|||||||
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()) {
|
||||||
exportZipComplete(null, new IllegalArgumentException("No tunnels exist"));
|
exportZipComplete(null, new IllegalArgumentException(
|
||||||
|
getContext().getResources().getString(R.string.no_tunnels_error)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompletableFuture.allOf(futureConfigs.toArray(new CompletableFuture[futureConfigs.size()]))
|
CompletableFuture.allOf(futureConfigs.toArray(new CompletableFuture[futureConfigs.size()]))
|
||||||
@ -65,7 +66,8 @@ public class ZipExporterPreference extends Preference {
|
|||||||
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");
|
||||||
if (!path.isDirectory() && !path.mkdirs())
|
if (!path.isDirectory() && !path.mkdirs())
|
||||||
throw new IOException("Cannot create output directory");
|
throw new IOException(
|
||||||
|
getContext().getResources().getString(R.string.create_output_dir_error));
|
||||||
try (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"));
|
||||||
|
@ -20,6 +20,7 @@ import java.io.InputStreamReader;
|
|||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,6 +31,7 @@ public class RootShell {
|
|||||||
private static final String SU = "su";
|
private static final String SU = "su";
|
||||||
private static final String TAG = "WireGuard/" + RootShell.class.getSimpleName();
|
private static final String TAG = "WireGuard/" + RootShell.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final String deviceNotRootedMessage;
|
private final String deviceNotRootedMessage;
|
||||||
private final File localBinaryDir;
|
private final File localBinaryDir;
|
||||||
private final File localTemporaryDir;
|
private final File localTemporaryDir;
|
||||||
@ -47,6 +49,7 @@ public class RootShell {
|
|||||||
localTemporaryDir = new File(cacheDir, "tmp");
|
localTemporaryDir = new File(cacheDir, "tmp");
|
||||||
preamble = String.format("export CALLING_PACKAGE=%s PATH=\"%s:$PATH\" TMPDIR='%s'; id -u\n",
|
preamble = String.format("export CALLING_PACKAGE=%s PATH=\"%s:$PATH\" TMPDIR='%s'; id -u\n",
|
||||||
BuildConfig.APPLICATION_ID, localBinaryDir, localTemporaryDir);
|
BuildConfig.APPLICATION_ID, localBinaryDir, localTemporaryDir);
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isExecutableInPath(final String name) {
|
private static boolean isExecutableInPath(final String name) {
|
||||||
@ -121,9 +124,10 @@ public class RootShell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (markersSeen != 4)
|
if (markersSeen != 4)
|
||||||
throw new IOException("Expected 4 markers, received " + markersSeen);
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.marker_count_error), markersSeen));
|
||||||
if (errnoStdout != errnoStderr)
|
if (errnoStdout != errnoStderr)
|
||||||
throw new IOException("Unable to read exit status");
|
throw new IOException(context.getResources().getString(R.string.exit_status_read_error));
|
||||||
Log.v(TAG, "exit: " + errnoStdout);
|
Log.v(TAG, "exit: " + errnoStdout);
|
||||||
return errnoStdout;
|
return errnoStdout;
|
||||||
}
|
}
|
||||||
@ -136,9 +140,9 @@ public class RootShell {
|
|||||||
if (isRunning())
|
if (isRunning())
|
||||||
return;
|
return;
|
||||||
if (!localBinaryDir.isDirectory() && !localBinaryDir.mkdirs())
|
if (!localBinaryDir.isDirectory() && !localBinaryDir.mkdirs())
|
||||||
throw new FileNotFoundException("Could not create local binary directory");
|
throw new FileNotFoundException(context.getResources().getString(R.string.create_bin_dir_error));
|
||||||
if (!localTemporaryDir.isDirectory() && !localTemporaryDir.mkdirs())
|
if (!localTemporaryDir.isDirectory() && !localTemporaryDir.mkdirs())
|
||||||
throw new FileNotFoundException("Could not create local temporary directory");
|
throw new FileNotFoundException(context.getResources().getString(R.string.create_temp_dir_error));
|
||||||
try {
|
try {
|
||||||
final ProcessBuilder builder = new ProcessBuilder().command(SU);
|
final ProcessBuilder builder = new ProcessBuilder().command(SU);
|
||||||
builder.environment().put("LC_ALL", "C");
|
builder.environment().put("LC_ALL", "C");
|
||||||
@ -168,7 +172,8 @@ public class RootShell {
|
|||||||
if (line.contains("Permission denied"))
|
if (line.contains("Permission denied"))
|
||||||
throw new NoRootException(deviceNotRootedMessage);
|
throw new NoRootException(deviceNotRootedMessage);
|
||||||
}
|
}
|
||||||
throw new IOException("Shell failed to start: " + process.exitValue());
|
throw new IOException(String.format(Locale.getDefault(),
|
||||||
|
context.getResources().getString(R.string.shell_start_error), process.exitValue()));
|
||||||
}
|
}
|
||||||
} catch (final IOException | NoRootException e) {
|
} catch (final IOException | NoRootException e) {
|
||||||
stop();
|
stop();
|
||||||
|
@ -12,6 +12,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.wireguard.android.Application;
|
import com.wireguard.android.Application;
|
||||||
import com.wireguard.android.BuildConfig;
|
import com.wireguard.android.BuildConfig;
|
||||||
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.util.RootShell.NoRootException;
|
import com.wireguard.android.util.RootShell.NoRootException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -41,6 +42,7 @@ public final class ToolsInstaller {
|
|||||||
@Nullable private static final File INSTALL_DIR = getInstallDir();
|
@Nullable private static final File INSTALL_DIR = getInstallDir();
|
||||||
private static final String TAG = "WireGuard/" + ToolsInstaller.class.getSimpleName();
|
private static final String TAG = "WireGuard/" + ToolsInstaller.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final File localBinaryDir;
|
private final File localBinaryDir;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
private final File nativeLibraryDir;
|
private final File nativeLibraryDir;
|
||||||
@ -50,6 +52,7 @@ public final class ToolsInstaller {
|
|||||||
public ToolsInstaller(final Context context) {
|
public ToolsInstaller(final Context context) {
|
||||||
localBinaryDir = new File(context.getCacheDir(), "bin");
|
localBinaryDir = new File(context.getCacheDir(), "bin");
|
||||||
nativeLibraryDir = new File(context.getApplicationInfo().nativeLibraryDir);
|
nativeLibraryDir = new File(context.getApplicationInfo().nativeLibraryDir);
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -102,7 +105,8 @@ public final class ToolsInstaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!areToolsAvailable)
|
if (!areToolsAvailable)
|
||||||
throw new FileNotFoundException("Required tools unavailable");
|
throw new FileNotFoundException(
|
||||||
|
context.getResources().getString(R.string.tools_unavailable_error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ public class FloatingActionsMenu extends ViewGroup {
|
|||||||
attr.recycle();
|
attr.recycle();
|
||||||
|
|
||||||
if (mLabelsStyle != 0 && expandsHorizontally()) {
|
if (mLabelsStyle != 0 && expandsHorizontally()) {
|
||||||
throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
|
throw new IllegalStateException(getResources().getString(R.string.horizontal_expand_error));
|
||||||
}
|
}
|
||||||
|
|
||||||
createAddButton(context);
|
createAddButton(context);
|
||||||
|
@ -114,4 +114,34 @@
|
|||||||
<string name="zip_export_error">Unable to export tunnels: %s</string>
|
<string name="zip_export_error">Unable to export tunnels: %s</string>
|
||||||
<string name="zip_export_success">Saved to %s</string>
|
<string name="zip_export_success">Saved to %s</string>
|
||||||
<string name="zip_export_summary">Zip file will be saved to downloads folder</string>
|
<string name="zip_export_summary">Zip file will be saved to downloads folder</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="vpn_not_authed_error">VPN service not authorized by user</string>
|
||||||
|
<string name="vpn_start_error">Unable to start Android VPN service</string>
|
||||||
|
<string name="no_config_error">Trying to bring up a tunnel with no config</string>
|
||||||
|
<string name="tun_create_error">Unable to create tun device</string>
|
||||||
|
<string name="tunnel_on_error">Unable to turn tunnel on (wgTurnOn returned %i)</string>
|
||||||
|
<string name="tunnel_config_error">Unable to configure tunnel (wg-quick returned %i)</string>
|
||||||
|
<string name="module_version_error">Unable to determine kernel module version</string>
|
||||||
|
<string name="config_file_exists_error">Configuration file %s already exists</string>
|
||||||
|
<string name="config_exists_error">Configuration for %s already exists</string>
|
||||||
|
<string name="config_delete_error">Cannot delete configuration file %s</string>
|
||||||
|
<string name="config_rename_error">Cannot rename configuration file %s</string>
|
||||||
|
<string name="config_not_found_error">Configuration file %s not found</string>
|
||||||
|
<string name="no_tunnels_error">No tunnels exist</string>
|
||||||
|
<string name="create_output_dir_error">Cannot create output directory</string>
|
||||||
|
<string name="illegal_filename_error">Illegal file name %s</string>
|
||||||
|
<string name="bad_extension_error">File must be .conf or .zip</string>
|
||||||
|
<string name="no_configs_error">No configurations found</string>
|
||||||
|
<string name="invalid_config_error">Invalid config passed to %s</string>
|
||||||
|
<string name="multiple_tunnels_error">Only one userspace tunnel can run at a time</string>
|
||||||
|
<string name="horizontal_expand_error">Action labels in horizontal expand orientation is not supported.</string>
|
||||||
|
<string name="marker_count_error">Expected 4 markers, received %i</string>
|
||||||
|
<string name="exit_status_read_error">Unable to read exit status</string>
|
||||||
|
<string name="create_bin_dir_error">Could not create local binary directory</string>
|
||||||
|
<string name="create_temp_dir_error">Could not create local temporary directory</string>
|
||||||
|
<string name="shell_start_error">Shell failed to start: %i</string>
|
||||||
|
<string name="tools_unavailable_error">Required tools unavailable</string>
|
||||||
|
<string name="type_name_kernel_module">Kernel module</string>
|
||||||
|
<string name="type_name_go_userspace">Go userspace</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user