summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java36
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java30
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt1
12 files changed, 123 insertions, 20 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 37bd9b287ebd..9c61a8a3cd8b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1277,6 +1277,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final FaceAuthenticationListener mFaceAuthenticationListener =
new FaceAuthenticationListener() {
+ public void onAuthenticatedChanged(boolean isAuthenticated) {
+ if (!isAuthenticated) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onFacesCleared();
+ }
+ }
+ }
+ }
+
@Override
public void onAuthEnrollmentStateChanged(boolean enrolled) {
notifyAboutEnrollmentChange(TYPE_FACE);
@@ -1961,7 +1972,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
protected void handleStartedGoingToSleep(int arg1) {
Assert.isMainThread();
- clearBiometricRecognized();
+ clearFingerprintRecognized();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -3010,7 +3021,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
void handleUserSwitching(int userId, Runnable resultCallback) {
mLogger.logUserSwitching(userId, "from UserTracker");
Assert.isMainThread();
- clearBiometricRecognized();
+ clearFingerprintRecognized();
boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userId);
mLogger.logTrustUsuallyManagedUpdated(userId, mUserTrustIsUsuallyManaged.get(userId),
trustUsuallyManaged, "userSwitching");
@@ -3560,25 +3571,30 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
return mServiceStates.get(subId);
}
- public void clearBiometricRecognized() {
- clearBiometricRecognized(UserHandle.USER_NULL);
+ /**
+ * Resets the fingerprint authenticated state to false.
+ */
+ public void clearFingerprintRecognized() {
+ clearFingerprintRecognized(UserHandle.USER_NULL);
}
- public void clearBiometricRecognizedWhenKeyguardDone(int unlockedUser) {
- clearBiometricRecognized(unlockedUser);
+ /**
+ * Resets the fingerprint authenticated state to false.
+ */
+ public void clearFingerprintRecognizedWhenKeyguardDone(int unlockedUser) {
+ clearFingerprintRecognized(unlockedUser);
}
- private void clearBiometricRecognized(int unlockedUser) {
+ private void clearFingerprintRecognized(int unlockedUser) {
Assert.isMainThread();
mUserFingerprintAuthenticated.clear();
mTrustManager.clearAllBiometricRecognized(FINGERPRINT, unlockedUser);
- mTrustManager.clearAllBiometricRecognized(FACE, unlockedUser);
- mLogger.d("clearBiometricRecognized");
+ mLogger.d("clearFingerprintRecognized");
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onBiometricsCleared();
+ cb.onFingerprintsCleared();
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 02dd3312c587..9d216dcede2b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -291,9 +291,14 @@ public class KeyguardUpdateMonitorCallback {
public void onLogoutEnabledChanged() { }
/**
- * Called when authenticated biometrics are cleared.
+ * Called when authenticated fingerprint biometrics are cleared.
*/
- public void onBiometricsCleared() { }
+ public void onFingerprintsCleared() { }
+
+ /**
+ * Called when authenticated face biometrics have cleared.
+ */
+ public void onFacesCleared() { }
/**
* Called when the secondary lock screen requirement changes.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
index 9c13a8c82b11..3fac865ffb1d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
@@ -43,7 +43,7 @@ public class DozeAuthRemover implements DozeMachine.Part {
if (newState == DozeMachine.State.DOZE || newState == DozeMachine.State.DOZE_AOD) {
int currentUser = mSelectedUserInteractor.getSelectedUserId();
if (mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(currentUser)) {
- mKeyguardUpdateMonitor.clearBiometricRecognized();
+ mKeyguardUpdateMonitor.clearFingerprintRecognized();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 30090874a480..b7260f2b2b94 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2611,14 +2611,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
if (mGoingToSleep) {
- mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser);
+ mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
return;
}
setPendingLock(false); // user may have authenticated during the screen off animation
handleHide();
- mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser);
+ mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
Trace.endSection();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index e47c44863980..eceaf6c3c4fd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -326,7 +326,7 @@ constructor(
it.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS
},
)
- .flowOn(backgroundDispatcher)
+ .flowOn(mainDispatcher) // should revoke auth ASAP in the main thread
.onEach { anyOfThemIsTrue ->
if (anyOfThemIsTrue) {
clearPendingAuthRequest("Resetting auth status")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
index 5ed70b526f1b..046916aeb277 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
@@ -78,6 +78,9 @@ interface KeyguardFaceAuthInteractor {
* flows.
*/
interface FaceAuthenticationListener {
+ /** Receive face isAuthenticated updates */
+ fun onAuthenticatedChanged(isAuthenticated: Boolean)
+
/** Receive face authentication status updates */
fun onAuthenticationStatusChanged(status: FaceAuthenticationStatus)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index 532df4afebf7..fb20000471a2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -16,8 +16,10 @@
package com.android.systemui.keyguard.domain.interactor
+import android.app.trust.TrustManager
import android.content.Context
import android.hardware.biometrics.BiometricFaceConstants
+import android.hardware.biometrics.BiometricSourceType
import com.android.keyguard.FaceAuthUiEvent
import com.android.keyguard.FaceWakeUpTriggersConfig
import com.android.keyguard.KeyguardUpdateMonitor
@@ -83,6 +85,7 @@ constructor(
private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig,
private val powerInteractor: PowerInteractor,
private val biometricSettingsRepository: BiometricSettingsRepository,
+ private val trustManager: TrustManager,
) : CoreStartable, KeyguardFaceAuthInteractor {
private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf()
@@ -291,6 +294,20 @@ constructor(
.onEach { running -> listeners.forEach { it.onRunningStateChanged(running) } }
.flowOn(mainDispatcher)
.launchIn(applicationScope)
+ repository.isAuthenticated
+ .sample(userRepository.selectedUserInfo, ::Pair)
+ .onEach { (isAuthenticated, userInfo) ->
+ if (!isAuthenticated) {
+ faceAuthenticationLogger.clearFaceRecognized()
+ trustManager.clearAllBiometricRecognized(BiometricSourceType.FACE, userInfo.id)
+ }
+ }
+ .flowOn(backgroundDispatcher)
+ .onEach { (isAuthenticated, _) ->
+ listeners.forEach { it.onAuthenticatedChanged(isAuthenticated) }
+ }
+ .flowOn(mainDispatcher)
+ .launchIn(applicationScope)
biometricSettingsRepository.isFaceAuthEnrolledAndEnabled
.onEach { enrolledAndEnabled ->
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index 8c5690b312ec..3c2facbc967a 100644
--- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -132,6 +132,10 @@ constructor(
logBuffer.log(TAG, DEBUG, "Face authentication failed")
}
+ fun clearFaceRecognized() {
+ logBuffer.log(TAG, DEBUG, "Clear face recognized")
+ }
+
fun authenticationError(
errorCode: Int,
errString: CharSequence?,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 80c68023b4c8..756c440eca89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -484,7 +484,12 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
}
@Override
- public void onBiometricsCleared() {
+ public void onFingerprintsCleared() {
+ update(false /* alwaysUpdate */);
+ }
+
+ @Override
+ public void onFacesCleared() {
update(false /* alwaysUpdate */);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index de12b8f91d20..4ab8e28bc232 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -17,8 +17,10 @@
package com.android.systemui.keyguard.domain.interactor
+import android.app.trust.TrustManager
import android.content.pm.UserInfo
import android.hardware.biometrics.BiometricFaceConstants
+import android.hardware.biometrics.BiometricSourceType
import android.os.Handler
import android.os.PowerManager
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -62,6 +64,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -74,8 +77,11 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@@ -99,7 +105,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig
- @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor
+ @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
+ @Mock private lateinit var trustManager: TrustManager
@Before
fun setup() {
@@ -146,7 +153,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
keyguardUpdateMonitor,
FakeTrustRepository(),
testScope.backgroundScope,
- mSelectedUserInteractor,
+ selectedUserInteractor,
underTest,
)
},
@@ -169,6 +176,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
faceWakeUpTriggersConfig,
powerInteractor,
fakeBiometricSettingsRepository,
+ trustManager,
)
}
@@ -498,6 +506,22 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
assertThat(faceAuthRepository.isLockedOut.value).isTrue()
}
+ @Test
+ fun whenIsAuthenticatedFalse_clearFaceBiometrics() =
+ testScope.runTest {
+ underTest.start()
+
+ faceAuthRepository.isAuthenticated.value = true
+ runCurrent()
+ verify(trustManager, never())
+ .clearAllBiometricRecognized(eq(BiometricSourceType.FACE), anyInt())
+
+ faceAuthRepository.isAuthenticated.value = false
+ runCurrent()
+
+ verify(trustManager).clearAllBiometricRecognized(eq(BiometricSourceType.FACE), anyInt())
+ }
+
companion object {
private const val primaryUserId = 1
private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
index 01dad381efa0..479309c18c92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
@@ -153,6 +153,36 @@ public class KeyguardStateControllerTest extends SysuiTestCase {
}
@Test
+ public void testCanSkipLockScreen_updateCalledOnFacesCleared() {
+ verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
+
+ // Cannot skip after there's a password/pin/pattern
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
+ assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse();
+
+ // Unless user is authenticated
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
+ mUpdateCallbackCaptor.getValue().onFacesCleared();
+ assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
+ }
+
+ @Test
+ public void testCanSkipLockScreen_updateCalledOnFingerprintssCleared() {
+ verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
+
+ // Cannot skip after there's a password/pin/pattern
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
+ assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse();
+
+ // Unless user is authenticated
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
+ mUpdateCallbackCaptor.getValue().onFingerprintsCleared();
+ assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
+ }
+
+ @Test
public void testIsUnlocked() {
// Is unlocked whenever the keyguard is not showing
assertThat(mKeyguardStateController.isShowing()).isFalse();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
index e289083a2d9e..a1b6587be0b8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
@@ -31,7 +31,6 @@ import kotlinx.coroutines.flow.filterNotNull
@SysUISingleton
class FakeDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceAuthRepository {
-
override val isAuthenticated = MutableStateFlow(false)
override val canRunFaceAuth = MutableStateFlow(false)
private val _authenticationStatus = MutableStateFlow<FaceAuthenticationStatus?>(null)