Do not run face detection for bypass when the user is authenticated by FP

FP authentication always dismisses the lock screen.

Fixes: 258323361
Test: atest KeyguardUpdateMonitorTest
Test: 1. Enroll face unlock & fp unlock
      2. Enable skip lockscreen under face unlock
      3. Lock the phone.
      4. Fail face auth 3 times to lock it out.
      5. Unlock the phone using UDFPS
      6. Face scanning animation should not be visible
      7. Camera protection ring should not be visible.
Change-Id: I809c8c5ce331f57d8a9b3407dd83ee5b8cc59768
This commit is contained in:
Chandru
2022-11-16 14:30:00 +00:00
committed by Chandru S
parent 3c3ac139ab
commit 6f5d50696a
4 changed files with 53 additions and 17 deletions

View File

@@ -50,10 +50,9 @@ data class KeyguardFaceListenModel(
override val listening: Boolean,
// keep sorted
val authInterruptActive: Boolean,
val becauseCannotSkipBouncer: Boolean,
val biometricSettingEnabledForUser: Boolean,
val bouncerFullyShown: Boolean,
val faceAuthenticated: Boolean,
val faceAndFpNotAuthenticated: Boolean,
val faceDisabled: Boolean,
val faceLockedOut: Boolean,
val fpLockedOut: Boolean,
@@ -67,7 +66,9 @@ data class KeyguardFaceListenModel(
val secureCameraLaunched: Boolean,
val switchingUser: Boolean,
val udfpsBouncerShowing: Boolean,
) : KeyguardListenModel()
val udfpsFingerDown: Boolean,
val userNotTrustedOrDetectionIsNeeded: Boolean,
) : KeyguardListenModel()
/**
* Verbose debug information associated with [KeyguardUpdateMonitor.shouldTriggerActiveUnlock].
*/

View File

@@ -808,9 +808,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
// Don't send cancel if authentication succeeds
mFingerprintCancelSignal = null;
mLogger.logFingerprintSuccess(userId, isStrongBiometric);
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
FACE_AUTH_UPDATED_FP_AUTHENTICATED);
mLogger.logFingerprintSuccess(userId, isStrongBiometric);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2734,9 +2734,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final boolean canBypass = mKeyguardBypassController != null
&& mKeyguardBypassController.canBypass();
// There's no reason to ask the HAL for authentication when the user can dismiss the
// bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
// TrustAgents or biometrics are keeping the device unlocked.
final boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
// bouncer because the user is trusted, unless we're bypassing and need to auto-dismiss
// the lock screen even when TrustAgents are keeping the device unlocked.
final boolean userNotTrustedOrDetectionIsNeeded = !getUserHasTrust(user) || canBypass;
// Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
// Lock-down mode shouldn't scan, since it is more explicit.
@@ -2753,11 +2753,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
strongAuthAllowsScanning = false;
}
// If the face has recently been authenticated do not attempt to authenticate again.
final boolean faceAuthenticated = getIsFaceAuthenticated();
// If the face or fp has recently been authenticated do not attempt to authenticate again.
final boolean faceAndFpNotAuthenticated = !getUserUnlockedWithBiometric(user);
final boolean faceDisabledForUser = isFaceDisabled(user);
final boolean biometricEnabledForUser = mBiometricEnabledForUser.get(user);
final boolean shouldListenForFaceAssistant = shouldListenForFaceAssistant();
final boolean isUdfpsFingerDown = mAuthController.isUdfpsFingerDown();
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2767,13 +2768,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| mOccludingAppRequestingFace
|| awakeKeyguard
|| shouldListenForFaceAssistant
|| mAuthController.isUdfpsFingerDown()
|| isUdfpsFingerDown
|| mUdfpsBouncerShowing)
&& !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
&& !mSwitchingUser && !faceDisabledForUser && userNotTrustedOrDetectionIsNeeded
&& !mKeyguardGoingAway && biometricEnabledForUser
&& strongAuthAllowsScanning && mIsPrimaryUser
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
&& !faceAuthenticated
&& faceAndFpNotAuthenticated
&& !mGoingToSleep
// We only care about fp locked out state and not face because we still trigger
// face auth even when face is locked out to show the user a message that face
@@ -2787,10 +2788,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
user,
shouldListen,
mAuthInterruptActive,
becauseCannotSkipBouncer,
biometricEnabledForUser,
mPrimaryBouncerFullyShown,
faceAuthenticated,
faceAndFpNotAuthenticated,
faceDisabledForUser,
isFaceLockedOut(),
fpLockedOut,
@@ -2803,7 +2803,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
strongAuthAllowsScanning,
mSecureCameraLaunched,
mSwitchingUser,
mUdfpsBouncerShowing));
mUdfpsBouncerShowing,
isUdfpsFingerDown,
userNotTrustedOrDetectionIsNeeded));
return shouldListen;
}

View File

@@ -84,10 +84,9 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
userId = user,
listening = false,
authInterruptActive = false,
becauseCannotSkipBouncer = false,
biometricSettingEnabledForUser = false,
bouncerFullyShown = false,
faceAuthenticated = false,
faceAndFpNotAuthenticated = false,
faceDisabled = false,
faceLockedOut = false,
fpLockedOut = false,
@@ -101,4 +100,6 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
secureCameraLaunched = false,
switchingUser = false,
udfpsBouncerShowing = false,
udfpsFingerDown = false,
userNotTrustedOrDetectionIsNeeded = false
)

View File

@@ -1378,6 +1378,29 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
}
@Test
public void testShouldListenForFace_whenFpIsAlreadyAuthenticated_returnsFalse()
throws RemoteException {
// Face auth should run when the following is true.
bouncerFullyVisibleAndNotGoingToSleep();
keyguardNotGoingAway();
currentUserIsPrimary();
strongAuthNotRequired();
biometricsEnabledForCurrentUser();
currentUserDoesNotHaveTrust();
biometricsNotDisabledThroughDevicePolicyManager();
userNotCurrentlySwitching();
mTestableLooper.processAllMessages();
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
successfulFingerprintAuth();
mTestableLooper.processAllMessages();
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
}
@Test
public void testShouldListenForFace_whenUserIsNotPrimary_returnsFalse() throws RemoteException {
cleanupKeyguardUpdateMonitor();
@@ -1932,6 +1955,15 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
.onAuthenticationAcquired(FINGERPRINT_ACQUIRED_START);
}
private void successfulFingerprintAuth() {
mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
.onAuthenticationSucceeded(
new FingerprintManager.AuthenticationResult(null,
null,
mCurrentUserId,
true));
}
private void triggerSuccessfulFaceAuth() {
mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
verify(mFaceManager).authenticate(any(),