Clean up error messages
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
dcb0e9b3e8
commit
2e8d566bd4
@ -23,7 +23,7 @@ import android.widget.Toast;
|
|||||||
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;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.widget.SlashDrawable;
|
import com.wireguard.android.widget.SlashDrawable;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -114,7 +114,7 @@ public class QuickTileService extends TileService {
|
|||||||
@Nullable final Throwable throwable) {
|
@Nullable final Throwable throwable) {
|
||||||
if (throwable == null)
|
if (throwable == null)
|
||||||
return;
|
return;
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
final String message = getString(R.string.toggle_error, error);
|
final String message = getString(R.string.toggle_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
||||||
|
@ -126,7 +126,7 @@ public final class GoBackend implements Backend {
|
|||||||
Objects.requireNonNull(config, context.getString(R.string.no_config_error));
|
Objects.requireNonNull(config, context.getString(R.string.no_config_error));
|
||||||
|
|
||||||
if (VpnService.prepare(context) != null)
|
if (VpnService.prepare(context) != null)
|
||||||
throw new Exception(context.getString(R.string.vpn_not_authed_error));
|
throw new Exception(context.getString(R.string.vpn_not_authorized_error));
|
||||||
|
|
||||||
final VpnService service;
|
final VpnService service;
|
||||||
if (!vpnService.isDone())
|
if (!vpnService.isDone())
|
||||||
|
@ -22,7 +22,7 @@ import com.wireguard.android.Application;
|
|||||||
import com.wireguard.android.R;
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.databinding.AppListDialogFragmentBinding;
|
import com.wireguard.android.databinding.AppListDialogFragmentBinding;
|
||||||
import com.wireguard.android.model.ApplicationData;
|
import com.wireguard.android.model.ApplicationData;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.util.ObservableKeyedArrayList;
|
import com.wireguard.android.util.ObservableKeyedArrayList;
|
||||||
import com.wireguard.android.util.ObservableKeyedList;
|
import com.wireguard.android.util.ObservableKeyedList;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ public class AppListDialogFragment extends DialogFragment {
|
|||||||
appData.clear();
|
appData.clear();
|
||||||
appData.addAll(data);
|
appData.addAll(data);
|
||||||
} else {
|
} else {
|
||||||
final String error = throwable != null ? ExceptionLoggers.unwrapMessage(throwable) : "Unknown";
|
final String error = ErrorMessages.get(throwable);
|
||||||
final String message = activity.getString(R.string.error_fetching_apps, error);
|
final String message = activity.getString(R.string.error_fetching_apps, error);
|
||||||
Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
|
Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
|
||||||
dismissAllowingStateLoss();
|
dismissAllowingStateLoss();
|
||||||
|
@ -25,7 +25,7 @@ import com.wireguard.android.databinding.TunnelDetailFragmentBinding;
|
|||||||
import com.wireguard.android.databinding.TunnelListItemBinding;
|
import com.wireguard.android.databinding.TunnelListItemBinding;
|
||||||
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.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for fragments that need to know the currently-selected tunnel. Only does anything when
|
* Base class for fragments that need to know the currently-selected tunnel. Only does anything when
|
||||||
@ -111,7 +111,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
|
|||||||
tunnel.setState(State.of(checked)).whenComplete((state, throwable) -> {
|
tunnel.setState(State.of(checked)).whenComplete((state, throwable) -> {
|
||||||
if (throwable == null)
|
if (throwable == null)
|
||||||
return;
|
return;
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
final int messageResId = checked ? R.string.error_up : R.string.error_down;
|
final int messageResId = checked ? R.string.error_up : R.string.error_down;
|
||||||
final String message = getContext().getString(messageResId, error);
|
final String message = getContext().getString(messageResId, error);
|
||||||
final View view = getView();
|
final View view = getView();
|
||||||
|
@ -27,8 +27,8 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ConfigNamingDialogFragment extends DialogFragment {
|
public class ConfigNamingDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
private static final String KEY_CONFIG_TEXT = "config_text";
|
private static final String KEY_CONFIG_TEXT = "config_text";
|
||||||
|
|
||||||
@Nullable private ConfigNamingDialogFragmentBinding binding;
|
@Nullable private ConfigNamingDialogFragmentBinding binding;
|
||||||
@Nullable private Config config;
|
@Nullable private Config config;
|
||||||
@Nullable private InputMethodManager imm;
|
@Nullable private InputMethodManager imm;
|
||||||
@ -65,23 +65,26 @@ public class ConfigNamingDialogFragment extends DialogFragment {
|
|||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
final Bundle arguments = getArguments();
|
||||||
|
final String configText = arguments.getString(KEY_CONFIG_TEXT);
|
||||||
|
final byte[] configBytes = configText.getBytes(StandardCharsets.UTF_8);
|
||||||
try {
|
try {
|
||||||
config = Config.parse(new ByteArrayInputStream(getArguments().getString(KEY_CONFIG_TEXT).getBytes(StandardCharsets.UTF_8)));
|
config = Config.parse(new ByteArrayInputStream(configBytes));
|
||||||
} catch (final BadConfigException | IOException e) {
|
} catch (final BadConfigException | IOException e) {
|
||||||
throw new RuntimeException(getResources().getString(R.string.invalid_config_error, getClass().getSimpleName()), e);
|
throw new IllegalArgumentException("Invalid config passed to " + getClass().getSimpleName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
final Activity activity = getActivity();
|
final Activity activity = Objects.requireNonNull(getActivity());
|
||||||
|
|
||||||
imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
|
||||||
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
||||||
alertDialogBuilder.setTitle(R.string.import_from_qrcode);
|
alertDialogBuilder.setTitle(R.string.import_from_qr_code);
|
||||||
|
|
||||||
binding = ConfigNamingDialogFragmentBinding.inflate(getActivity().getLayoutInflater(), null, false);
|
binding = ConfigNamingDialogFragmentBinding.inflate(activity.getLayoutInflater(), null, false);
|
||||||
binding.executePendingBindings();
|
binding.executePendingBindings();
|
||||||
alertDialogBuilder.setView(binding.getRoot());
|
alertDialogBuilder.setView(binding.getRoot());
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import com.wireguard.android.databinding.TunnelEditorFragmentBinding;
|
|||||||
import com.wireguard.android.fragment.AppListDialogFragment.AppExclusionListener;
|
import com.wireguard.android.fragment.AppListDialogFragment.AppExclusionListener;
|
||||||
import com.wireguard.android.model.Tunnel;
|
import com.wireguard.android.model.Tunnel;
|
||||||
import com.wireguard.android.model.TunnelManager;
|
import com.wireguard.android.model.TunnelManager;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.viewmodel.ConfigProxy;
|
import com.wireguard.android.viewmodel.ConfigProxy;
|
||||||
import com.wireguard.config.Config;
|
import com.wireguard.config.Config;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
|
|||||||
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
onFinished();
|
onFinished();
|
||||||
} else {
|
} else {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
message = getString(R.string.config_save_error, savedTunnel.getName(), error);
|
message = getString(R.string.config_save_error, savedTunnel.getName(), error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
@ -140,7 +140,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
|
|||||||
try {
|
try {
|
||||||
newConfig = binding.getConfig().resolve();
|
newConfig = binding.getConfig().resolve();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(e);
|
final String error = ErrorMessages.get(e);
|
||||||
final String tunnelName = tunnel == null ? binding.getName() : tunnel.getName();
|
final String tunnelName = tunnel == null ? binding.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);
|
||||||
Log.e(TAG, message, e);
|
Log.e(TAG, message, e);
|
||||||
@ -208,7 +208,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
|
|||||||
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
onFinished();
|
onFinished();
|
||||||
} else {
|
} else {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
message = getString(R.string.tunnel_create_error, error);
|
message = getString(R.string.tunnel_create_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
@ -227,7 +227,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
|
|||||||
Log.d(TAG, "Attempting to save config of renamed tunnel " + tunnel.getName());
|
Log.d(TAG, "Attempting to save config of renamed tunnel " + tunnel.getName());
|
||||||
renamedTunnel.setConfig(newConfig).whenComplete((a, b) -> onConfigSaved(renamedTunnel, b));
|
renamedTunnel.setConfig(newConfig).whenComplete((a, b) -> onConfigSaved(renamedTunnel, b));
|
||||||
} else {
|
} else {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
message = getString(R.string.tunnel_rename_error, error);
|
message = getString(R.string.tunnel_rename_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
|
@ -37,7 +37,7 @@ import com.wireguard.android.databinding.ObservableKeyedRecyclerViewAdapter;
|
|||||||
import com.wireguard.android.databinding.TunnelListFragmentBinding;
|
import com.wireguard.android.databinding.TunnelListFragmentBinding;
|
||||||
import com.wireguard.android.databinding.TunnelListItemBinding;
|
import com.wireguard.android.databinding.TunnelListItemBinding;
|
||||||
import com.wireguard.android.model.Tunnel;
|
import com.wireguard.android.model.Tunnel;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.widget.MultiselectableRelativeLayout;
|
import com.wireguard.android.widget.MultiselectableRelativeLayout;
|
||||||
import com.wireguard.android.widget.fab.FloatingActionsMenuRecyclerViewScrollListener;
|
import com.wireguard.android.widget.fab.FloatingActionsMenuRecyclerViewScrollListener;
|
||||||
import com.wireguard.config.BadConfigException;
|
import com.wireguard.config.BadConfigException;
|
||||||
@ -270,7 +270,7 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
final IntentIntegrator intentIntegrator = IntentIntegrator.forSupportFragment(this);
|
final IntentIntegrator intentIntegrator = IntentIntegrator.forSupportFragment(this);
|
||||||
intentIntegrator.setOrientationLocked(false);
|
intentIntegrator.setOrientationLocked(false);
|
||||||
intentIntegrator.setBeepEnabled(false);
|
intentIntegrator.setBeepEnabled(false);
|
||||||
intentIntegrator.setPrompt(getString(R.string.qrcode_hint));
|
intentIntegrator.setPrompt(getString(R.string.qr_code_hint));
|
||||||
intentIntegrator.initiateScan(Collections.singletonList(IntentIntegrator.QR_CODE));
|
intentIntegrator.initiateScan(Collections.singletonList(IntentIntegrator.QR_CODE));
|
||||||
|
|
||||||
if (binding != null)
|
if (binding != null)
|
||||||
@ -301,7 +301,7 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
message = getResources().getQuantityString(R.plurals.delete_success, count, count);
|
message = getResources().getQuantityString(R.plurals.delete_success, count, count);
|
||||||
} else {
|
} else {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
message = getResources().getQuantityString(R.plurals.delete_error, count, count, error);
|
message = getResources().getQuantityString(R.plurals.delete_error, count, count, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
String message = null;
|
String message = null;
|
||||||
|
|
||||||
for (final Throwable throwable : throwables) {
|
for (final Throwable throwable : throwables) {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
message = getString(R.string.import_error, error);
|
message = getString(R.string.import_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.wireguard.android.Application;
|
import com.wireguard.android.Application;
|
||||||
import com.wireguard.android.R;
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.util.FragmentUtils;
|
import com.wireguard.android.util.FragmentUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@ -76,7 +76,7 @@ public class LogExporterPreference extends Preference {
|
|||||||
|
|
||||||
private void exportLogComplete(final String filePath, @Nullable final Throwable throwable) {
|
private void exportLogComplete(final String filePath, @Nullable final Throwable throwable) {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
final String message = getContext().getString(R.string.log_export_error, error);
|
final String message = getContext().getString(R.string.log_export_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
@ -98,7 +98,7 @@ public class LogExporterPreference extends Preference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTitle() {
|
public CharSequence getTitle() {
|
||||||
return getContext().getString(R.string.log_exporter_title);
|
return getContext().getString(R.string.log_export_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,7 +18,7 @@ import android.util.Log;
|
|||||||
import com.wireguard.android.Application;
|
import com.wireguard.android.Application;
|
||||||
import com.wireguard.android.R;
|
import com.wireguard.android.R;
|
||||||
import com.wireguard.android.model.Tunnel;
|
import com.wireguard.android.model.Tunnel;
|
||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ErrorMessages;
|
||||||
import com.wireguard.android.util.FragmentUtils;
|
import com.wireguard.android.util.FragmentUtils;
|
||||||
import com.wireguard.config.Config;
|
import com.wireguard.config.Config;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ public class ZipExporterPreference extends Preference {
|
|||||||
|
|
||||||
private void exportZipComplete(@Nullable final String filePath, @Nullable final Throwable throwable) {
|
private void exportZipComplete(@Nullable final String filePath, @Nullable final Throwable throwable) {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
final String error = ExceptionLoggers.unwrapMessage(throwable);
|
final String error = ErrorMessages.get(throwable);
|
||||||
final String message = getContext().getString(R.string.zip_export_error, error);
|
final String message = getContext().getString(R.string.zip_export_error, error);
|
||||||
Log.e(TAG, message, throwable);
|
Log.e(TAG, message, throwable);
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
@ -108,7 +108,7 @@ public class ZipExporterPreference extends Preference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTitle() {
|
public CharSequence getTitle() {
|
||||||
return getContext().getString(R.string.zip_exporter_title);
|
return getContext().getString(R.string.zip_export_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
130
app/src/main/java/com/wireguard/android/util/ErrorMessages.java
Normal file
130
app/src/main/java/com/wireguard/android/util/ErrorMessages.java
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wireguard.android.util;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.wireguard.android.Application;
|
||||||
|
import com.wireguard.android.R;
|
||||||
|
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;
|
||||||
|
import com.wireguard.crypto.Key.Format;
|
||||||
|
import com.wireguard.crypto.KeyFormatException;
|
||||||
|
import com.wireguard.crypto.KeyFormatException.Type;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
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<Format, Integer> KFE_FORMAT_MAP = new EnumMap<>(Maps.of(
|
||||||
|
Format.BASE64, R.string.key_length_explanation_base64,
|
||||||
|
Format.BINARY, R.string.key_length_explanation_binary,
|
||||||
|
Format.HEX, R.string.key_length_explanation_hex
|
||||||
|
));
|
||||||
|
private static final Map<Type, Integer> KFE_TYPE_MAP = new EnumMap<>(Maps.of(
|
||||||
|
Type.CONTENTS, R.string.key_contents_error,
|
||||||
|
Type.LENGTH, R.string.key_length_error
|
||||||
|
));
|
||||||
|
private static final Map<Class, Integer> PE_CLASS_MAP = Maps.of(
|
||||||
|
InetAddress.class, R.string.parse_error_inet_address,
|
||||||
|
InetEndpoint.class, R.string.parse_error_inet_endpoint,
|
||||||
|
InetNetwork.class, R.string.parse_error_inet_network,
|
||||||
|
Integer.class, R.string.parse_error_integer
|
||||||
|
);
|
||||||
|
|
||||||
|
private ErrorMessages() {
|
||||||
|
// Prevent instantiation
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get(@Nullable final Throwable throwable) {
|
||||||
|
final Resources resources = Application.get().getResources();
|
||||||
|
if (throwable == null)
|
||||||
|
return resources.getString(R.string.unknown_error);
|
||||||
|
final Throwable rootCause = rootCause(throwable);
|
||||||
|
final String message;
|
||||||
|
if (rootCause instanceof BadConfigException) {
|
||||||
|
final BadConfigException bce = (BadConfigException) rootCause;
|
||||||
|
final String reason = getBadConfigExceptionReason(resources, bce);
|
||||||
|
final String context = bce.getLocation() == Location.TOP_LEVEL ?
|
||||||
|
resources.getString(R.string.bad_config_context_top_level,
|
||||||
|
bce.getSection().getName()) :
|
||||||
|
resources.getString(R.string.bad_config_context,
|
||||||
|
bce.getSection().getName(),
|
||||||
|
bce.getLocation().getName());
|
||||||
|
final String explanation = getBadConfigExceptionExplanation(resources, bce);
|
||||||
|
message = resources.getString(R.string.bad_config_error, reason, context) + explanation;
|
||||||
|
} else if (rootCause.getMessage() != null) {
|
||||||
|
message = rootCause.getMessage();
|
||||||
|
} else {
|
||||||
|
final String errorType = rootCause.getClass().getSimpleName();
|
||||||
|
message = resources.getString(R.string.generic_error, errorType);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getBadConfigExceptionExplanation(final Resources resources,
|
||||||
|
final BadConfigException bce) {
|
||||||
|
if (bce.getCause() instanceof KeyFormatException) {
|
||||||
|
final KeyFormatException kfe = (KeyFormatException) bce.getCause();
|
||||||
|
if (kfe.getType() == Type.LENGTH)
|
||||||
|
return resources.getString(KFE_FORMAT_MAP.get(kfe.getFormat()));
|
||||||
|
} else if (bce.getCause() instanceof ParseException) {
|
||||||
|
final ParseException pe = (ParseException) bce.getCause();
|
||||||
|
if (pe.getMessage() != null)
|
||||||
|
return ": " + pe.getMessage();
|
||||||
|
} else if (bce.getLocation() == Location.LISTEN_PORT) {
|
||||||
|
return resources.getString(R.string.bad_config_explanation_udp_port);
|
||||||
|
} else if (bce.getLocation() == Location.MTU) {
|
||||||
|
return resources.getString(R.string.bad_config_explanation_positive_number);
|
||||||
|
} else if (bce.getLocation() == Location.PERSISTENT_KEEPALIVE) {
|
||||||
|
return resources.getString(R.string.bad_config_explanation_pka);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getBadConfigExceptionReason(final Resources resources,
|
||||||
|
final BadConfigException bce) {
|
||||||
|
if (bce.getCause() instanceof KeyFormatException) {
|
||||||
|
final KeyFormatException kfe = (KeyFormatException) bce.getCause();
|
||||||
|
return resources.getString(KFE_TYPE_MAP.get(kfe.getType()));
|
||||||
|
} else if (bce.getCause() instanceof ParseException) {
|
||||||
|
final ParseException pe = (ParseException) bce.getCause();
|
||||||
|
final String type = resources.getString(PE_CLASS_MAP.containsKey(pe.getParsingClass()) ?
|
||||||
|
PE_CLASS_MAP.get(pe.getParsingClass()) : R.string.parse_error_generic);
|
||||||
|
return resources.getString(R.string.parse_error_reason, type, pe.getText());
|
||||||
|
}
|
||||||
|
return resources.getString(BCE_REASON_MAP.get(bce.getReason()), bce.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Throwable rootCause(final Throwable throwable) {
|
||||||
|
Throwable cause = throwable;
|
||||||
|
while (cause.getCause() != null) {
|
||||||
|
if (cause instanceof BadConfigException)
|
||||||
|
break;
|
||||||
|
cause = cause.getCause();
|
||||||
|
}
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
}
|
@ -5,17 +5,9 @@
|
|||||||
|
|
||||||
package com.wireguard.android.util;
|
package com.wireguard.android.util;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.wireguard.android.Application;
|
|
||||||
import com.wireguard.android.R;
|
|
||||||
import com.wireguard.config.BadConfigException;
|
|
||||||
import com.wireguard.config.ParseException;
|
|
||||||
import com.wireguard.crypto.KeyFormatException;
|
|
||||||
|
|
||||||
import java9.util.concurrent.CompletionException;
|
|
||||||
import java9.util.function.BiConsumer;
|
import java9.util.function.BiConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,53 +20,12 @@ public enum ExceptionLoggers implements BiConsumer<Object, Throwable> {
|
|||||||
E(Log.ERROR);
|
E(Log.ERROR);
|
||||||
|
|
||||||
private static final String TAG = "WireGuard/" + ExceptionLoggers.class.getSimpleName();
|
private static final String TAG = "WireGuard/" + ExceptionLoggers.class.getSimpleName();
|
||||||
|
|
||||||
private final int priority;
|
private final int priority;
|
||||||
|
|
||||||
ExceptionLoggers(final int priority) {
|
ExceptionLoggers(final int priority) {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Throwable unwrap(final Throwable throwable) {
|
|
||||||
if (throwable instanceof CompletionException && throwable.getCause() != null)
|
|
||||||
return throwable.getCause();
|
|
||||||
if (throwable instanceof ParseException && throwable.getCause() != null)
|
|
||||||
return throwable.getCause();
|
|
||||||
return throwable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String unwrapMessage(final Throwable throwable) {
|
|
||||||
final Throwable innerThrowable = unwrap(throwable);
|
|
||||||
final Resources resources = Application.get().getResources();
|
|
||||||
String message;
|
|
||||||
if (innerThrowable instanceof BadConfigException) {
|
|
||||||
final BadConfigException configException = (BadConfigException) innerThrowable;
|
|
||||||
message = resources.getString(R.string.parse_error, configException.getText(), configException.getLocation());
|
|
||||||
final Throwable cause = unwrap(configException);
|
|
||||||
if (cause.getMessage() != null)
|
|
||||||
message += ": " + cause.getMessage();
|
|
||||||
} else if (innerThrowable instanceof KeyFormatException) {
|
|
||||||
final KeyFormatException keyFormatException = (KeyFormatException) innerThrowable;
|
|
||||||
switch (keyFormatException.getFormat()) {
|
|
||||||
case BASE64:
|
|
||||||
message = resources.getString(R.string.key_length_base64_exception_message);
|
|
||||||
break;
|
|
||||||
case BINARY:
|
|
||||||
message = resources.getString(R.string.key_length_exception_message);
|
|
||||||
break;
|
|
||||||
case HEX:
|
|
||||||
message = resources.getString(R.string.key_length_hex_exception_message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Will never happen, as getFormat is not nullable.
|
|
||||||
message = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message = innerThrowable.getMessage();
|
|
||||||
}
|
|
||||||
return message != null ? message : innerThrowable.getClass().getSimpleName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(final Object result, @Nullable final Throwable throwable) {
|
public void accept(final Object result, @Nullable final Throwable throwable) {
|
||||||
if (throwable != null)
|
if (throwable != null)
|
||||||
|
@ -123,9 +123,9 @@ public class RootShell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (markersSeen != 4)
|
if (markersSeen != 4)
|
||||||
throw new IOException(context.getString(R.string.marker_count_error, markersSeen));
|
throw new IOException(context.getString(R.string.shell_marker_count_error, markersSeen));
|
||||||
if (errnoStdout != errnoStderr)
|
if (errnoStdout != errnoStderr)
|
||||||
throw new IOException(context.getString(R.string.exit_status_read_error));
|
throw new IOException(context.getString(R.string.shell_exit_status_read_error));
|
||||||
Log.v(TAG, "exit: " + errnoStdout);
|
Log.v(TAG, "exit: " + errnoStdout);
|
||||||
return errnoStdout;
|
return errnoStdout;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ public class FloatingActionsMenu extends ViewGroup {
|
|||||||
attr.recycle();
|
attr.recycle();
|
||||||
|
|
||||||
if (mLabelsStyle != 0 && expandsHorizontally()) {
|
if (mLabelsStyle != 0 && expandsHorizontally()) {
|
||||||
throw new IllegalStateException(getResources().getString(R.string.horizontal_expand_error));
|
throw new IllegalStateException("Action labels in horizontal expand orientation are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
createAddButton(context);
|
createAddButton(context);
|
||||||
|
@ -89,7 +89,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:onClick="@{fragment::onRequestScanQRCode}"
|
android:onClick="@{fragment::onRequestScanQRCode}"
|
||||||
app:fabSize="mini"
|
app:fabSize="mini"
|
||||||
app:fab_title="@string/create_from_qrcode"
|
app:fab_title="@string/create_from_qr_code"
|
||||||
app:srcCompat="@drawable/ic_action_scan_qr_code_white" />
|
app:srcCompat="@drawable/ic_action_scan_qr_code_white" />
|
||||||
|
|
||||||
<com.wireguard.android.widget.fab.LabeledFloatingActionButton
|
<com.wireguard.android.widget.fab.LabeledFloatingActionButton
|
||||||
|
@ -28,25 +28,41 @@
|
|||||||
<string name="addresses">Addresses</string>
|
<string name="addresses">Addresses</string>
|
||||||
<string name="allowed_ips">Allowed IPs</string>
|
<string name="allowed_ips">Allowed IPs</string>
|
||||||
<string name="app_name">WireGuard</string>
|
<string name="app_name">WireGuard</string>
|
||||||
|
<string name="bad_config_context">%s\'s %s</string>
|
||||||
|
<string name="bad_config_context_top_level">%s</string>
|
||||||
|
<string name="bad_config_error">%s in %s</string>
|
||||||
|
<string name="bad_config_explanation_pka">: Must be positive and no more than 65535</string>
|
||||||
|
<string name="bad_config_explanation_positive_number">: Must be positive</string>
|
||||||
|
<string name="bad_config_explanation_udp_port">: Must be a valid UDP port number</string>
|
||||||
|
<string name="bad_config_reason_invalid_key">Invalid key</string>
|
||||||
|
<string name="bad_config_reason_invalid_number">Invalid number</string>
|
||||||
|
<string name="bad_config_reason_invalid_value">Invalid value</string>
|
||||||
|
<string name="bad_config_reason_missing_attribute">Missing attribute</string>
|
||||||
|
<string name="bad_config_reason_missing_section">Missing section</string>
|
||||||
|
<string name="bad_config_reason_missing_value">Missing value</string>
|
||||||
|
<string name="bad_config_reason_syntax_error">Syntax error</string>
|
||||||
|
<string name="bad_config_reason_unknown_attribute">Unknown attribute</string>
|
||||||
|
<string name="bad_config_reason_unknown_section">Unknown section</string>
|
||||||
|
<string name="bad_config_reason_value_out_of_range">Value out of range</string>
|
||||||
<string name="bad_extension_error">File must be .conf or .zip</string>
|
<string name="bad_extension_error">File must be .conf or .zip</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="config_delete_error">Cannot delete configuration file %s</string>
|
<string name="config_delete_error">Cannot delete configuration file %s</string>
|
||||||
<string name="config_exists_error">Configuration for %s already exists</string>
|
<string name="config_exists_error">Configuration for “%s” already exists</string>
|
||||||
<string name="config_file_exists_error">Configuration file %s already exists</string>
|
<string name="config_file_exists_error">Configuration file “%s” already exists</string>
|
||||||
<string name="config_not_found_error">Configuration file %s not found</string>
|
<string name="config_not_found_error">Configuration file “%s” not found</string>
|
||||||
<string name="config_rename_error">Cannot rename configuration file %s</string>
|
<string name="config_rename_error">Cannot rename configuration file “%s”</string>
|
||||||
<string name="config_save_error">Unable to save configuration for “%1$s”: %2$s</string>
|
<string name="config_save_error">Cannot save configuration for “%1$s”: %2$s</string>
|
||||||
<string name="config_save_success">Successfully saved configuration for “%s”</string>
|
<string name="config_save_success">Successfully saved configuration for “%s”</string>
|
||||||
<string name="create_activity_title">Create WireGuard Tunnel</string>
|
<string name="create_activity_title">Create WireGuard Tunnel</string>
|
||||||
<string name="create_bin_dir_error">Could not create local binary directory</string>
|
<string name="create_bin_dir_error">Cannot create local binary directory</string>
|
||||||
<string name="create_empty">Create from scratch</string>
|
<string name="create_empty">Create from scratch</string>
|
||||||
<string name="create_from_file">Create from file or archive</string>
|
<string name="create_from_file">Create from file or archive</string>
|
||||||
<string name="create_from_qrcode">Create from QR code</string>
|
<string name="create_from_qr_code">Create from QR code</string>
|
||||||
<string name="create_output_dir_error">Cannot create output directory</string>
|
<string name="create_output_dir_error">Cannot create output directory</string>
|
||||||
<string name="create_temp_dir_error">Could not create local temporary directory</string>
|
<string name="create_temp_dir_error">Cannot create local temporary directory</string>
|
||||||
<string name="create_tunnel">Create Tunnel</string>
|
<string name="create_tunnel">Create Tunnel</string>
|
||||||
<string name="dark_theme_summary_off">Currently using light day theme</string>
|
<string name="dark_theme_summary_off">Currently using light (day) theme</string>
|
||||||
<string name="dark_theme_summary_on">Currently using dark night theme</string>
|
<string name="dark_theme_summary_on">Currently using dark (night) theme</string>
|
||||||
<string name="dark_theme_title">Use dark theme</string>
|
<string name="dark_theme_title">Use dark theme</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="deselect_all">Deselect All</string>
|
<string name="deselect_all">Deselect All</string>
|
||||||
@ -59,28 +75,25 @@
|
|||||||
<string name="error_up">Error bringing up tunnel: %s</string>
|
<string name="error_up">Error bringing up tunnel: %s</string>
|
||||||
<string name="exclude_private_ips">Exclude private IPs</string>
|
<string name="exclude_private_ips">Exclude private IPs</string>
|
||||||
<string name="excluded_applications">Excluded Applications</string>
|
<string name="excluded_applications">Excluded Applications</string>
|
||||||
<string name="exit_status_read_error">Unable to read exit status</string>
|
|
||||||
<string name="generate">Generate</string>
|
<string name="generate">Generate</string>
|
||||||
|
<string name="generic_error">Unknown “%s” error</string>
|
||||||
<string name="hint_automatic">(auto)</string>
|
<string name="hint_automatic">(auto)</string>
|
||||||
<string name="hint_generated">(generated)</string>
|
<string name="hint_generated">(generated)</string>
|
||||||
<string name="hint_optional">(optional)</string>
|
<string name="hint_optional">(optional)</string>
|
||||||
<string name="hint_random">(random)</string>
|
<string name="hint_random">(random)</string>
|
||||||
<string name="horizontal_expand_error">Action labels in horizontal expand orientation is not supported.</string>
|
<string name="illegal_filename_error">Illegal file name “%s”</string>
|
||||||
<string name="illegal_filename_error">Illegal file name %s</string>
|
|
||||||
<string name="import_error">Unable to import tunnel: %s</string>
|
<string name="import_error">Unable to import tunnel: %s</string>
|
||||||
<string name="import_from_qrcode">Import Tunnel from QR Code</string>
|
<string name="import_from_qr_code">Import Tunnel from QR Code</string>
|
||||||
<string name="import_success">Imported “%s”</string>
|
<string name="import_success">Imported “%s”</string>
|
||||||
<string name="interface_title">Interface</string>
|
<string name="interface_title">Interface</string>
|
||||||
<string name="invalid_config_error">Invalid config passed to %s</string>
|
<string name="key_length_explanation_base64">: WireGuard base64 keys must be 44 characters (32 bytes)</string>
|
||||||
<string name="key_length_base64_exception_message">WireGuard base64 keys must be 44 characters encoding 32 bytes</string>
|
<string name="key_length_explanation_binary">: WireGuard keys must be 32 bytes</string>
|
||||||
<string name="key_length_exception_message">WireGuard keys must be 32 bytes</string>
|
<string name="key_length_explanation_hex">: WireGuard hex keys must be 64 characters (32 bytes)</string>
|
||||||
<string name="key_length_hex_exception_message">WireGuard hex keys must be 64 characters encoding 32 bytes</string>
|
|
||||||
<string name="listen_port">Listen port</string>
|
<string name="listen_port">Listen port</string>
|
||||||
<string name="log_export_error">Unable to export log: %s</string>
|
<string name="log_export_error">Unable to export log: %s</string>
|
||||||
<string name="log_export_success">Saved to %s</string>
|
<string name="log_export_success">Saved to “%s”</string>
|
||||||
<string name="log_export_summary">Log file will be saved to downloads folder</string>
|
<string name="log_export_summary">Log file will be saved to downloads folder</string>
|
||||||
<string name="log_exporter_title">Export log file</string>
|
<string name="log_export_title">Export log file</string>
|
||||||
<string name="marker_count_error">Expected 4 markers, received %i</string>
|
|
||||||
<string name="module_version_error">Unable to determine kernel module version</string>
|
<string name="module_version_error">Unable to determine kernel module version</string>
|
||||||
<string name="mtu">MTU</string>
|
<string name="mtu">MTU</string>
|
||||||
<string name="multiple_tunnels_error">Only one userspace tunnel can run at a time</string>
|
<string name="multiple_tunnels_error">Only one userspace tunnel can run at a time</string>
|
||||||
@ -88,7 +101,12 @@
|
|||||||
<string name="no_config_error">Trying to bring up a tunnel with no config</string>
|
<string name="no_config_error">Trying to bring up a tunnel with no config</string>
|
||||||
<string name="no_configs_error">No configurations found</string>
|
<string name="no_configs_error">No configurations found</string>
|
||||||
<string name="no_tunnels_error">No tunnels exist</string>
|
<string name="no_tunnels_error">No tunnels exist</string>
|
||||||
<string name="parse_error">Cannot parse “%1$s” at %2$s</string>
|
<string name="parse_error_generic">string</string>
|
||||||
|
<string name="parse_error_inet_address">IP address</string>
|
||||||
|
<string name="parse_error_inet_endpoint">endpoint</string>
|
||||||
|
<string name="parse_error_inet_network">IP network</string>
|
||||||
|
<string name="parse_error_integer">number</string>
|
||||||
|
<string name="parse_error_reason">Cannot parse %1$s “%2$s”</string>
|
||||||
<string name="peer">Peer</string>
|
<string name="peer">Peer</string>
|
||||||
<string name="permission_description">Allows an app to control WireGuard tunnels. Apps with this permission may enable and disable WireGuard tunnels at will, potentially misdirecting Internet traffic.</string>
|
<string name="permission_description">Allows an app to control WireGuard tunnels. Apps with this permission may enable and disable WireGuard tunnels at will, potentially misdirecting Internet traffic.</string>
|
||||||
<string name="permission_label">control WireGuard tunnels</string>
|
<string name="permission_label">control WireGuard tunnels</string>
|
||||||
@ -97,13 +115,15 @@
|
|||||||
<string name="private_key">Private key</string>
|
<string name="private_key">Private key</string>
|
||||||
<string name="public_key">Public key</string>
|
<string name="public_key">Public key</string>
|
||||||
<string name="public_key_description">Public key</string>
|
<string name="public_key_description">Public key</string>
|
||||||
<string name="qrcode_hint">Tip: generate with `qrencode -t ansiutf8 < tunnel.conf`.</string>
|
<string name="qr_code_hint">Tip: generate with `qrencode -t ansiutf8 < tunnel.conf`.</string>
|
||||||
<string name="restore_on_boot_summary">Bring up previously-enabled tunnels on boot</string>
|
<string name="restore_on_boot_summary">Bring up previously-enabled tunnels on boot</string>
|
||||||
<string name="restore_on_boot_title">Restore on boot</string>
|
<string name="restore_on_boot_title">Restore on boot</string>
|
||||||
<string name="save">Save</string>
|
<string name="save">Save</string>
|
||||||
<string name="select_all">Select all</string>
|
<string name="select_all">Select all</string>
|
||||||
<string name="set_exclusions">Set Exclusions</string>
|
<string name="set_exclusions">Set Exclusions</string>
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
|
<string name="shell_exit_status_read_error">Shell cannot read exit status</string>
|
||||||
|
<string name="shell_marker_count_error">Shell expected 4 markers, received %i</string>
|
||||||
<string name="shell_start_error">Shell failed to start: %i</string>
|
<string name="shell_start_error">Shell failed to start: %i</string>
|
||||||
<string name="toggle_error">Error toggling WireGuard tunnel: %s</string>
|
<string name="toggle_error">Error toggling WireGuard tunnel: %s</string>
|
||||||
<string name="tools_installer_already">wg and wg-quick are already installed</string>
|
<string name="tools_installer_already">wg and wg-quick are already installed</string>
|
||||||
@ -120,10 +140,7 @@
|
|||||||
<string name="tunnel_config_error">Unable to configure tunnel (wg-quick returned %i)</string>
|
<string name="tunnel_config_error">Unable to configure tunnel (wg-quick returned %i)</string>
|
||||||
<string name="tunnel_create_error">Unable to create tunnel: %s</string>
|
<string name="tunnel_create_error">Unable to create tunnel: %s</string>
|
||||||
<string name="tunnel_create_success">Successfully created tunnel “%s”</string>
|
<string name="tunnel_create_success">Successfully created tunnel “%s”</string>
|
||||||
<string name="tunnel_error_already_exists">Tunnel %s already exists</string>
|
<string name="tunnel_error_already_exists">Tunnel “%s” already exists</string>
|
||||||
<string name="tunnel_error_empty_interface_address">Address is empty</string>
|
|
||||||
<string name="tunnel_error_empty_peer_public_key">Peer public key may not be empty</string>
|
|
||||||
<string name="tunnel_error_forbidden_endpoint_chars">Forbidden characters in endpoint</string>
|
|
||||||
<string name="tunnel_error_invalid_name">Invalid name</string>
|
<string name="tunnel_error_invalid_name">Invalid name</string>
|
||||||
<string name="tunnel_list_placeholder">Add a tunnel using the blue button</string>
|
<string name="tunnel_list_placeholder">Add a tunnel using the blue button</string>
|
||||||
<string name="tunnel_name">Tunnel Name</string>
|
<string name="tunnel_name">Tunnel Name</string>
|
||||||
@ -132,14 +149,17 @@
|
|||||||
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string>
|
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string>
|
||||||
<string name="type_name_go_userspace">Go userspace</string>
|
<string name="type_name_go_userspace">Go userspace</string>
|
||||||
<string name="type_name_kernel_module">Kernel module</string>
|
<string name="type_name_kernel_module">Kernel module</string>
|
||||||
|
<string name="unknown_error">Unknown error</string>
|
||||||
<string name="version_summary">%1$s backend v%2$s</string>
|
<string name="version_summary">%1$s backend v%2$s</string>
|
||||||
<string name="version_summary_checking">Checking %s backend version</string>
|
<string name="version_summary_checking">Checking %s backend version</string>
|
||||||
<string name="version_summary_unknown">Unknown %s version</string>
|
<string name="version_summary_unknown">Unknown %s version</string>
|
||||||
<string name="version_title">WireGuard for Android v%s"</string>
|
<string name="version_title">WireGuard for Android v%s</string>
|
||||||
<string name="vpn_not_authed_error">VPN service not authorized by user</string>
|
<string name="vpn_not_authorized_error">VPN service not authorized by user</string>
|
||||||
<string name="vpn_start_error">Unable to start Android VPN service</string>
|
<string name="vpn_start_error">Unable to start Android VPN service</string>
|
||||||
<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="zip_exporter_title">Export tunnels to zip file</string>
|
<string name="zip_export_title">Export tunnels to zip file</string>
|
||||||
|
<string name="key_length_error">Incorrect key length</string>
|
||||||
|
<string name="key_contents_error">Bad characters in key</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user