From 6b1747884759016c2903bc276d32c0ec391d6c81 Mon Sep 17 00:00:00 2001 From: Wendly Li Date: Wed, 21 Sep 2022 16:43:10 +0000 Subject: [PATCH] Cancel AodTimeoutAction when finger lift. If AodTimeoutAction is not cancelled when finger lift and user try to unlock the screen again, AodTimeoutAction will still send finger up in 1 second. So the second unlocking will be terminated by fake finger up event. But the user's finger haven't leave the screen, the UI will show third unlocking immediately. So AodTimeoutAction needs to be cancelled when finger lift. Bug: 247048663 Test: Check UI works properly Test: Run atest UdfpsControllerTest Change-Id: I1a4a0038e514ca1045db6894461e790c67cb0084 Signed-off-by: Wendly Li --- .../systemui/biometrics/UdfpsController.java | 6 +++ .../biometrics/UdfpsControllerTest.java | 53 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 27e9af9b394a7..412dc0577876f 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -912,6 +912,12 @@ public class UdfpsController implements DozeReceiver { if (view.isDisplayConfigured()) { view.unconfigureDisplay(); } + + 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 08b1c28f21124..53e8c6e6d9215 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -18,6 +18,7 @@ package com.android.systemui.biometrics; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; +import static android.view.MotionEvent.ACTION_UP; import static junit.framework.Assert.assertEquals; @@ -680,6 +681,58 @@ public class UdfpsControllerTest extends SysuiTestCase { verify(mUdfpsView).unconfigureDisplay(); } + @Test + public void aodInterruptCancelTimeoutActionWhenFingerUp() 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 ACTION_UP event + when(mUdfpsView.isDisplayConfigured()).thenReturn(true); + + // WHEN ACTION_UP is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent upEvent = MotionEvent.obtain(0, 0, ACTION_UP, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, upEvent); + mBiometricsExecutor.runAllReady(); + upEvent.recycle(); + + // Configure UdfpsView to accept the ACTION_DOWN event + when(mUdfpsView.isDisplayConfigured()).thenReturn(false); + + // WHEN ACTION_DOWN is received + 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