diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md
index 92a44356cd9..7452cd4d043 100644
--- a/packages/local_auth/local_auth_android/CHANGELOG.md
+++ b/packages/local_auth/local_auth_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.23
+
+* Switches internals to Pigeon and fixes Java warnings.
+
## 1.0.22
* Sets an explicit Java compatibility version.
diff --git a/packages/local_auth/local_auth_android/android/lint-baseline.xml b/packages/local_auth/local_auth_android/android/lint-baseline.xml
index 3f0a47a6824..a695371a999 100644
--- a/packages/local_auth/local_auth_android/android/lint-baseline.xml
+++ b/packages/local_auth/local_auth_android/android/lint-baseline.xml
@@ -1,50 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml b/packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml
index 63f75079e00..ef323b4281c 100644
--- a/packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml
+++ b/packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
-
diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java
index c30f879d2c7..b5b824500dc 100644
--- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java
+++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java
@@ -8,7 +8,6 @@
import android.app.AlertDialog;
import android.app.Application;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
@@ -26,7 +25,6 @@
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
-import io.flutter.plugin.common.MethodCall;
import java.util.concurrent.Executor;
/**
@@ -35,35 +33,20 @@
*
One instance per call is generated to ensure readable separation of executable paths across
* method calls.
*/
-@SuppressWarnings("deprecation")
class AuthenticationHelper extends BiometricPrompt.AuthenticationCallback
implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
/** The callback that handles the result of this authentication process. */
interface AuthCompletionHandler {
- /** Called when authentication was successful. */
- void onSuccess();
-
- /**
- * Called when authentication failed due to user. For instance, when user cancels the auth or
- * quits the app.
- */
- void onFailure();
-
- /**
- * Called when authentication fails due to non-user related problems such as system errors,
- * phone not having a FP reader etc.
- *
- * @param code The error code to be returned to Flutter app.
- * @param error The description of the error.
- */
- void onError(String code, String error);
+ /** Called when authentication attempt is complete. */
+ void complete(Messages.AuthResult authResult);
}
// This is null when not using v2 embedding;
private final Lifecycle lifecycle;
private final FragmentActivity activity;
private final AuthCompletionHandler completionHandler;
- private final MethodCall call;
+ private final boolean useErrorDialogs;
+ private final Messages.AuthStrings strings;
private final BiometricPrompt.PromptInfo promptInfo;
private final boolean isAuthSticky;
private final UiThreadExecutor uiThreadExecutor;
@@ -73,23 +56,24 @@ interface AuthCompletionHandler {
AuthenticationHelper(
Lifecycle lifecycle,
FragmentActivity activity,
- MethodCall call,
- AuthCompletionHandler completionHandler,
+ @NonNull Messages.AuthOptions options,
+ @NonNull Messages.AuthStrings strings,
+ @NonNull AuthCompletionHandler completionHandler,
boolean allowCredentials) {
this.lifecycle = lifecycle;
this.activity = activity;
this.completionHandler = completionHandler;
- this.call = call;
- this.isAuthSticky = call.argument("stickyAuth");
+ this.strings = strings;
+ this.isAuthSticky = options.getSticky();
+ this.useErrorDialogs = options.getUseErrorDialgs();
this.uiThreadExecutor = new UiThreadExecutor();
BiometricPrompt.PromptInfo.Builder promptBuilder =
new BiometricPrompt.PromptInfo.Builder()
- .setDescription((String) call.argument("localizedReason"))
- .setTitle((String) call.argument("signInTitle"))
- .setSubtitle((String) call.argument("biometricHint"))
- .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction"))
- .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction"));
+ .setDescription(strings.getReason())
+ .setTitle(strings.getSignInTitle())
+ .setSubtitle(strings.getBiometricHint())
+ .setConfirmationRequired(options.getSensitiveTransaction());
int allowedAuthenticators =
BiometricManager.Authenticators.BIOMETRIC_WEAK
@@ -98,7 +82,7 @@ interface AuthCompletionHandler {
if (allowCredentials) {
allowedAuthenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL;
} else {
- promptBuilder.setNegativeButtonText((String) call.argument("cancelButton"));
+ promptBuilder.setNegativeButtonText(strings.getCancelButton());
}
promptBuilder.setAllowedAuthenticators(allowedAuthenticators);
@@ -135,40 +119,35 @@ private void stop() {
@SuppressLint("SwitchIntDef")
@Override
- public void onAuthenticationError(int errorCode, CharSequence errString) {
+ public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
switch (errorCode) {
case BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL:
- if (call.argument("useErrorDialogs")) {
+ if (useErrorDialogs) {
showGoToSettingsDialog(
- (String) call.argument("deviceCredentialsRequired"),
- (String) call.argument("deviceCredentialsSetupDescription"));
+ strings.getDeviceCredentialsRequiredTitle(),
+ strings.getDeviceCredentialsSetupDescription());
return;
}
- completionHandler.onError("NotAvailable", "Security credentials not available.");
+ completionHandler.complete(Messages.AuthResult.ERROR_NOT_AVAILABLE);
break;
case BiometricPrompt.ERROR_NO_SPACE:
case BiometricPrompt.ERROR_NO_BIOMETRICS:
- if (call.argument("useErrorDialogs")) {
+ if (useErrorDialogs) {
showGoToSettingsDialog(
- (String) call.argument("biometricRequired"),
- (String) call.argument("goToSettingDescription"));
+ strings.getBiometricRequiredTitle(), strings.getGoToSettingsDescription());
return;
}
- completionHandler.onError("NotEnrolled", "No Biometrics enrolled on this device.");
+ completionHandler.complete(Messages.AuthResult.ERROR_NOT_ENROLLED);
break;
case BiometricPrompt.ERROR_HW_UNAVAILABLE:
case BiometricPrompt.ERROR_HW_NOT_PRESENT:
- completionHandler.onError("NotAvailable", "Security credentials not available.");
+ completionHandler.complete(Messages.AuthResult.ERROR_NOT_AVAILABLE);
break;
case BiometricPrompt.ERROR_LOCKOUT:
- completionHandler.onError(
- "LockedOut",
- "The operation was canceled because the API is locked out due to too many attempts. This occurs after 5 failed attempts, and lasts for 30 seconds.");
+ completionHandler.complete(Messages.AuthResult.ERROR_LOCKED_OUT_TEMPORARILY);
break;
case BiometricPrompt.ERROR_LOCKOUT_PERMANENT:
- completionHandler.onError(
- "PermanentlyLockedOut",
- "The operation was canceled because ERROR_LOCKOUT occurred too many times. Biometric authentication is disabled until the user unlocks with strong authentication (PIN/Pattern/Password)");
+ completionHandler.complete(Messages.AuthResult.ERROR_LOCKED_OUT_PERMANENTLY);
break;
case BiometricPrompt.ERROR_CANCELED:
// If we are doing sticky auth and the activity has been paused,
@@ -176,18 +155,18 @@ public void onAuthenticationError(int errorCode, CharSequence errString) {
if (activityPaused && isAuthSticky) {
return;
} else {
- completionHandler.onFailure();
+ completionHandler.complete(Messages.AuthResult.SUCCESS);
}
break;
default:
- completionHandler.onFailure();
+ completionHandler.complete(Messages.AuthResult.FAILURE);
}
stop();
}
@Override
- public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
- completionHandler.onSuccess();
+ public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
+ completionHandler.complete(Messages.AuthResult.SUCCESS);
stop();
}
@@ -212,13 +191,7 @@ public void onActivityResumed(Activity ignored) {
final BiometricPrompt prompt = new BiometricPrompt(activity, uiThreadExecutor, this);
// When activity is resuming, we cannot show the prompt right away. We need to post it to the
// UI queue.
- uiThreadExecutor.handler.post(
- new Runnable() {
- @Override
- public void run() {
- prompt.authenticate(promptInfo);
- }
- });
+ uiThreadExecutor.handler.post(() -> prompt.authenticate(promptInfo));
}
}
@@ -236,32 +209,26 @@ public void onResume(@NonNull LifecycleOwner owner) {
@SuppressLint("InflateParams")
private void showGoToSettingsDialog(String title, String descriptionText) {
View view = LayoutInflater.from(activity).inflate(R.layout.go_to_setting, null, false);
- TextView message = (TextView) view.findViewById(R.id.fingerprint_required);
- TextView description = (TextView) view.findViewById(R.id.go_to_setting_description);
+ TextView message = view.findViewById(R.id.fingerprint_required);
+ TextView description = view.findViewById(R.id.go_to_setting_description);
message.setText(title);
description.setText(descriptionText);
Context context = new ContextThemeWrapper(activity, R.style.AlertDialogCustom);
OnClickListener goToSettingHandler =
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- completionHandler.onFailure();
- stop();
- activity.startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
- }
+ (dialog, which) -> {
+ completionHandler.complete(Messages.AuthResult.FAILURE);
+ stop();
+ activity.startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
};
OnClickListener cancelHandler =
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- completionHandler.onFailure();
- stop();
- }
+ (dialog, which) -> {
+ completionHandler.complete(Messages.AuthResult.FAILURE);
+ stop();
};
new AlertDialog.Builder(context)
.setView(view)
- .setPositiveButton((String) call.argument("goToSetting"), goToSettingHandler)
- .setNegativeButton((String) call.argument("cancelButton"), cancelHandler)
+ .setPositiveButton(strings.getGoToSettingsButton(), goToSettingHandler)
+ .setNegativeButton(strings.getCancelButton(), cancelHandler)
.setCancelable(false)
.show();
}
@@ -295,7 +262,7 @@ public void onStart(@NonNull LifecycleOwner owner) {}
@Override
public void onCreate(@NonNull LifecycleOwner owner) {}
- private static class UiThreadExecutor implements Executor {
+ static class UiThreadExecutor implements Executor {
final Handler handler = new Handler(Looper.getMainLooper());
@Override
diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java
index d724b38c0a7..f955f7821ec 100644
--- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java
+++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java
@@ -21,13 +21,17 @@
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;
-import io.flutter.plugin.common.MethodCall;
-import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
-import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.localauth.AuthenticationHelper.AuthCompletionHandler;
+import io.flutter.plugins.localauth.Messages.AuthClassification;
+import io.flutter.plugins.localauth.Messages.AuthOptions;
+import io.flutter.plugins.localauth.Messages.AuthResult;
+import io.flutter.plugins.localauth.Messages.AuthResultWrapper;
+import io.flutter.plugins.localauth.Messages.AuthStrings;
+import io.flutter.plugins.localauth.Messages.LocalAuthApi;
+import io.flutter.plugins.localauth.Messages.Result;
import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -35,9 +39,7 @@
*
*
Instantiate this in an add to app scenario to gracefully handle activity and context changes.
*/
-@SuppressWarnings("deprecation")
-public class LocalAuthPlugin implements MethodCallHandler, FlutterPlugin, ActivityAware {
- private static final String CHANNEL_NAME = "plugins.flutter.io/local_auth_android";
+public class LocalAuthPlugin implements FlutterPlugin, ActivityAware, LocalAuthApi {
private static final int LOCK_REQUEST_CODE = 221;
private Activity activity;
private AuthenticationHelper authHelper;
@@ -45,20 +47,19 @@ public class LocalAuthPlugin implements MethodCallHandler, FlutterPlugin, Activi
@VisibleForTesting final AtomicBoolean authInProgress = new AtomicBoolean(false);
// These are null when not using v2 embedding.
- private MethodChannel channel;
private Lifecycle lifecycle;
private BiometricManager biometricManager;
private KeyguardManager keyguardManager;
- private Result lockRequestResult;
+ Result lockRequestResult;
private final PluginRegistry.ActivityResultListener resultListener =
new PluginRegistry.ActivityResultListener() {
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == LOCK_REQUEST_CODE) {
if (resultCode == RESULT_OK && lockRequestResult != null) {
- authenticateSuccess(lockRequestResult);
+ onAuthenticationCompleted(lockRequestResult, AuthResult.SUCCESS);
} else {
- authenticateFail(lockRequestResult);
+ onAuthenticationCompleted(lockRequestResult, AuthResult.FAILURE);
}
lockRequestResult = null;
}
@@ -72,16 +73,13 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
* Calling this will register the plugin with the passed registrar. However, plugins
* initialized this way won't react to changes in activity or context.
*
- * @param registrar attaches this plugin's {@link
- * io.flutter.plugin.common.MethodChannel.MethodCallHandler} to the registrar's {@link
- * io.flutter.plugin.common.BinaryMessenger}.
+ * @param registrar provides access to necessary plugin context.
*/
@SuppressWarnings("deprecation")
- public static void registerWith(PluginRegistry.Registrar registrar) {
- final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME);
+ public static void registerWith(@NonNull PluginRegistry.Registrar registrar) {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
plugin.activity = registrar.activity();
- channel.setMethodCallHandler(plugin);
+ LocalAuthApi.setup(registrar.messenger(), plugin);
registrar.addActivityResultListener(plugin.resultListener);
}
@@ -92,176 +90,112 @@ public static void registerWith(PluginRegistry.Registrar registrar) {
*/
public LocalAuthPlugin() {}
- @Override
- public void onMethodCall(MethodCall call, @NonNull final Result result) {
- switch (call.method) {
- case "authenticate":
- authenticate(call, result);
- break;
- case "getEnrolledBiometrics":
- getEnrolledBiometrics(result);
- break;
- case "isDeviceSupported":
- isDeviceSupported(result);
- break;
- case "stopAuthentication":
- stopAuthentication(result);
- break;
- case "deviceSupportsBiometrics":
- deviceSupportsBiometrics(result);
- break;
- default:
- result.notImplemented();
- break;
+ public @NonNull Boolean isDeviceSupported() {
+ return isDeviceSecure() || canAuthenticateWithBiometrics();
+ }
+
+ public @NonNull Boolean deviceCanSupportBiometrics() {
+ return hasBiometricHardware();
+ }
+
+ public @NonNull List getEnrolledBiometrics() {
+ ArrayList biometrics = new ArrayList<>();
+ if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ == BiometricManager.BIOMETRIC_SUCCESS) {
+ biometrics.add(AuthClassification.WEAK);
}
+ if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
+ == BiometricManager.BIOMETRIC_SUCCESS) {
+ biometrics.add(AuthClassification.STRONG);
+ }
+ return biometrics;
}
- /*
- * Starts authentication process
- */
- private void authenticate(MethodCall call, final Result result) {
+ public @NonNull Boolean stopAuthentication() {
+ try {
+ if (authHelper != null && authInProgress.get()) {
+ authHelper.stopAuthentication();
+ authHelper = null;
+ }
+ authInProgress.set(false);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public void authenticate(
+ @NonNull AuthOptions options,
+ @NonNull AuthStrings strings,
+ @NonNull Result result) {
if (authInProgress.get()) {
- result.error("auth_in_progress", "Authentication in progress", null);
+ result.success(
+ new AuthResultWrapper.Builder().setValue(AuthResult.ERROR_ALREADY_IN_PROGRESS).build());
return;
}
if (activity == null || activity.isFinishing()) {
- result.error("no_activity", "local_auth plugin requires a foreground activity", null);
+ result.success(
+ new AuthResultWrapper.Builder().setValue(AuthResult.ERROR_NO_ACTIVITY).build());
return;
}
if (!(activity instanceof FragmentActivity)) {
- result.error(
- "no_fragment_activity",
- "local_auth plugin requires activity to be a FragmentActivity.",
- null);
+ result.success(
+ new AuthResultWrapper.Builder().setValue(AuthResult.ERROR_NOT_FRAGMENT_ACTIVITY).build());
return;
}
if (!isDeviceSupported()) {
- authInProgress.set(false);
- result.error("NotAvailable", "Required security features not enabled", null);
+ result.success(
+ new AuthResultWrapper.Builder().setValue(AuthResult.ERROR_NOT_AVAILABLE).build());
return;
}
authInProgress.set(true);
AuthCompletionHandler completionHandler = createAuthCompletionHandler(result);
- boolean isBiometricOnly = call.argument("biometricOnly");
- boolean allowCredentials = !isBiometricOnly && canAuthenticateWithDeviceCredential();
+ boolean allowCredentials = !options.getBiometricOnly() && canAuthenticateWithDeviceCredential();
- sendAuthenticationRequest(call, completionHandler, allowCredentials);
- return;
+ sendAuthenticationRequest(options, strings, allowCredentials, completionHandler);
}
@VisibleForTesting
- public AuthCompletionHandler createAuthCompletionHandler(final Result result) {
- return new AuthCompletionHandler() {
- @Override
- public void onSuccess() {
- authenticateSuccess(result);
- }
-
- @Override
- public void onFailure() {
- authenticateFail(result);
- }
-
- @Override
- public void onError(String code, String error) {
- if (authInProgress.compareAndSet(true, false)) {
- result.error(code, error, null);
- }
- }
- };
+ public @NonNull AuthCompletionHandler createAuthCompletionHandler(
+ @NonNull final Result result) {
+ return authResult -> onAuthenticationCompleted(result, authResult);
}
@VisibleForTesting
public void sendAuthenticationRequest(
- MethodCall call, AuthCompletionHandler completionHandler, boolean allowCredentials) {
+ @NonNull AuthOptions options,
+ @NonNull AuthStrings strings,
+ boolean allowCredentials,
+ @NonNull AuthCompletionHandler completionHandler) {
authHelper =
new AuthenticationHelper(
- lifecycle, (FragmentActivity) activity, call, completionHandler, allowCredentials);
+ lifecycle,
+ (FragmentActivity) activity,
+ options,
+ strings,
+ completionHandler,
+ allowCredentials);
authHelper.authenticate();
}
- private void authenticateSuccess(Result result) {
+ void onAuthenticationCompleted(Result result, AuthResult value) {
if (authInProgress.compareAndSet(true, false)) {
- result.success(true);
+ result.success(new AuthResultWrapper.Builder().setValue(value).build());
}
}
- private void authenticateFail(Result result) {
- if (authInProgress.compareAndSet(true, false)) {
- result.success(false);
- }
- }
-
- /*
- * Stops the authentication if in progress.
- */
- private void stopAuthentication(Result result) {
- try {
- if (authHelper != null && authInProgress.get()) {
- authHelper.stopAuthentication();
- authHelper = null;
- }
- authInProgress.set(false);
- result.success(true);
- } catch (Exception e) {
- result.success(false);
- }
- }
-
- private void deviceSupportsBiometrics(final Result result) {
- result.success(hasBiometricHardware());
- }
-
- /*
- * Returns enrolled biometric types available on device.
- */
- private void getEnrolledBiometrics(final Result result) {
- try {
- if (activity == null || activity.isFinishing()) {
- result.error("no_activity", "local_auth plugin requires a foreground activity", null);
- return;
- }
- ArrayList biometrics = getEnrolledBiometrics();
- result.success(biometrics);
- } catch (Exception e) {
- result.error("no_biometrics_available", e.getMessage(), null);
- }
- }
-
- @VisibleForTesting
- public ArrayList getEnrolledBiometrics() {
- ArrayList biometrics = new ArrayList<>();
- if (activity == null || activity.isFinishing()) {
- return biometrics;
- }
- if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- == BiometricManager.BIOMETRIC_SUCCESS) {
- biometrics.add("weak");
- }
- if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
- == BiometricManager.BIOMETRIC_SUCCESS) {
- biometrics.add("strong");
- }
- return biometrics;
- }
-
@VisibleForTesting
public boolean isDeviceSecure() {
if (keyguardManager == null) return false;
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && keyguardManager.isDeviceSecure());
}
- @VisibleForTesting
- public boolean isDeviceSupported() {
- return isDeviceSecure() || canAuthenticateWithBiometrics();
- }
-
private boolean canAuthenticateWithBiometrics() {
if (biometricManager == null) return false;
return biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
@@ -288,18 +222,15 @@ public boolean canAuthenticateWithDeviceCredential() {
== BiometricManager.BIOMETRIC_SUCCESS;
}
- private void isDeviceSupported(Result result) {
- result.success(isDeviceSupported());
- }
-
@Override
- public void onAttachedToEngine(FlutterPluginBinding binding) {
- channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), CHANNEL_NAME);
- channel.setMethodCallHandler(this);
+ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
+ LocalAuthApi.setup(binding.getBinaryMessenger(), this);
}
@Override
- public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}
+ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+ LocalAuthApi.setup(binding.getBinaryMessenger(), null);
+ }
private void setServicesFromActivity(Activity activity) {
if (activity == null) return;
@@ -310,11 +241,10 @@ private void setServicesFromActivity(Activity activity) {
}
@Override
- public void onAttachedToActivity(ActivityPluginBinding binding) {
+ public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
binding.addActivityResultListener(resultListener);
setServicesFromActivity(binding.getActivity());
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
- channel.setMethodCallHandler(this);
}
@Override
@@ -324,7 +254,7 @@ public void onDetachedFromActivityForConfigChanges() {
}
@Override
- public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
+ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
binding.addActivityResultListener(resultListener);
setServicesFromActivity(binding.getActivity());
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
@@ -333,7 +263,6 @@ public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding
@Override
public void onDetachedFromActivity() {
lifecycle = null;
- channel.setMethodCallHandler(null);
activity = null;
}
diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java
new file mode 100644
index 00000000000..a8b6738bd75
--- /dev/null
+++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/Messages.java
@@ -0,0 +1,742 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Autogenerated from Pigeon (v9.2.4), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+package io.flutter.plugins.localauth;
+
+import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import io.flutter.plugin.common.BasicMessageChannel;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MessageCodec;
+import io.flutter.plugin.common.StandardMessageCodec;
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Generated class from Pigeon. */
+@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"})
+public class Messages {
+
+ /** Error class for passing custom error details to Flutter via a thrown PlatformException. */
+ public static class FlutterError extends RuntimeException {
+
+ /** The error code. */
+ public final String code;
+
+ /** The error details. Must be a datatype supported by the api codec. */
+ public final Object details;
+
+ public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) {
+ super(message);
+ this.code = code;
+ this.details = details;
+ }
+ }
+
+ @NonNull
+ protected static ArrayList