diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 2578df33c167b..0f5a99c1596db 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -245,7 +245,7 @@ public class UdfpsController implements DozeReceiver { mAcquiredReceived = true; final UdfpsView view = mOverlay.getOverlayView(); if (view != null) { - view.unconfigureDisplay(); + unconfigureDisplay(view); } if (acquiredGood) { mOverlay.onAcquiredGood(); @@ -737,6 +737,19 @@ public class UdfpsController implements DozeReceiver { mOverlay = null; mOrientationListener.disable(); + + } + + private void unconfigureDisplay(@NonNull UdfpsView view) { + if (view.isDisplayConfigured()) { + view.unconfigureDisplay(); + + if (mCancelAodTimeoutAction != null) { + mCancelAodTimeoutAction.run(); + mCancelAodTimeoutAction = null; + } + mIsAodInterruptActive = false; + } } /** @@ -812,12 +825,12 @@ public class UdfpsController implements DozeReceiver { * sensors, this can result in illumination persisting for longer than necessary. */ void onCancelUdfps() { - if (mOverlay != null && mOverlay.getOverlayView() != null) { - onFingerUp(mOverlay.getRequestId(), mOverlay.getOverlayView()); - } if (!mIsAodInterruptActive) { return; } + if (mOverlay != null && mOverlay.getOverlayView() != null) { + onFingerUp(mOverlay.getRequestId(), mOverlay.getOverlayView()); + } if (mCancelAodTimeoutAction != null) { mCancelAodTimeoutAction.run(); mCancelAodTimeoutAction = null; @@ -911,15 +924,8 @@ public class UdfpsController implements DozeReceiver { } } mOnFingerDown = false; - if (view.isDisplayConfigured()) { - view.unconfigureDisplay(); - } + unconfigureDisplay(view); - if (mCancelAodTimeoutAction != null) { - mCancelAodTimeoutAction.run(); - 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 11e58801bb7e0..f210708806aba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.graphics.Rect; +import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; @@ -688,7 +689,7 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test - public void aodInterruptCancelTimeoutActionWhenFingerUp() throws RemoteException { + public void aodInterruptCancelTimeoutActionOnFingerUp() throws RemoteException { when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); @@ -739,6 +740,56 @@ public class UdfpsControllerTest extends SysuiTestCase { verify(mUdfpsView, times(1)).unconfigureDisplay(); } + @Test + public void aodInterruptCancelTimeoutActionOnAcquired() throws RemoteException { + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); + + // GIVEN AOD interrupt + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mScreenObserver.onScreenTurnedOn(); + mFgExecutor.runAllReady(); + mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); + mFgExecutor.runAllReady(); + + // Configure UdfpsView to accept the acquired event + when(mUdfpsView.isDisplayConfigured()).thenReturn(true); + + // WHEN acquired is received + mOverlayController.onAcquired(TEST_UDFPS_SENSOR_ID, + BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD); + + // Configure UdfpsView to accept the ACTION_DOWN event + when(mUdfpsView.isDisplayConfigured()).thenReturn(false); + + // WHEN ACTION_DOWN is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); + mBiometricsExecutor.runAllReady(); + downEvent.recycle(); + + // WHEN ACTION_MOVE is received + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + mBiometricsExecutor.runAllReady(); + moveEvent.recycle(); + mFgExecutor.runAllReady(); + + // Configure UdfpsView to accept the finger up event + when(mUdfpsView.isDisplayConfigured()).thenReturn(true); + + // WHEN it times out + mFgExecutor.advanceClockToNext(); + mFgExecutor.runAllReady(); + + // THEN the display should be unconfigured once. If the timeout action is not + // cancelled, the display would be unconfigured twice which would cause two + // FP attempts. + verify(mUdfpsView, times(1)).unconfigureDisplay(); + } + @Test public void aodInterruptScreenOff() throws RemoteException { // GIVEN screen off