From 2079d344c1b8f5ac46e3ac9d85522d91157c175d Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 13 Oct 2022 22:51:42 +0000 Subject: [PATCH] Fix BiometricPrompt retrying without finger lift Authentication errors from BiometricPrompt would result in a call to `onCancelUdfps` to turn off the UDFPS illumination. As a side effect, `onCancelUdfps` would clear the internal state machine, including the fact that a finger is touching the sensor. Consequently, any natural micromovement of the finger would register as a new touch and lead to a new authentication attempt. We no longer need `onCancelUdfps` to turn off the UDFPS illumination early. This is handled in `UdfpsOverlayController#onAcquired` and the lifecycle methods of the fingerprint client monitors. Bug: 236338150 Test: atest SystemUITests:com.android.systemui.biometrics Change-Id: I5110a798e9557a7df55f42eac467a3da4c2d4c00 --- .../systemui/biometrics/AuthController.java | 13 ------------- .../systemui/biometrics/UdfpsController.java | 18 +++++++----------- .../biometrics/UdfpsControllerTest.java | 2 +- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index d43e5d9d09cc3..3b41a2d22380e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -626,17 +626,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, mUdfpsController.onAodInterrupt(screenX, screenY, major, minor); } - /** - * Cancel a fingerprint scan manually. This will get rid of the white circle on the udfps - * sensor area even if the user hasn't explicitly lifted their finger yet. - */ - public void onCancelUdfps() { - if (mUdfpsController == null) { - return; - } - mUdfpsController.onCancelUdfps(); - } - private void sendResultAndCleanUp(@DismissedReason int reason, @Nullable byte[] credentialAttestation) { if (mReceiver == null) { @@ -964,8 +953,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, } else { Log.w(TAG, "onBiometricError callback but dialog is gone"); } - - onCancelUdfps(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index a7648bffe503f..d17f7878f5f30 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -786,7 +786,7 @@ public class UdfpsController implements DozeReceiver { // ACTION_UP/ACTION_CANCEL, we need to be careful about not letting the screen // accidentally remain in high brightness mode. As a mitigation, queue a call to // cancel the fingerprint scan. - mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps, + mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::cancelAodInterrupt, AOD_INTERRUPT_TIMEOUT_MILLIS); // using a hard-coded value for major and minor until it is available from the sensor onFingerDown(requestId, screenX, screenY, minor, major); @@ -813,26 +813,22 @@ public class UdfpsController implements DozeReceiver { } /** - * Cancel UDFPS affordances - ability to hide the UDFPS overlay before the user explicitly - * lifts their finger. Generally, this should be called on errors in the authentication flow. - * - * The sensor that triggers an AOD fingerprint interrupt (see onAodInterrupt) doesn't give - * ACTION_UP/ACTION_CANCEL events, so and AOD interrupt scan needs to be cancelled manually. + * The sensor that triggers {@link #onAodInterrupt} doesn't emit ACTION_UP or ACTION_CANCEL + * events, which means the fingerprint gesture created by the AOD interrupt needs to be + * cancelled manually. * This should be called when authentication either succeeds or fails. Failing to cancel the * scan will leave the display in the UDFPS mode until the user lifts their finger. On optical * sensors, this can result in illumination persisting for longer than necessary. */ - void onCancelUdfps() { + @VisibleForTesting + void cancelAodInterrupt() { if (!mIsAodInterruptActive) { return; } if (mOverlay != null && mOverlay.getOverlayView() != null) { onFingerUp(mOverlay.getRequestId(), mOverlay.getOverlayView()); } - if (mCancelAodTimeoutAction != null) { - mCancelAodTimeoutAction.run(); - mCancelAodTimeoutAction = null; - } + mCancelAodTimeoutAction = null; mIsAodInterruptActive = false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 8923ba8175688..d610709cdcda3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -659,7 +659,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); when(mUdfpsView.isDisplayConfigured()).thenReturn(true); // WHEN it is cancelled - mUdfpsController.onCancelUdfps(); + mUdfpsController.cancelAodInterrupt(); // THEN the display is unconfigured verify(mUdfpsView).unconfigureDisplay(); }