diff options
6 files changed, 112 insertions, 16 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index bcd1a1ee2696..81305f90e2b8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -219,13 +219,16 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard }; - private SwipeListener mSwipeListener = new SwipeListener() { + private final SwipeListener mSwipeListener = new SwipeListener() { @Override public void onSwipeUp() { if (!mUpdateMonitor.isFaceDetectionRunning()) { - mUpdateMonitor.requestFaceAuth(true, FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER); + boolean didFaceAuthRun = mUpdateMonitor.requestFaceAuth(true, + FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER); mKeyguardSecurityCallback.userActivity(); - showMessage(null, null); + if (didFaceAuthRun) { + showMessage(null, null); + } } if (mUpdateMonitor.isFaceEnrolled()) { mUpdateMonitor.requestActiveUnlock( @@ -234,7 +237,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } } }; - private ConfigurationController.ConfigurationListener mConfigurationListener = + private final ConfigurationController.ConfigurationListener mConfigurationListener = new ConfigurationController.ConfigurationListener() { @Override public void onThemeChanged() { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index b54665a11a8c..fadaa72f767b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -2366,11 +2366,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab * @param userInitiatedRequest true if the user explicitly requested face auth * @param reason One of the reasons {@link FaceAuthApiRequestReason} on why this API is being * invoked. + * @return current face auth detection state, true if it is running. */ - public void requestFaceAuth(boolean userInitiatedRequest, + public boolean requestFaceAuth(boolean userInitiatedRequest, @FaceAuthApiRequestReason String reason) { mLogger.logFaceAuthRequested(userInitiatedRequest, reason); updateFaceListeningState(BIOMETRIC_ACTION_START, apiRequestReasonToUiEvent(reason)); + return isFaceDetectionRunning(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index aaf2f8c625c7..ddb57f74cacf 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -3933,20 +3933,19 @@ public final class NotificationPanelViewController { mShadeLog.v("onMiddleClicked on Keyguard, mDozingOnDown: false"); // Try triggering face auth, this "might" run. Check // KeyguardUpdateMonitor#shouldListenForFace to see when face auth won't run. - mUpdateMonitor.requestFaceAuth(true, + boolean didFaceAuthRun = mUpdateMonitor.requestFaceAuth(true, FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED); - mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT, - 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */); - mLockscreenGestureLogger - .log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT); - if (!mUpdateMonitor.isFaceDetectionRunning()) { - startUnlockHintAnimation(); - } - if (mUpdateMonitor.isFaceEnrolled()) { + if (didFaceAuthRun) { mUpdateMonitor.requestActiveUnlock( ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT, "lockScreenEmptySpaceTap"); + } else { + mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT, + 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */); + mLockscreenGestureLogger + .log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT); + startUnlockHintAnimation(); } } return true; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 48e82397e826..b885d546c517 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -146,6 +146,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback; + @Captor + private ArgumentCaptor<KeyguardSecurityContainer.SwipeListener> mSwipeListenerArgumentCaptor; private Configuration mConfiguration; @@ -475,6 +477,64 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { verify(mKeyguardUpdateMonitor, never()).getUserHasTrust(anyInt()); } + @Test + public void onSwipeUp_whenFaceDetectionIsNotRunning_initiatesFaceAuth() { + KeyguardSecurityContainer.SwipeListener registeredSwipeListener = + getRegisteredSwipeListener(); + when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(false); + setupGetSecurityView(); + + registeredSwipeListener.onSwipeUp(); + + verify(mKeyguardUpdateMonitor).requestFaceAuth(true, + FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER); + } + + @Test + public void onSwipeUp_whenFaceDetectionIsRunning_doesNotInitiateFaceAuth() { + KeyguardSecurityContainer.SwipeListener registeredSwipeListener = + getRegisteredSwipeListener(); + when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(true); + + registeredSwipeListener.onSwipeUp(); + + verify(mKeyguardUpdateMonitor, never()) + .requestFaceAuth(true, + FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER); + } + + @Test + public void onSwipeUp_whenFaceDetectionIsTriggered_hidesBouncerMessage() { + KeyguardSecurityContainer.SwipeListener registeredSwipeListener = + getRegisteredSwipeListener(); + when(mKeyguardUpdateMonitor.requestFaceAuth(true, + FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)).thenReturn(true); + setupGetSecurityView(); + + registeredSwipeListener.onSwipeUp(); + + verify(mKeyguardPasswordViewControllerMock).showMessage(null, null); + } + + @Test + public void onSwipeUp_whenFaceDetectionIsNotTriggered_retainsBouncerMessage() { + KeyguardSecurityContainer.SwipeListener registeredSwipeListener = + getRegisteredSwipeListener(); + when(mKeyguardUpdateMonitor.requestFaceAuth(true, + FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)).thenReturn(false); + setupGetSecurityView(); + + registeredSwipeListener.onSwipeUp(); + + verify(mKeyguardPasswordViewControllerMock, never()).showMessage(null, null); + } + + private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() { + mKeyguardSecurityContainerController.onViewAttached(); + verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture()); + return mSwipeListenerArgumentCaptor.getValue(); + } + private void setupConditionsToEnableSideFpsHint() { attachView(); setSideFpsHintEnabledFromResources(true); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 784e7ddb6d06..ebfb4d4d1778 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -25,6 +25,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; +import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED; import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT; import static com.google.common.truth.Truth.assertThat; @@ -647,6 +648,36 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT); } + @Test + public void requestFaceAuth_whenFaceAuthWasStarted_returnsTrue() throws RemoteException { + // This satisfies all the preconditions to run face auth. + keyguardNotGoingAway(); + currentUserIsPrimary(); + currentUserDoesNotHaveTrust(); + biometricsNotDisabledThroughDevicePolicyManager(); + biometricsEnabledForCurrentUser(); + userNotCurrentlySwitching(); + bouncerFullyVisibleAndNotGoingToSleep(); + mTestableLooper.processAllMessages(); + + boolean didFaceAuthRun = mKeyguardUpdateMonitor.requestFaceAuth(true, + NOTIFICATION_PANEL_CLICKED); + + assertThat(didFaceAuthRun).isTrue(); + } + + @Test + public void requestFaceAuth_whenFaceAuthWasNotStarted_returnsFalse() throws RemoteException { + // This ensures face auth won't run. + biometricsDisabledForCurrentUser(); + mTestableLooper.processAllMessages(); + + boolean didFaceAuthRun = mKeyguardUpdateMonitor.requestFaceAuth(true, + NOTIFICATION_PANEL_CLICKED); + + assertThat(didFaceAuthRun).isFalse(); + } + private void testStrongAuthExceptOnBouncer(int strongAuth) { when(mKeyguardBypassController.canBypass()).thenReturn(true); mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index 0ecbc826abbb..02f28a235b95 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -18,6 +18,7 @@ package com.android.systemui.shade; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED; import static com.android.keyguard.KeyguardClockSwitch.LARGE; import static com.android.keyguard.KeyguardClockSwitch.SMALL; import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED; @@ -1606,7 +1607,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mNotificationPanelViewController.mStatusBarStateListener; statusBarStateListener.onStateChanged(KEYGUARD); mNotificationPanelViewController.setDozing(false, false); - when(mUpdateMonitor.isFaceDetectionRunning()).thenReturn(false); + when(mUpdateMonitor.requestFaceAuth(true, NOTIFICATION_PANEL_CLICKED)).thenReturn(false); // This sets the dozing state that is read when onMiddleClicked is eventually invoked. mTouchHandler.onTouch(mock(View.class), mDownMotionEvent); @@ -1621,7 +1622,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mNotificationPanelViewController.mStatusBarStateListener; statusBarStateListener.onStateChanged(KEYGUARD); mNotificationPanelViewController.setDozing(false, false); - when(mUpdateMonitor.isFaceDetectionRunning()).thenReturn(true); + when(mUpdateMonitor.requestFaceAuth(true, NOTIFICATION_PANEL_CLICKED)).thenReturn(true); // This sets the dozing state that is read when onMiddleClicked is eventually invoked. mTouchHandler.onTouch(mock(View.class), mDownMotionEvent); |