diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt index 819768544b0c9..e6283b86283bd 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt @@ -26,7 +26,6 @@ data class KeyguardFingerprintListenModel( val credentialAttempted: Boolean, val deviceInteractive: Boolean, val dreaming: Boolean, - val encryptedOrLockdown: Boolean, val fingerprintDisabled: Boolean, val fingerprintLockedOut: Boolean, val goingToSleep: Boolean, @@ -37,6 +36,7 @@ data class KeyguardFingerprintListenModel( val primaryUser: Boolean, val shouldListenSfpsState: Boolean, val shouldListenForFingerprintAssistant: Boolean, + val strongerAuthRequired: Boolean, val switchingUser: Boolean, val udfps: Boolean, val userDoesNotHaveTrust: Boolean diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 01be33e1e1565..4d0a273a21890 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -363,16 +363,18 @@ public class KeyguardSecurityContainerController extends ViewController { - // Trigger the fingerprint success path so the bouncer can be shown - handleFingerprintAuthenticated(userId, isStrongBiometric); - }; - /** * Propagates a pointer down event to keyguard. */ @@ -2651,27 +2678,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser && biometricEnabledForUser; - - final boolean shouldListenBouncerState = !(mFingerprintLockedOut - && mPrimaryBouncerIsOrWillBeShowing && mCredentialAttempted); - - final boolean isEncryptedOrLockdownForUser = isEncryptedOrLockdown(user); + final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed(); + final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled(); + final boolean shouldListenBouncerState = + !strongerAuthRequired || !mPrimaryBouncerIsOrWillBeShowing; final boolean shouldListenUdfpsState = !isUdfps || (!userCanSkipBouncer - && !isEncryptedOrLockdownForUser + && !strongerAuthRequired && userDoesNotHaveTrust); boolean shouldListenSideFpsState = true; - if (isSfpsSupported() && isSfpsEnrolled()) { + if (isSideFps) { shouldListenSideFpsState = mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true; } boolean shouldListen = shouldListenKeyguardState && shouldListenUserState - && shouldListenBouncerState && shouldListenUdfpsState && !isFingerprintLockedOut() + && shouldListenBouncerState && shouldListenUdfpsState && shouldListenSideFpsState; - maybeLogListenerModelData( new KeyguardFingerprintListenModel( System.currentTimeMillis(), @@ -2683,7 +2708,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mCredentialAttempted, mDeviceInteractive, mIsDreaming, - isEncryptedOrLockdownForUser, fingerprintDisabledForUser, mFingerprintLockedOut, mGoingToSleep, @@ -2694,6 +2718,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mIsPrimaryUser, shouldListenSideFpsState, shouldListenForFingerprintAssistant, + strongerAuthRequired, mSwitchingUser, isUdfps, userDoesNotHaveTrust)); @@ -2721,10 +2746,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab final boolean isEncryptedOrTimedOut = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT) || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT); - - // TODO: always disallow when fp is already locked out? - final boolean fpLockedOut = mFingerprintLockedOut || mFingerprintLockedOutPermanent; - + final boolean fpLockedOut = isFingerprintLockedOut(); final boolean canBypass = mKeyguardBypassController != null && mKeyguardBypassController.canBypass(); // There's no reason to ask the HAL for authentication when the user can dismiss the @@ -2846,15 +2868,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // Waiting for restart via handleFingerprintError(). return; } - mLogger.v("startListeningForFingerprint()"); if (unlockPossible) { mFingerprintCancelSignal = new CancellationSignal(); - if (isEncryptedOrLockdown(userId)) { - mFpm.detectFingerprint(mFingerprintCancelSignal, mFingerprintDetectionCallback, + if (!isUnlockingWithFingerprintAllowed()) { + mLogger.v("startListeningForFingerprint - detect"); + mFpm.detectFingerprint( + mFingerprintCancelSignal, + (sensorId, user, isStrongBiometric) -> { + mLogger.d("fingerprint detected"); + // Trigger the fingerprint success path so the bouncer can be shown + handleFingerprintAuthenticated(user, isStrongBiometric); + }, userId); } else { + mLogger.v("startListeningForFingerprint - authenticate"); mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal, mFingerprintAuthenticationCallback, null /* handler */, FingerprintManager.SENSOR_ID_ANY, userId, 0 /* flags */); @@ -3071,11 +3100,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } + // Immediately stop previous biometric listening states. + // Resetting lockout states updates the biometric listening states. if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) { + stopListeningForFace(FACE_AUTH_UPDATED_USER_SWITCHING); handleFaceLockoutReset(mFaceManager.getLockoutModeForUser( mFaceSensorProperties.get(0).sensorId, userId)); } if (mFpm != null && !mFingerprintSensorProperties.isEmpty()) { + stopListeningForFingerprint(); handleFingerprintLockoutReset(mFpm.getLockoutModeForUser( mFingerprintSensorProperties.get(0).sensorId, userId)); } @@ -3482,7 +3515,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @AnyThread public void setSwitchingUser(boolean switching) { mSwitchingUser = switching; - // Since this comes in on a binder thread, we need to post if first + // Since this comes in on a binder thread, we need to post it first mHandler.post(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_USER_SWITCHING)); } @@ -3574,8 +3607,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab Assert.isMainThread(); mUserFingerprintAuthenticated.clear(); mUserFaceAuthenticated.clear(); - mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT, unlockedUser); - mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE, unlockedUser); + mTrustManager.clearAllBiometricRecognized(FINGERPRINT, unlockedUser); + mTrustManager.clearAllBiometricRecognized(FACE, unlockedUser); mLogger.d("clearBiometricRecognized"); for (int i = 0; i < mCallbacks.size(); i++) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 4363b88bf21e0..0c1cb9233c892 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -116,9 +116,9 @@ class AuthRippleController @Inject constructor( notificationShadeWindowController.setForcePluginOpen(false, this) } - fun showUnlockRipple(biometricSourceType: BiometricSourceType?) { + fun showUnlockRipple(biometricSourceType: BiometricSourceType) { if (!keyguardStateController.isShowing || - keyguardUpdateMonitor.userNeedsStrongAuth()) { + !keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(biometricSourceType)) { return } @@ -246,7 +246,7 @@ class AuthRippleController @Inject constructor( object : KeyguardUpdateMonitorCallback() { override fun onBiometricAuthenticated( userId: Int, - biometricSourceType: BiometricSourceType?, + biometricSourceType: BiometricSourceType, isStrongBiometric: Boolean ) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) { @@ -255,14 +255,14 @@ class AuthRippleController @Inject constructor( showUnlockRipple(biometricSourceType) } - override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) { + override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) { mView.retractDwellRipple() } } override fun onBiometricAcquired( - biometricSourceType: BiometricSourceType?, + biometricSourceType: BiometricSourceType, acquireInfo: Int ) { if (biometricSourceType == BiometricSourceType.FINGERPRINT && diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt index 84a80744185ec..2cf5fb98d07e0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.domain.interactor import android.content.res.ColorStateList +import android.hardware.biometrics.BiometricSourceType import android.os.Handler import android.os.Trace import android.os.UserHandle @@ -71,7 +72,7 @@ constructor( KeyguardUpdateMonitor.getCurrentUser() ) && !needsFullscreenBouncer() && - !keyguardUpdateMonitor.userNeedsStrongAuth() && + keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE) && !keyguardBypassController.bypassEnabled /** Runnable to show the primary bouncer. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index aa0757e1d572d..000fe140882c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -240,8 +240,8 @@ public class KeyguardBouncer { && !mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( KeyguardUpdateMonitor.getCurrentUser()) && !needsFullscreenBouncer() - && !mKeyguardUpdateMonitor.isFaceLockedOut() - && !mKeyguardUpdateMonitor.userNeedsStrongAuth() + && mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + BiometricSourceType.FACE) && !mKeyguardBypassController.getBypassEnabled()) { mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY); } else { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt index 88396628017b9..afd582a3b8228 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt @@ -63,7 +63,6 @@ private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel( credentialAttempted = false, deviceInteractive = false, dreaming = false, - encryptedOrLockdown = false, fingerprintDisabled = false, fingerprintLockedOut = false, goingToSleep = false, @@ -74,6 +73,7 @@ private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel( primaryUser = false, shouldListenSfpsState = false, shouldListenForFingerprintAssistant = false, + strongerAuthRequired = false, switchingUser = false, udfps = false, userDoesNotHaveTrust = false diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 4d58b09f10767..e39b9b58158f9 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -379,9 +379,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { } @Test - public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() { + public void onBouncerVisibilityChanged_unlockingWithFingerprintNotAllowed_sideFpsHintHidden() { setupConditionsToEnableSideFpsHint(); - setNeedsStrongAuth(true); + setUnlockingWithFingerprintAllowed(false); reset(mSideFpsController); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); @@ -574,7 +574,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { attachView(); setSideFpsHintEnabledFromResources(true); setFingerprintDetectionRunning(true); - setNeedsStrongAuth(false); + setUnlockingWithFingerprintAllowed(true); } private void attachView() { @@ -593,9 +593,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { enabled); } - private void setNeedsStrongAuth(boolean needed) { - when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed); - mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0); + private void setUnlockingWithFingerprintAllowed(boolean allowed) { + when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()).thenReturn(allowed); } private void setupGetSecurityView() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index beb9a72de3243..1cce472b7c735 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -27,6 +27,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.BIOMETRIC_STATE_CANCELLING_RESTARTING; import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT; import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser; @@ -281,7 +282,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { componentInfo, FaceSensorProperties.TYPE_UNKNOWN, false /* supportsFaceDetection */, true /* supportsSelfIllumination */, false /* resetLockoutRequiresChallenge */)); - when(mFingerprintManager.isHardwareDetected()).thenReturn(true); when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true); when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of( @@ -594,30 +594,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test - public void testFingerprintDoesNotAuth_whenEncrypted() { - testFingerprintWhenStrongAuth( - STRONG_AUTH_REQUIRED_AFTER_BOOT); - } - - @Test - public void testFingerprintDoesNotAuth_whenDpmLocked() { - testFingerprintWhenStrongAuth( - KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW); - } - - @Test - public void testFingerprintDoesNotAuth_whenUserLockdown() { - testFingerprintWhenStrongAuth( - KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); - } - - private void testFingerprintWhenStrongAuth(int strongAuth) { + public void testOnlyDetectFingerprint_whenFingerprintUnlockNotAllowed() { // Clear invocations, since previous setup (e.g. registering BiometricManager callbacks) // will trigger updateBiometricListeningState(); clearInvocations(mFingerprintManager); mKeyguardUpdateMonitor.resetBiometricListeningState(); - when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth); + when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false); mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); mTestableLooper.processAllMessages(); @@ -928,10 +911,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { faceLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE; final boolean fpLocked = fingerprintLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE; - when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser))) - .thenReturn(fingerprintLockoutMode); - when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser))) - .thenReturn(faceLockoutMode); mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); @@ -940,7 +919,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(), anyInt()); +// resetFaceManager(); +// resetFingerprintManager(); + when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser))) + .thenReturn(fingerprintLockoutMode); + when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser))) + .thenReturn(faceLockoutMode); final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal); final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal); mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel; @@ -951,14 +936,22 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.handleUserSwitchComplete(newUser); mTestableLooper.processAllMessages(); - verify(faceCancel, faceLocked ? times(1) : never()).cancel(); - verify(fpCancel, fpLocked ? times(1) : never()).cancel(); - verify(callback, faceLocked ? times(1) : never()).onBiometricRunningStateChanged( + // THEN face and fingerprint listening are always cancelled immediately + verify(faceCancel).cancel(); + verify(callback).onBiometricRunningStateChanged( eq(false), eq(BiometricSourceType.FACE)); - verify(callback, fpLocked ? times(1) : never()).onBiometricRunningStateChanged( + verify(fpCancel).cancel(); + verify(callback).onBiometricRunningStateChanged( eq(false), eq(BiometricSourceType.FINGERPRINT)); + + // THEN locked out states are updated assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked); assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked); + + // Fingerprint should be restarted once its cancelled bc on lockout, the device + // can still detectFingerprint (and if it's not locked out, fingerprint can listen) + assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState) + .isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING); } @Test @@ -1144,9 +1137,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { // GIVEN status bar state is on the keyguard mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD); - // WHEN user hasn't authenticated since last boot - when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser())) - .thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT); + // WHEN user hasn't authenticated since last boot, cannot unlock with FP + when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false); // THEN we shouldn't listen for udfps assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false); @@ -1259,8 +1251,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true); // WHEN device in lock down - when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn( - KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false); // THEN we shouldn't listen for udfps assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt index 0b528a5c8d1e9..eb8c823ffe1c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt @@ -37,7 +37,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.leak.RotationUtils -import javax.inject.Provider +import com.android.systemui.util.mockito.any import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -46,15 +46,16 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers +import org.mockito.ArgumentMatchers.eq import org.mockito.Mock -import org.mockito.Mockito.any +import org.mockito.Mockito.`when` import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import org.mockito.MockitoSession import org.mockito.quality.Strictness +import javax.inject.Provider @SmallTest @RunWith(AndroidTestingRunner::class) @@ -118,12 +119,13 @@ class AuthRippleControllerTest : SysuiTestCase() { @Test fun testFingerprintTrigger_KeyguardShowing_Ripple() { - // GIVEN fp exists, keyguard is showing, user doesn't need strong auth + // GIVEN fp exists, keyguard is showing, unlocking with fp allowed val fpsLocation = Point(5, 5) `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) controller.onViewAttached() `when`(keyguardStateController.isShowing).thenReturn(true) - `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false) + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + eq(BiometricSourceType.FINGERPRINT))).thenReturn(true) // WHEN fingerprint authenticated val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) @@ -140,11 +142,12 @@ class AuthRippleControllerTest : SysuiTestCase() { @Test fun testFingerprintTrigger_KeyguardNotShowing_NoRipple() { - // GIVEN fp exists & user doesn't need strong auth + // GIVEN fp exists & unlocking with fp allowed val fpsLocation = Point(5, 5) `when`(authController.udfpsLocation).thenReturn(fpsLocation) controller.onViewAttached() - `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false) + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + eq(BiometricSourceType.FINGERPRINT))).thenReturn(true) // WHEN keyguard is NOT showing & fingerprint authenticated `when`(keyguardStateController.isShowing).thenReturn(false) @@ -160,15 +163,16 @@ class AuthRippleControllerTest : SysuiTestCase() { } @Test - fun testFingerprintTrigger_StrongAuthRequired_NoRipple() { + fun testFingerprintTrigger_biometricUnlockNotAllowed_NoRipple() { // GIVEN fp exists & keyguard is showing val fpsLocation = Point(5, 5) `when`(authController.udfpsLocation).thenReturn(fpsLocation) controller.onViewAttached() `when`(keyguardStateController.isShowing).thenReturn(true) - // WHEN user needs strong auth & fingerprint authenticated - `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(true) + // WHEN unlocking with fingerprint is NOT allowed & fingerprint authenticated + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + eq(BiometricSourceType.FINGERPRINT))).thenReturn(false) val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) verify(keyguardUpdateMonitor).registerCallback(captor.capture()) captor.value.onBiometricAuthenticated( @@ -182,13 +186,14 @@ class AuthRippleControllerTest : SysuiTestCase() { @Test fun testFaceTriggerBypassEnabled_Ripple() { - // GIVEN face auth sensor exists, keyguard is showing & strong auth isn't required + // GIVEN face auth sensor exists, keyguard is showing & unlocking with face is allowed val faceLocation = Point(5, 5) `when`(authController.faceSensorLocation).thenReturn(faceLocation) controller.onViewAttached() `when`(keyguardStateController.isShowing).thenReturn(true) - `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false) + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + BiometricSourceType.FACE)).thenReturn(true) // WHEN bypass is enabled & face authenticated `when`(bypassController.canBypass()).thenReturn(true) @@ -275,6 +280,8 @@ class AuthRippleControllerTest : SysuiTestCase() { `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) controller.onViewAttached() `when`(keyguardStateController.isShowing).thenReturn(true) + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + BiometricSourceType.FINGERPRINT)).thenReturn(true) `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) controller.showUnlockRipple(BiometricSourceType.FINGERPRINT) @@ -295,6 +302,8 @@ class AuthRippleControllerTest : SysuiTestCase() { `when`(keyguardStateController.isShowing).thenReturn(true) `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) `when`(authController.isUdfpsFingerDown).thenReturn(true) + `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + eq(BiometricSourceType.FACE))).thenReturn(true) controller.showUnlockRipple(BiometricSourceType.FACE) assertTrue("reveal didn't start on keyguardFadingAway", diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index d3b5418996359..df7ee432e79e2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -39,6 +39,7 @@ import static org.mockito.Mockito.when; import android.content.res.ColorStateList; import android.graphics.Color; +import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -398,6 +399,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { @Test public void testShow_delaysIfFaceAuthIsRunning() { + when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)) + .thenReturn(true); when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true); mBouncer.show(true /* reset */); @@ -410,9 +413,10 @@ public class KeyguardBouncerTest extends SysuiTestCase { } @Test - public void testShow_doesNotDelaysIfFaceAuthIsLockedOut() { + public void testShow_doesNotDelaysIfFaceAuthIsNotAllowed() { when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true); - when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(true); + when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)) + .thenReturn(false); mBouncer.show(true /* reset */); verify(mHandler, never()).postDelayed(any(), anyLong());