浏览代码

ErrorMessages: do not use R from backend

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
master
Jason A. Donenfeld 4 年前
父节点
当前提交
afd75cc4cf
共有 6 个文件被更改,包括 83 次插入47 次删除
  1. +0
    -7
      app/src/main/java/com/wireguard/android/backend/Backend.java
  2. +31
    -0
      app/src/main/java/com/wireguard/android/backend/BackendException.java
  3. +9
    -14
      app/src/main/java/com/wireguard/android/backend/GoBackend.java
  4. +5
    -11
      app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
  5. +14
    -3
      app/src/main/java/com/wireguard/android/preference/VersionPreference.java
  6. +24
    -12
      app/src/main/java/com/wireguard/android/util/ErrorMessages.java

+ 0
- 7
app/src/main/java/com/wireguard/android/backend/Backend.java 查看文件

@@ -41,13 +41,6 @@ public interface Backend {
*/ */
Statistics getStatistics(Tunnel tunnel) throws Exception; Statistics getStatistics(Tunnel tunnel) throws Exception;


/**
* Determine type name of underlying backend.
*
* @return Type name
*/
String getTypePrettyName();

/** /**
* Determine version of underlying backend. * Determine version of underlying backend.
* *


+ 31
- 0
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;
}
}

+ 9
- 14
app/src/main/java/com/wireguard/android/backend/GoBackend.java 查看文件

@@ -14,10 +14,8 @@ import androidx.annotation.Nullable;
import androidx.collection.ArraySet; import androidx.collection.ArraySet;
import android.util.Log; 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.backend.Tunnel.State;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.SharedLibraryLoader; import com.wireguard.android.util.SharedLibraryLoader;
import com.wireguard.config.Config; import com.wireguard.config.Config;
import com.wireguard.config.InetNetwork; import com.wireguard.config.InetNetwork;
@@ -28,7 +26,6 @@ import com.wireguard.crypto.KeyFormatException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@@ -130,11 +127,6 @@ public final class GoBackend implements Backend {
return stats; return stats;
} }


@Override
public String getTypePrettyName() {
return context.getString(R.string.type_name_go_userspace);
}

@Override @Override
public String getVersion() { public String getVersion() {
return wgVersion(); return wgVersion();
@@ -171,10 +163,11 @@ public final class GoBackend implements Backend {
Log.i(TAG, "Bringing tunnel " + tunnel.getName() + " " + state); Log.i(TAG, "Bringing tunnel " + tunnel.getName() + " " + state);


if (state == State.UP) { 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) 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; final VpnService service;
if (!vpnService.isDone()) if (!vpnService.isDone())
@@ -183,7 +176,9 @@ 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(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); service.setOwner(this);


@@ -225,12 +220,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(context.getString(R.string.tun_create_error));
throw new BackendException(Reason.TUN_CREATION_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(context.getString(R.string.tunnel_on_error, currentTunnelHandle));
throw new BackendException(Reason.GO_ACTIVATION_ERROR_CODE, currentTunnelHandle);


currentTunnel = tunnel; currentTunnel = tunnel;
currentConfig = config; currentConfig = config;


+ 5
- 11
app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java 查看文件

@@ -5,12 +5,13 @@


package com.wireguard.android.backend; package com.wireguard.android.backend;


import android.content.Context;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;

import android.content.Context;
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.backend.BackendException.Reason;
import com.wireguard.android.backend.Tunnel.State; import com.wireguard.android.backend.Tunnel.State;
import com.wireguard.config.Config; import com.wireguard.config.Config;
import com.wireguard.crypto.Key; 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 static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName();


private final File localTemporaryDir; private final File localTemporaryDir;
private final Context context;
private final Map<Tunnel, Config> runningConfigs = new HashMap<>(); private final Map<Tunnel, Config> runningConfigs = new HashMap<>();
private final Set<TunnelStateChangeNotificationReceiver> notifiers = new HashSet<>(); private final Set<TunnelStateChangeNotificationReceiver> notifiers = new HashSet<>();


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
@@ -92,17 +91,12 @@ public final class WgQuickBackend implements Backend {
return stats; return stats;
} }


@Override
public String getTypePrettyName() {
return context.getString(R.string.type_name_kernel_module);
}

@Override @Override
public String getVersion() throws Exception { public String getVersion() throws Exception {
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(context.getString(R.string.module_version_error));
throw new BackendException(Reason.UNKNOWN_KERNEL_MODULE_NAME);
return output.get(0); return output.get(0);
} }


@@ -150,7 +144,7 @@ public final class WgQuickBackend implements Backend {
// noinspection ResultOfMethodCallIgnored // noinspection ResultOfMethodCallIgnored
tempFile.delete(); tempFile.delete();
if (result != 0) 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) if (state == State.UP)
runningConfigs.put(tunnel, config); runningConfigs.put(tunnel, config);


+ 14
- 3
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.Application;
import com.wireguard.android.BuildConfig; import com.wireguard.android.BuildConfig;
import com.wireguard.android.R; 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; import java.util.Locale;


public class VersionPreference extends Preference { public class VersionPreference extends Preference {
@Nullable private String versionSummary; @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) { public VersionPreference(final Context context, final AttributeSet attrs) {
super(context, attrs); super(context, attrs);


Application.getBackendAsync().thenAccept(backend -> { 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) -> { Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
versionSummary = exception == null 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(); notifyChanged();
}); });
}); });


+ 24
- 12
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.Application;
import com.wireguard.android.R; import com.wireguard.android.R;
import com.wireguard.android.backend.BackendException;
import com.wireguard.config.BadConfigException; import com.wireguard.config.BadConfigException;
import com.wireguard.config.BadConfigException.Location; import com.wireguard.config.BadConfigException.Location;
import com.wireguard.config.BadConfigException.Reason;
import com.wireguard.config.InetEndpoint; import com.wireguard.config.InetEndpoint;
import com.wireguard.config.InetNetwork; import com.wireguard.config.InetNetwork;
import com.wireguard.config.ParseException; import com.wireguard.config.ParseException;
@@ -29,16 +29,25 @@ import java.util.Map;
import java9.util.Maps; import java9.util.Maps;


public final class ErrorMessages { 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( private static final Map<Format, Integer> KFE_FORMAT_MAP = new EnumMap<>(Maps.of(
Format.BASE64, R.string.key_length_explanation_base64, Format.BASE64, R.string.key_length_explanation_base64,
@@ -77,6 +86,9 @@ public final class ErrorMessages {
bce.getLocation().getName()); bce.getLocation().getName());
final String explanation = getBadConfigExceptionExplanation(resources, bce); final String explanation = getBadConfigExceptionExplanation(resources, bce);
message = resources.getString(R.string.bad_config_error, reason, context) + explanation; 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) { } else if (rootCause.getMessage() != null) {
message = rootCause.getMessage(); message = rootCause.getMessage();
} else { } else {
@@ -123,7 +135,7 @@ public final class ErrorMessages {
private static Throwable rootCause(final Throwable throwable) { private static Throwable rootCause(final Throwable throwable) {
Throwable cause = throwable; Throwable cause = throwable;
while (cause.getCause() != null) { while (cause.getCause() != null) {
if (cause instanceof BadConfigException)
if (cause instanceof BadConfigException || cause instanceof BackendException)
break; break;
final Throwable nextCause = cause.getCause(); final Throwable nextCause = cause.getCause();
if (nextCause instanceof RemoteException) if (nextCause instanceof RemoteException)


正在加载...
取消
保存