summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/com/wireguard/android/backend/Backend.java7
-rw-r--r--app/src/main/java/com/wireguard/android/backend/BackendException.java31
-rw-r--r--app/src/main/java/com/wireguard/android/backend/GoBackend.java23
-rw-r--r--app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java16
-rw-r--r--app/src/main/java/com/wireguard/android/preference/VersionPreference.java17
-rw-r--r--app/src/main/java/com/wireguard/android/util/ErrorMessages.java36
6 files changed, 83 insertions, 47 deletions
diff --git a/app/src/main/java/com/wireguard/android/backend/Backend.java b/app/src/main/java/com/wireguard/android/backend/Backend.java
index 7569b5fa..84e32eb2 100644
--- a/app/src/main/java/com/wireguard/android/backend/Backend.java
+++ b/app/src/main/java/com/wireguard/android/backend/Backend.java
@@ -42,13 +42,6 @@ public interface Backend {
Statistics getStatistics(Tunnel tunnel) throws Exception;
/**
- * Determine type name of underlying backend.
- *
- * @return Type name
- */
- String getTypePrettyName();
-
- /**
* Determine version of underlying backend.
*
* @return The version of the backend.
diff --git a/app/src/main/java/com/wireguard/android/backend/BackendException.java b/app/src/main/java/com/wireguard/android/backend/BackendException.java
new file mode 100644
index 00000000..2994e02a
--- /dev/null
+++ b/app/src/main/java/com/wireguard/android/backend/BackendException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend;
+
+public final class BackendException extends Exception {
+ public enum Reason {
+ UNKNOWN_KERNEL_MODULE_NAME,
+ WG_QUICK_CONFIG_ERROR_CODE,
+ TUNNEL_MISSING_CONFIG,
+ VPN_NOT_AUTHORIZED,
+ UNABLE_TO_START_VPN,
+ TUN_CREATION_ERROR,
+ GO_ACTIVATION_ERROR_CODE
+
+ }
+ private final Reason reason;
+ private final Object[] format;
+ public BackendException(final Reason reason, final Object ...format) {
+ this.reason = reason;
+ this.format = format;
+ }
+ public Reason getReason() {
+ return reason;
+ }
+ public Object[] getFormat() {
+ return format;
+ }
+}
diff --git a/app/src/main/java/com/wireguard/android/backend/GoBackend.java b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
index 6bbf5a3b..00c1d217 100644
--- a/app/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -14,10 +14,8 @@ import androidx.annotation.Nullable;
import androidx.collection.ArraySet;
import android.util.Log;
-import com.wireguard.android.Application;
-import com.wireguard.android.R;
+import com.wireguard.android.backend.BackendException.Reason;
import com.wireguard.android.backend.Tunnel.State;
-import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.SharedLibraryLoader;
import com.wireguard.config.Config;
import com.wireguard.config.InetNetwork;
@@ -28,7 +26,6 @@ import com.wireguard.crypto.KeyFormatException;
import java.net.InetAddress;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -131,11 +128,6 @@ public final class GoBackend implements Backend {
}
@Override
- public String getTypePrettyName() {
- return context.getString(R.string.type_name_go_userspace);
- }
-
- @Override
public String getVersion() {
return wgVersion();
}
@@ -171,10 +163,11 @@ public final class GoBackend implements Backend {
Log.i(TAG, "Bringing tunnel " + tunnel.getName() + " " + state);
if (state == State.UP) {
- Objects.requireNonNull(config, context.getString(R.string.no_config_error));
+ if (config == null)
+ throw new BackendException(Reason.TUNNEL_MISSING_CONFIG);
if (VpnService.prepare(context) != null)
- throw new Exception(context.getString(R.string.vpn_not_authorized_error));
+ throw new BackendException(Reason.VPN_NOT_AUTHORIZED);
final VpnService service;
if (!vpnService.isDone())
@@ -183,7 +176,9 @@ public final class GoBackend implements Backend {
try {
service = vpnService.get(2, TimeUnit.SECONDS);
} catch (final TimeoutException e) {
- throw new Exception(context.getString(R.string.vpn_start_error), e);
+ final Exception be = new BackendException(Reason.UNABLE_TO_START_VPN);
+ be.initCause(e);
+ throw be;
}
service.setOwner(this);
@@ -225,12 +220,12 @@ public final class GoBackend implements Backend {
builder.setBlocking(true);
try (final ParcelFileDescriptor tun = builder.establish()) {
if (tun == null)
- throw new Exception(context.getString(R.string.tun_create_error));
+ throw new BackendException(Reason.TUN_CREATION_ERROR);
Log.d(TAG, "Go backend v" + wgVersion());
currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig);
}
if (currentTunnelHandle < 0)
- throw new Exception(context.getString(R.string.tunnel_on_error, currentTunnelHandle));
+ throw new BackendException(Reason.GO_ACTIVATION_ERROR_CODE, currentTunnelHandle);
currentTunnel = tunnel;
currentConfig = config;
diff --git a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
index e04e6658..5769da66 100644
--- a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
@@ -5,12 +5,13 @@
package com.wireguard.android.backend;
-import android.content.Context;
import androidx.annotation.Nullable;
+
+import android.content.Context;
import android.util.Log;
import com.wireguard.android.Application;
-import com.wireguard.android.R;
+import com.wireguard.android.backend.BackendException.Reason;
import com.wireguard.android.backend.Tunnel.State;
import com.wireguard.config.Config;
import com.wireguard.crypto.Key;
@@ -40,13 +41,11 @@ public final class WgQuickBackend implements Backend {
private static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName();
private final File localTemporaryDir;
- private final Context context;
private final Map<Tunnel, Config> runningConfigs = new HashMap<>();
private final Set<TunnelStateChangeNotificationReceiver> notifiers = new HashSet<>();
public WgQuickBackend(final Context context) {
localTemporaryDir = new File(context.getCacheDir(), "tmp");
- this.context = context;
}
@Override
@@ -93,16 +92,11 @@ public final class WgQuickBackend implements Backend {
}
@Override
- public String getTypePrettyName() {
- return context.getString(R.string.type_name_kernel_module);
- }
-
- @Override
public String getVersion() throws Exception {
final List<String> output = new ArrayList<>();
if (Application.getRootShell()
.run(output, "cat /sys/module/wireguard/version") != 0 || output.isEmpty())
- throw new Exception(context.getString(R.string.module_version_error));
+ throw new BackendException(Reason.UNKNOWN_KERNEL_MODULE_NAME);
return output.get(0);
}
@@ -150,7 +144,7 @@ public final class WgQuickBackend implements Backend {
// noinspection ResultOfMethodCallIgnored
tempFile.delete();
if (result != 0)
- throw new Exception(context.getString(R.string.tunnel_config_error, result));
+ throw new BackendException(Reason.WG_QUICK_CONFIG_ERROR_CODE, result);
if (state == State.UP)
runningConfigs.put(tunnel, config);
diff --git a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
index a0a5d1ff..7e95a8ae 100644
--- a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
@@ -16,21 +16,32 @@ import android.util.AttributeSet;
import com.wireguard.android.Application;
import com.wireguard.android.BuildConfig;
import com.wireguard.android.R;
+import com.wireguard.android.backend.Backend;
+import com.wireguard.android.backend.GoBackend;
+import com.wireguard.android.backend.WgQuickBackend;
import java.util.Locale;
public class VersionPreference extends Preference {
@Nullable private String versionSummary;
+ private String getBackendPrettyName(final Context context, final Backend backend) {
+ if (backend instanceof GoBackend)
+ return context.getString(R.string.type_name_kernel_module);
+ if (backend instanceof WgQuickBackend)
+ return context.getString(R.string.type_name_go_userspace);
+ return "";
+ }
+
public VersionPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
Application.getBackendAsync().thenAccept(backend -> {
- versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypePrettyName().toLowerCase(Locale.ENGLISH));
+ versionSummary = getContext().getString(R.string.version_summary_checking, getBackendPrettyName(context, backend).toLowerCase(Locale.ENGLISH));
Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
versionSummary = exception == null
- ? getContext().getString(R.string.version_summary, backend.getTypePrettyName(), version)
- : getContext().getString(R.string.version_summary_unknown, backend.getTypePrettyName().toLowerCase(Locale.ENGLISH));
+ ? getContext().getString(R.string.version_summary, getBackendPrettyName(context, backend), version)
+ : getContext().getString(R.string.version_summary_unknown, getBackendPrettyName(context, backend).toLowerCase(Locale.ENGLISH));
notifyChanged();
});
});
diff --git a/app/src/main/java/com/wireguard/android/util/ErrorMessages.java b/app/src/main/java/com/wireguard/android/util/ErrorMessages.java
index 7f926541..59d513f4 100644
--- a/app/src/main/java/com/wireguard/android/util/ErrorMessages.java
+++ b/app/src/main/java/com/wireguard/android/util/ErrorMessages.java
@@ -12,9 +12,9 @@ import androidx.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.R;
+import com.wireguard.android.backend.BackendException;
import com.wireguard.config.BadConfigException;
import com.wireguard.config.BadConfigException.Location;
-import com.wireguard.config.BadConfigException.Reason;
import com.wireguard.config.InetEndpoint;
import com.wireguard.config.InetNetwork;
import com.wireguard.config.ParseException;
@@ -29,16 +29,25 @@ import java.util.Map;
import java9.util.Maps;
public final class ErrorMessages {
- private static final Map<Reason, Integer> BCE_REASON_MAP = new EnumMap<>(Maps.of(
- Reason.INVALID_KEY, R.string.bad_config_reason_invalid_key,
- Reason.INVALID_NUMBER, R.string.bad_config_reason_invalid_number,
- Reason.INVALID_VALUE, R.string.bad_config_reason_invalid_value,
- Reason.MISSING_ATTRIBUTE, R.string.bad_config_reason_missing_attribute,
- Reason.MISSING_SECTION, R.string.bad_config_reason_missing_section,
- Reason.MISSING_VALUE, R.string.bad_config_reason_missing_value,
- Reason.SYNTAX_ERROR, R.string.bad_config_reason_syntax_error,
- Reason.UNKNOWN_ATTRIBUTE, R.string.bad_config_reason_unknown_attribute,
- Reason.UNKNOWN_SECTION, R.string.bad_config_reason_unknown_section
+ private static final Map<BadConfigException.Reason, Integer> BCE_REASON_MAP = new EnumMap<>(Maps.of(
+ BadConfigException.Reason.INVALID_KEY, R.string.bad_config_reason_invalid_key,
+ BadConfigException.Reason.INVALID_NUMBER, R.string.bad_config_reason_invalid_number,
+ BadConfigException.Reason.INVALID_VALUE, R.string.bad_config_reason_invalid_value,
+ BadConfigException.Reason.MISSING_ATTRIBUTE, R.string.bad_config_reason_missing_attribute,
+ BadConfigException.Reason.MISSING_SECTION, R.string.bad_config_reason_missing_section,
+ BadConfigException.Reason.MISSING_VALUE, R.string.bad_config_reason_missing_value,
+ BadConfigException.Reason.SYNTAX_ERROR, R.string.bad_config_reason_syntax_error,
+ BadConfigException.Reason.UNKNOWN_ATTRIBUTE, R.string.bad_config_reason_unknown_attribute,
+ BadConfigException.Reason.UNKNOWN_SECTION, R.string.bad_config_reason_unknown_section
+ ));
+ private static final Map<BackendException.Reason, Integer> BE_REASON_MAP = new EnumMap<>(Maps.of(
+ BackendException.Reason.UNKNOWN_KERNEL_MODULE_NAME, R.string.module_version_error,
+ BackendException.Reason.WG_QUICK_CONFIG_ERROR_CODE, R.string.tunnel_config_error,
+ BackendException.Reason.TUNNEL_MISSING_CONFIG, R.string.no_config_error,
+ BackendException.Reason.VPN_NOT_AUTHORIZED, R.string.vpn_not_authorized_error,
+ BackendException.Reason.UNABLE_TO_START_VPN, R.string.vpn_start_error,
+ BackendException.Reason.TUN_CREATION_ERROR, R.string.tun_create_error,
+ BackendException.Reason.GO_ACTIVATION_ERROR_CODE, R.string.tunnel_on_error
));
private static final Map<Format, Integer> KFE_FORMAT_MAP = new EnumMap<>(Maps.of(
Format.BASE64, R.string.key_length_explanation_base64,
@@ -77,6 +86,9 @@ public final class ErrorMessages {
bce.getLocation().getName());
final String explanation = getBadConfigExceptionExplanation(resources, bce);
message = resources.getString(R.string.bad_config_error, reason, context) + explanation;
+ } else if (rootCause instanceof BackendException) {
+ final BackendException be = (BackendException) rootCause;
+ message = resources.getString(BE_REASON_MAP.get(be.getReason()), be.getFormat());
} else if (rootCause.getMessage() != null) {
message = rootCause.getMessage();
} else {
@@ -123,7 +135,7 @@ public final class ErrorMessages {
private static Throwable rootCause(final Throwable throwable) {
Throwable cause = throwable;
while (cause.getCause() != null) {
- if (cause instanceof BadConfigException)
+ if (cause instanceof BadConfigException || cause instanceof BackendException)
break;
final Throwable nextCause = cause.getCause();
if (nextCause instanceof RemoteException)