From adef4840f3ffdc97503fe1ac0943381d43efe10d Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 26 Jul 2019 11:20:10 -0700 Subject: [PATCH] Do not request cancel authentication unless currently authenticating Currently we always send cancel() if ConfirmDeviceCredentialActivity goes into the background. However, if the biometric state is no longer authenticating, requesting cancel() in this state will result in an inconsistent state between BiometricService/client and ConfirmDeviceCredentials. BiometricService/client will receive the ERROR_CANCELED message incorrectly, while ConfirmDeviceCredential is showing / pending user password. When the password is entered, its result is ignored. The correct behavior is for ConfirmDeviceCredentialActivity to invoke cancel() only if it's still authenticating. Otherwise BiometricService and its client will receive ERROR_CANCELED, instead of the actual password auth result. Bug: 138279856 Test: BiometricPromptDemo, enable device credential fallback, get into lockout state, successfully enter password. API result is success instead of "canceled" now. Change-Id: I6521e896d0402fe856dc85476f51149c9b3084a8 Merged-In: I6521e896d0402fe856dc85476f51149c9b3084a8 (cherry picked from commit 49c7d0765090750f88f11153dfcf9ec378b0c84d) --- src/com/android/settings/password/BiometricFragment.java | 8 ++++++++ .../settings/password/ConfirmDeviceCredentialActivity.java | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java index bd5a10de46..66b665b337 100644 --- a/src/com/android/settings/password/BiometricFragment.java +++ b/src/com/android/settings/password/BiometricFragment.java @@ -58,11 +58,13 @@ public class BiometricFragment extends InstrumentedFragment { private Bundle mBundle; private BiometricPrompt mBiometricPrompt; private CancellationSignal mCancellationSignal; + private boolean mAuthenticating; private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() { @Override public void onAuthenticationError(int error, @NonNull CharSequence message) { + mAuthenticating = false; mClientExecutor.execute(() -> { mClientCallback.onAuthenticationError(error, message); }); @@ -71,6 +73,7 @@ public class BiometricFragment extends InstrumentedFragment { @Override public void onAuthenticationSucceeded(AuthenticationResult result) { + mAuthenticating = false; mClientExecutor.execute(() -> { mClientCallback.onAuthenticationSucceeded(result); }); @@ -134,6 +137,10 @@ public class BiometricFragment extends InstrumentedFragment { } } + boolean isAuthenticating() { + return mAuthenticating; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -180,6 +187,7 @@ public class BiometricFragment extends InstrumentedFragment { mCancellationSignal = new CancellationSignal(); // TODO: CC doesn't use crypto for now + mAuthenticating = true; mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor, mAuthenticationCallback, mUserId, mCancelCallback); } diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java index 53841e89be..8476f92429 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java @@ -251,7 +251,10 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { if (!isChangingConfigurations()) { mGoingToBackground = true; if (mBiometricFragment != null) { - mBiometricFragment.cancel(); + Log.d(TAG, "Authenticating: " + mBiometricFragment.isAuthenticating()); + if (mBiometricFragment.isAuthenticating()) { + mBiometricFragment.cancel(); + } } if (mIsFallback && !mCCLaunched) { -- 2.11.0