summaryrefslogtreecommitdiff
path: root/app/src/main/java/se
diff options
context:
space:
mode:
authorcyberta <cyberta@riseup.net>2025-04-15 01:00:08 +0000
committercyberta <cyberta@riseup.net>2025-04-15 01:00:08 +0000
commita9f2c30d415e1349616101a11ddfa0719995ef8d (patch)
tree70838b6149deb178fc31a45cd8f38e55c110c1be /app/src/main/java/se
parent1b668a3163ce2d824486f045a9f0a0b1ee29256f (diff)
show error dialog in case invite code scanning fails
Diffstat (limited to 'app/src/main/java/se')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java86
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java55
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/helpers/AbstractQrScannerHelper.java3
9 files changed, 133 insertions, 38 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
index e3175010..fe30a324 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
@@ -1,15 +1,30 @@
package se.leap.bitmaskclient.base.models;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.ADDRESS_FORMAT;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.AUTH_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.CERTIFICATE_LENGTH;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.CERTIFICATE_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_INVALID;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_LENGTH;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.UNKNOWN_TYPE;
+
+import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.Nullable;
+
import java.io.UnsupportedEncodingException;
import java.net.IDN;
import java.net.URISyntaxException;
import java.net.URLEncoder;
+import java.util.IllegalFormatException;
import java.util.Locale;
+import se.leap.bitmaskclient.R;
+
public class Introducer implements Parcelable {
private final String type;
private final String address;
@@ -69,45 +84,52 @@ public class Introducer implements Parcelable {
public boolean validate() {
if (!"obfsvpnintro".equals(type)) {
- throw new IllegalArgumentException("Unknown type: " + type);
+ throw new IntroducerException(UNKNOWN_TYPE, "Unknown type: ", type);
}
if (!address.contains(":") || address.split(":").length != 2) {
- throw new IllegalArgumentException("Expected address in format ipaddr:port");
+ throw new IntroducerException(ADDRESS_FORMAT, "Expected address in format ipaddr:port");
}
if (certificate.length() != 70) {
- throw new IllegalArgumentException("Wrong certificate length: " + certificate.length());
+ throw new IntroducerException(CERTIFICATE_LENGTH, "Wrong certificate length: ", String.valueOf(certificate.length()));
}
if (!"localhost".equals(fullyQualifiedDomainName) && fullyQualifiedDomainName.split("\\.").length < 2) {
- throw new IllegalArgumentException("Expected a FQDN, got: " + fullyQualifiedDomainName);
+ throw new IntroducerException(FQDN_LENGTH, "Expected a FQDN, got: ", fullyQualifiedDomainName);
}
if (auth == null || auth.isEmpty()) {
- throw new IllegalArgumentException("Auth token is missing");
+ throw new IntroducerException(AUTH_MISSING, "Auth token is missing");
}
return true;
}
- public static Introducer fromUrl(String introducerUrl) throws URISyntaxException, IllegalArgumentException {
+ /**
+ * Helper method to create an Introducer model object, containing the information how to query a menshen API via a proxy
+ * @param introducerUrl String representing an 'invite code'
+ * @return Introducer model
+ * @throws NullPointerException in case the parameter introducerUrl is null
+ * @throws IntroducerException in case the parameter introducerUrl is invalid
+ */
+ public static Introducer fromUrl(String introducerUrl) throws NullPointerException, IntroducerException {
Uri uri = Uri.parse(introducerUrl);
String fqdn = uri.getQueryParameter("fqdn");
if (fqdn == null || fqdn.isEmpty()) {
- throw new IllegalArgumentException("FQDN not found in the introducer URL");
+ throw new IntroducerException(FQDN_MISSING, "FQDN not found in the introducer URL");
}
if (!isAscii(fqdn)) {
- throw new IllegalArgumentException("FQDN is not ASCII: " + fqdn);
+ throw new IntroducerException(FQDN_INVALID, "FQDN is not ASCII: " + fqdn, fqdn);
}
boolean kcp = "1".equals(uri.getQueryParameter( "kcp"));
String cert = uri.getQueryParameter( "cert");
if (cert == null || cert.isEmpty()) {
- throw new IllegalArgumentException("Cert not found in the introducer URL");
+ throw new IntroducerException(CERTIFICATE_MISSING, "Cert not found in the introducer URL");
}
String auth = uri.getQueryParameter( "auth");
if (auth == null || auth.isEmpty()) {
- throw new IllegalArgumentException("Authentication token not found in the introducer URL");
+ throw new IntroducerException(AUTH_MISSING, "Authentication token not found in the introducer URL");
}
return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp, auth);
}
@@ -129,4 +151,48 @@ public class Introducer implements Parcelable {
return String.format(Locale.US, "%s://%s?fqdn=%s&kcp=%d&cert=%s&auth=%s", type, address, URLEncoder.encode(fullyQualifiedDomainName, "UTF-8"), kcpEnabled ? 1 : 0, URLEncoder.encode(certificate, "UTF-8"), URLEncoder.encode(auth, "UTF-8"));
}
+ public static class IntroducerException extends IllegalArgumentException {
+ public static final int UNKNOWN_TYPE = 100;
+ public static final int ADDRESS_FORMAT = 200;
+ public static final int CERTIFICATE_LENGTH = 300;
+ public static final int CERTIFICATE_MISSING = 310;
+ public static final int FQDN_LENGTH = 400;
+ public static final int FQDN_MISSING = 410;
+ public static final int FQDN_INVALID = 420;
+ public static final int AUTH_MISSING = 500;
+
+ private final Object[] args;
+ private final int type;
+
+ public IntroducerException(int type, String defaultMsg, Object... args) {
+ super(args == null ? defaultMsg : String.format(defaultMsg, args));
+ this.type = type;
+ this.args = args;
+ }
+
+
+ @Nullable
+ public String getLocalizedMessage(Context context) {
+ if (context == null) {
+ return getMessage();
+ }
+ try {
+ return switch (type) {
+ case UNKNOWN_TYPE -> context.getString(R.string.error_invite_unknown_type, args);
+ case ADDRESS_FORMAT -> context.getString(R.string.error_invite_address_format);
+ case CERTIFICATE_LENGTH -> context.getString(R.string.error_invite_certificate_length, args);
+ case CERTIFICATE_MISSING -> context.getString(R.string.error_invite_certificate_missing);
+ case FQDN_LENGTH -> context.getString(R.string.error_invite_fqdn_length, args);
+ case FQDN_MISSING -> context.getString(R.string.error_invite_fqdn_missing);
+ case FQDN_INVALID -> context.getString(R.string.error_invite_fqdn_invalid, args);
+ case AUTH_MISSING -> context.getString(R.string.error_invite_auth_missing);
+ default -> getMessage();
+ };
+ } catch (IllegalFormatException e) {
+ e.printStackTrace();
+ return getMessage();
+ }
+
+ }
+ }
} \ No newline at end of file
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
index b4ec23e6..1708fe83 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
@@ -983,7 +983,7 @@ public final class Provider implements Parcelable {
return introducer;
}
- public void setIntroducer(String introducerUrl) throws URISyntaxException, IllegalArgumentException {
+ public void setIntroducer(String introducerUrl) throws NullPointerException, IllegalArgumentException {
this.introducer = Introducer.fromUrl(introducerUrl);
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
index 63ae3731..a981a6ef 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
@@ -75,6 +75,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB
ERRORS = "errors",
ERRORID = "errorId",
INITIAL_ACTION = "initalAction",
+ ERROR_EXTRA = "errorExtra",
BACKEND_ERROR_KEY = "error",
BACKEND_ERROR_MESSAGE = "message",
USER_MESSAGE = "userMessage",
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
index 79c6f5c4..55024b2c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
@@ -10,9 +10,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.RECEIVER_KEY;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_EXCEPTION;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_TIMEOUT;
-import static se.leap.bitmaskclient.providersetup.ProviderApiManagerV5.PROXY_HOST;
-import static se.leap.bitmaskclient.providersetup.ProviderApiManagerV5.SOCKS_PROXY_SCHEME;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_TOR_TIMEOUT;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.ERROR_TOR_TIMEOUT;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_PROVIDER_JSON;
import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF;
@@ -25,7 +23,6 @@ import android.util.Log;
import androidx.core.content.IntentCompat;
import org.jetbrains.annotations.Blocking;
-import org.json.JSONException;
import org.json.JSONObject;
import java.util.concurrent.TimeoutException;
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java
index 965741f0..5a922419 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java
@@ -59,9 +59,9 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.QUIETLY_UPDATE_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_INVALID_CERTIFICATE;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.ERROR_CERTIFICATE_PINNING;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.ERROR_INVALID_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_CA_CERT;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_EIP_SERVICE_JSON;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_GEOIP_JSON;
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java
index 2680f612..88f027c3 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java
@@ -19,7 +19,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.QUIETLY_UPDATE_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_INVALID_CERTIFICATE;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.ERROR_INVALID_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_V5_BRIDGES;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_V5_GATEWAYS;
import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_V5_SERVICE_JSON;
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java
index 172d2636..ab4a64d4 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java
@@ -16,8 +16,20 @@
*/
package se.leap.bitmaskclient.providersetup;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORID;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERROR_EXTRA;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.INITIAL_ACTION;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_PROVIDER_DETAILS;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.DEFAULT;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.SETUP_ERRORS.valueOf;
+
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
@@ -33,16 +45,6 @@ import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
-import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORID;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.INITIAL_ACTION;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_PROVIDER_DETAILS;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.DEFAULT;
-import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.valueOf;
-
/**
* Implements a dialog to show why a download failed.
*
@@ -56,21 +58,24 @@ public class ProviderSetupFailedDialog extends DialogFragment {
private final static String KEY_DOWNLOAD_ERROR = "key_download_error";
private final static String KEY_INITAL_ACTION = "key_inital_action";
private String reasonToFail;
- private DOWNLOAD_ERRORS downloadError = DEFAULT;
+ private SETUP_ERRORS setupError = DEFAULT;
private String initialAction;
+ private String errorExtra;
+
private Provider provider;
/**
* Represent error types that need different error handling actions
*/
- public enum DOWNLOAD_ERRORS {
+ public enum SETUP_ERRORS {
DEFAULT,
ERROR_CORRUPTED_PROVIDER_JSON,
ERROR_INVALID_CERTIFICATE,
ERROR_CERTIFICATE_PINNING,
ERROR_NEW_URL_NO_VPN_PROVIDER,
- ERROR_TOR_TIMEOUT
+ ERROR_TOR_TIMEOUT,
+ ERROR_QR_CODE_SCANNING
}
/**
@@ -98,9 +103,13 @@ public class ProviderSetupFailedDialog extends DialogFragment {
}
if (errorJson.has(ERRORID)) {
- dialogFragment.downloadError = valueOf(errorJson.getString(ERRORID));
+ dialogFragment.setupError = valueOf(errorJson.getString(ERRORID));
} else if (testNewURL) {
- dialogFragment.downloadError = DOWNLOAD_ERRORS.ERROR_NEW_URL_NO_VPN_PROVIDER;
+ dialogFragment.setupError = SETUP_ERRORS.ERROR_NEW_URL_NO_VPN_PROVIDER;
+ }
+
+ if (errorJson.has(ERROR_EXTRA)) {
+ dialogFragment.errorExtra = errorJson.getString(ERROR_EXTRA);
}
if (errorJson.has(INITIAL_ACTION)) {
@@ -126,7 +135,7 @@ public class ProviderSetupFailedDialog extends DialogFragment {
builder.setMessage(reasonToFail)
.setNegativeButton(R.string.cancel, (dialog, id)
-> interfaceWithConfigurationWizard.cancelSettingUpProvider());
- switch (downloadError) {
+ switch (setupError) {
case ERROR_CORRUPTED_PROVIDER_JSON:
builder.setPositiveButton(R.string.update_provider_details, (dialog, which)
-> interfaceWithConfigurationWizard.updateProviderDetails());
@@ -140,6 +149,15 @@ public class ProviderSetupFailedDialog extends DialogFragment {
builder.setPositiveButton(R.string.retry, (dialog, id)
-> interfaceWithConfigurationWizard.addAndSelectNewProvider(provider.getMainUrl()));
break;
+ case ERROR_QR_CODE_SCANNING:
+ builder.setNegativeButton(android.R.string.cancel, null);
+ builder.setPositiveButton(R.string.error_invite_copy, ((dialog, id) -> {
+ ClipboardManager clipboard = (ClipboardManager)
+ getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clip = ClipData.newPlainText(getContext().getString(R.string.error), errorExtra);
+ clipboard.setPrimaryClip(clip);
+ }));
+ break;
case ERROR_TOR_TIMEOUT:
builder.setPositiveButton(R.string.retry, (dialog, id) -> {
handleTorTimeoutError();
@@ -148,6 +166,7 @@ public class ProviderSetupFailedDialog extends DialogFragment {
PreferenceHelper.useSnowflake(false);
handleTorTimeoutError();
}));
+ break;
default:
builder.setPositiveButton(R.string.retry, (dialog, id)
-> interfaceWithConfigurationWizard.retrySetUpProvider(provider));
@@ -212,7 +231,7 @@ public class ProviderSetupFailedDialog extends DialogFragment {
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_PROVIDER, provider);
outState.putString(KEY_REASON_TO_FAIL, reasonToFail);
- outState.putString(KEY_DOWNLOAD_ERROR, downloadError.toString());
+ outState.putString(KEY_DOWNLOAD_ERROR, setupError.toString());
outState.putString(KEY_INITAL_ACTION, initialAction);
}
@@ -227,7 +246,7 @@ public class ProviderSetupFailedDialog extends DialogFragment {
this.reasonToFail = savedInstanceState.getString(KEY_REASON_TO_FAIL);
}
if (savedInstanceState.containsKey(KEY_DOWNLOAD_ERROR)) {
- this.downloadError = valueOf(savedInstanceState.getString(KEY_DOWNLOAD_ERROR));
+ this.setupError = valueOf(savedInstanceState.getString(KEY_DOWNLOAD_ERROR));
}
if (savedInstanceState.containsKey(KEY_INITAL_ACTION)) {
this.initialAction = savedInstanceState.getString(KEY_INITAL_ACTION);
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
index 157b582c..823357ff 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
@@ -16,6 +16,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
+import org.json.JSONObject;
+
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -26,9 +28,9 @@ import se.leap.bitmaskclient.base.utils.ViewHelper;
import se.leap.bitmaskclient.databinding.FProviderSelectionBinding;
import se.leap.bitmaskclient.providersetup.activities.CancelCallback;
import se.leap.bitmaskclient.providersetup.fragments.helpers.AbstractQrScannerHelper;
-import se.leap.bitmaskclient.providersetup.helpers.QrScannerHelper;
import se.leap.bitmaskclient.providersetup.fragments.viewmodel.ProviderSelectionViewModel;
import se.leap.bitmaskclient.providersetup.fragments.viewmodel.ProviderSelectionViewModelFactory;
+import se.leap.bitmaskclient.providersetup.helpers.QrScannerHelper;
public class ProviderSelectionFragment extends BaseSetupFragment implements CancelCallback, AbstractQrScannerHelper.ScanResultCallback {
@@ -233,4 +235,11 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc
e.printStackTrace();
}
}
+
+ @Override
+ public void onScanError(JSONObject error) {
+ if (setupActivityCallback != null) {
+ setupActivityCallback.onError(error.toString());
+ }
+ }
} \ No newline at end of file
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/helpers/AbstractQrScannerHelper.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/helpers/AbstractQrScannerHelper.java
index 132d8cc9..08cb6c82 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/helpers/AbstractQrScannerHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/helpers/AbstractQrScannerHelper.java
@@ -2,11 +2,14 @@ package se.leap.bitmaskclient.providersetup.fragments.helpers;
import androidx.fragment.app.Fragment;
+import org.json.JSONObject;
+
import se.leap.bitmaskclient.base.models.Introducer;
public abstract class AbstractQrScannerHelper {
public interface ScanResultCallback {
void onScanResult(Introducer introducer);
+ void onScanError(JSONObject error);
}
public AbstractQrScannerHelper(Fragment fragment, ScanResultCallback callback) {