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
This commit is contained in:
Ilya Matyukhin
2022-10-13 22:51:42 +00:00
parent 3d0ea920d1
commit 2079d344c1
3 changed files with 8 additions and 25 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}