summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt131
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt2
10 files changed, 210 insertions, 45 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 91259a65eff9..3e75cebb1c7d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -34,6 +34,7 @@ import android.hardware.face.FaceSensorPropertiesInternal
import android.os.CancellationSignal
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
import com.android.internal.logging.InstanceId.fakeInstanceId
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Flags as AConfigFlags
@@ -55,6 +56,7 @@ import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus
import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.keyguard.data.repository.BiometricType
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
@@ -77,6 +79,9 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
@@ -90,6 +95,7 @@ import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.StringWriter
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
@@ -136,12 +142,12 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
@Captor
private lateinit var faceLockoutResetCallback: ArgumentCaptor<FaceManager.LockoutResetCallback>
- private val testDispatcher = kosmos.testDispatcher
+ private val testDispatcher by lazy { kosmos.testDispatcher }
- private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
- private val testScope = kosmos.testScope
- private val fakeUserRepository = kosmos.fakeUserRepository
- private val fakeExecutor = kosmos.fakeExecutor
+ private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
+ private val testScope by lazy { kosmos.testScope }
+ private val fakeUserRepository by lazy { kosmos.fakeUserRepository }
+ private val fakeExecutor by lazy { kosmos.fakeExecutor }
private lateinit var authStatus: FlowValue<FaceAuthenticationStatus?>
private lateinit var detectStatus: FlowValue<FaceDetectionStatus?>
private lateinit var authRunning: FlowValue<Boolean?>
@@ -149,18 +155,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
private lateinit var lockedOut: FlowValue<Boolean?>
private lateinit var canFaceAuthRun: FlowValue<Boolean?>
private lateinit var authenticated: FlowValue<Boolean?>
- private val biometricSettingsRepository = kosmos.fakeBiometricSettingsRepository
- private val deviceEntryFingerprintAuthRepository =
+ private val biometricSettingsRepository by lazy { kosmos.fakeBiometricSettingsRepository }
+ private val deviceEntryFingerprintAuthRepository by lazy {
kosmos.fakeDeviceEntryFingerprintAuthRepository
- private val trustRepository = kosmos.fakeTrustRepository
- private val keyguardRepository = kosmos.fakeKeyguardRepository
- private val powerInteractor = kosmos.powerInteractor
- private val keyguardInteractor = kosmos.keyguardInteractor
- private val alternateBouncerInteractor = kosmos.alternateBouncerInteractor
- private val displayStateInteractor = kosmos.displayStateInteractor
- private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
- private val displayRepository = kosmos.displayRepository
- private val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
+ }
+ private val trustRepository by lazy { kosmos.fakeTrustRepository }
+ private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository }
+ private val powerInteractor by lazy { kosmos.powerInteractor }
+ private val keyguardInteractor by lazy { kosmos.keyguardInteractor }
+ private val alternateBouncerInteractor by lazy { kosmos.alternateBouncerInteractor }
+ private val displayStateInteractor by lazy { kosmos.displayStateInteractor }
+ private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository }
+ private val displayRepository by lazy { kosmos.displayRepository }
+ private val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
private lateinit var featureFlags: FakeFeatureFlags
private var wasAuthCancelled = false
@@ -180,9 +187,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
whenever(bypassController.bypassEnabled).thenReturn(true)
underTest = createDeviceEntryFaceAuthRepositoryImpl(faceManager, bypassController)
- mSetFlagsRule.disableFlags(
- AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
- )
+ if (!SceneContainerFlag.isEnabled) {
+ mSetFlagsRule.disableFlags(
+ AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
+ )
+ }
}
private fun createDeviceEntryFaceAuthRepositoryImpl(
@@ -227,6 +236,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
powerInteractor,
keyguardInteractor,
alternateBouncerInteractor,
+ { kosmos.sceneInteractor },
faceDetectBuffer,
faceAuthBuffer,
keyguardTransitionInteractor,
@@ -547,6 +557,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun withSceneContainerEnabled_authenticateDoesNotRunWhenKeyguardIsGoingAway() =
+ testScope.runTest {
+ testGatingCheckForFaceAuth(sceneContainerEnabled = true) {
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ KeyguardState.LOCKSCREEN,
+ KeyguardState.UNDEFINED,
+ value = 0.5f,
+ transitionState = TransitionState.RUNNING
+ ),
+ validateStep = false
+ )
+ runCurrent()
+ }
+ }
+
+ @Test
fun authenticateDoesNotRunWhenDeviceIsGoingToSleep() =
testScope.runTest {
testGatingCheckForFaceAuth {
@@ -595,6 +623,31 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun withSceneContainer_authenticateRunsWhenSecureCameraIsActiveIfBouncerIsShowing() =
+ testScope.runTest {
+ initCollectors()
+ allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled = true)
+ bouncerRepository.setAlternateVisible(false)
+
+ // launch secure camera
+ keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
+ keyguardRepository.setKeyguardOccluded(true)
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "for-test")
+ runCurrent()
+ assertThat(canFaceAuthRun()).isFalse()
+
+ // but bouncer is shown after that.
+ kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test")
+ kosmos.sceneInteractor.setTransitionState(
+ MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer))
+ )
+ runCurrent()
+
+ assertThat(canFaceAuthRun()).isTrue()
+ }
+
+ @Test
fun authenticateDoesNotRunOnUnsupportedPosture() =
testScope.runTest {
testGatingCheckForFaceAuth {
@@ -841,6 +894,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun withSceneContainer_faceDetectDoesNotRunWhenKeyguardGoingAway() =
+ testScope.runTest {
+ testGatingCheckForDetect(sceneContainerEnabled = true) {
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ KeyguardState.LOCKSCREEN,
+ KeyguardState.UNDEFINED,
+ value = 0.5f,
+ transitionState = TransitionState.RUNNING
+ ),
+ validateStep = false
+ )
+ runCurrent()
+ }
+ }
+
+ @Test
fun detectDoesNotRunWhenDeviceSleepingStartingToSleep() =
testScope.runTest {
testGatingCheckForDetect {
@@ -1052,10 +1123,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
private suspend fun TestScope.testGatingCheckForFaceAuth(
+ sceneContainerEnabled: Boolean = false,
gatingCheckModifier: suspend () -> Unit
) {
initCollectors()
- allPreconditionsToRunFaceAuthAreTrue()
+ allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
gatingCheckModifier()
runCurrent()
@@ -1069,7 +1141,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
faceAuthenticateIsNotCalled()
// flip the gating check back on.
- allPreconditionsToRunFaceAuthAreTrue()
+ allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
assertThat(underTest.canRunFaceAuth.value).isTrue()
faceAuthenticateIsCalled()
@@ -1094,10 +1166,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
private suspend fun TestScope.testGatingCheckForDetect(
+ sceneContainerEnabled: Boolean = false,
gatingCheckModifier: suspend () -> Unit
) {
initCollectors()
- allPreconditionsToRunFaceAuthAreTrue()
+ allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled)
// This will stop face auth from running but is required to be false for detect.
biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(false)
@@ -1145,12 +1218,22 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
cancellationSignal.value.setOnCancelListener { wasAuthCancelled = true }
}
- private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue() {
+ private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue(
+ sceneContainerEnabled: Boolean = false
+ ) {
fakeExecutor.runAllReady()
verify(faceManager, atLeastOnce())
.addLockoutResetCallback(faceLockoutResetCallback.capture())
trustRepository.setCurrentUserTrusted(false)
- keyguardRepository.setKeyguardGoingAway(false)
+ if (sceneContainerEnabled) {
+ // Keyguard is not going away
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(KeyguardState.OFF, KeyguardState.LOCKSCREEN, value = 1.0f),
+ validateStep = false
+ )
+ } else {
+ keyguardRepository.setKeyguardGoingAway(false)
+ }
powerInteractor.setAwakeForTest()
biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
biometricSettingsRepository.setIsFaceAuthSupportedInCurrentPosture(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
index 2b2c121fb79a..aee72de22a24 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
@@ -25,8 +25,11 @@ import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.logging.uiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
+import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -260,6 +263,23 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
}
@Test
+ fun triggersFaceAuthWhenLockscreenIsClicked() =
+ testScope.runTest {
+ collectLastValue(underTest.isMenuVisible)
+ runCurrent()
+ kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = true
+
+ underTest.onClick(100.0f, 100.0f)
+ runCurrent()
+
+ val runningAuthRequest =
+ kosmos.fakeDeviceEntryFaceAuthRepository.runningAuthRequest.value
+ assertThat(runningAuthRequest?.first)
+ .isEqualTo(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
+ assertThat(runningAuthRequest?.second).isEqualTo(true)
+ }
+
+ @Test
fun showMenu_leaveLockscreen_returnToLockscreen_menuNotVisible() =
testScope.runTest {
val isMenuVisible by collectLastValue(underTest.isMenuVisible)
@@ -302,6 +322,7 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
broadcastDispatcher = fakeBroadcastDispatcher,
accessibilityManager = kosmos.accessibilityManagerWrapper,
pulsingGestureListener = kosmos.pulsingGestureListener,
+ faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor,
)
setUpState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index 9460eaf8abca..d288ccee2ae8 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -57,7 +57,10 @@ import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.log.SessionTracker
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.Scenes.Bouncer
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
@@ -159,6 +162,7 @@ constructor(
private val powerInteractor: PowerInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val alternateBouncerInteractor: AlternateBouncerInteractor,
+ private val sceneInteractor: dagger.Lazy<SceneInteractor>,
@FaceDetectTableLog private val faceDetectLog: TableLogBuffer,
@FaceAuthTableLog private val faceAuthLog: TableLogBuffer,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -385,7 +389,16 @@ constructor(
biometricSettingsRepository.isFaceAuthEnrolledAndEnabled,
"isFaceAuthEnrolledAndEnabled"
),
- Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"),
+ Pair(
+ if (SceneContainerFlag.isEnabled) {
+ keyguardTransitionInteractor
+ .isInTransitionWhere(toStatePredicate = { it == KeyguardState.UNDEFINED })
+ .isFalse()
+ } else {
+ keyguardRepository.isKeyguardGoingAway.isFalse()
+ },
+ "keyguardNotGoingAway"
+ ),
Pair(
keyguardTransitionInteractor
.isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState)
@@ -397,7 +410,11 @@ constructor(
.isFalse()
.or(
alternateBouncerInteractor.isVisible.or(
- keyguardInteractor.primaryBouncerShowing
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.get().transitionState.map { it.isIdle(Bouncer) }
+ } else {
+ keyguardInteractor.primaryBouncerShowing
+ }
)
),
"secureCameraNotActiveOrAnyBouncerIsShowing"
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
index c536d6b4f6f8..183e0e96e765 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
@@ -46,6 +46,9 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
@@ -90,6 +93,7 @@ constructor(
private val powerInteractor: PowerInteractor,
private val biometricSettingsRepository: BiometricSettingsRepository,
private val trustManager: TrustManager,
+ private val sceneInteractor: Lazy<SceneInteractor>,
deviceEntryFaceAuthStatusInteractor: DeviceEntryFaceAuthStatusInteractor,
) : DeviceEntryFaceAuthInteractor {
@@ -103,9 +107,7 @@ constructor(
keyguardUpdateMonitor.setFaceAuthInteractor(this)
observeFaceAuthStateUpdates()
faceAuthenticationLogger.interactorStarted()
- primaryBouncerInteractor
- .get()
- .isShowing
+ isBouncerVisible
.whenItFlipsToTrue()
.onEach {
faceAuthenticationLogger.bouncerVisibilityChanged()
@@ -181,19 +183,23 @@ constructor(
// auth so that the switched user can unlock the device with face auth.
userRepository.selectedUser
.pairwise()
- .onEach { (previous, curr) ->
+ .filter { (previous, curr) ->
val wasSwitching = previous.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS
val isSwitching = curr.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS
- if (wasSwitching && !isSwitching) {
- resetLockedOutState(curr.userInfo.id)
- yield()
- runFaceAuth(
- FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING,
- // Fallback to detection if bouncer is not showing so that we can detect a
- // face and then show the bouncer to the user if face auth can't run
- fallbackToDetect = !primaryBouncerInteractor.get().isBouncerShowing()
- )
- }
+ // User switching was in progress and is complete now.
+ wasSwitching && !isSwitching
+ }
+ .map { (_, curr) -> curr.userInfo.id }
+ .sample(isBouncerVisible, ::Pair)
+ .onEach { (userId, isBouncerCurrentlyVisible) ->
+ resetLockedOutState(userId)
+ yield()
+ runFaceAuth(
+ FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING,
+ // Fallback to detection if bouncer is not showing so that we can detect a
+ // face and then show the bouncer to the user if face auth can't run
+ fallbackToDetect = !isBouncerCurrentlyVisible
+ )
}
.launchIn(applicationScope)
@@ -210,6 +216,14 @@ constructor(
.launchIn(applicationScope)
}
+ private val isBouncerVisible: Flow<Boolean> by lazy {
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.get().transitionState.map { it.isIdle(Scenes.Bouncer) }
+ } else {
+ primaryBouncerInteractor.get().isShowing
+ }
+ }
+
private suspend fun resetLockedOutState(currentUserId: Int) {
val lockoutMode = facePropertyRepository.getLockoutMode(currentUserId)
repository.setLockedOut(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
index cd49c6a4d2e0..4a8ada7f1184 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
@@ -27,6 +27,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.KeyguardRepository
@@ -67,6 +68,7 @@ constructor(
broadcastDispatcher: BroadcastDispatcher,
private val accessibilityManager: AccessibilityManagerWrapper,
private val pulsingGestureListener: PulsingGestureListener,
+ private val faceAuthInteractor: DeviceEntryFaceAuthInteractor,
) {
/** Whether the long-press handling feature should be enabled. */
val isLongPressHandlingEnabled: StateFlow<Boolean> =
@@ -129,7 +131,8 @@ constructor(
}
}
- /** Notifies that the user has long-pressed on the lock screen.
+ /**
+ * Notifies that the user has long-pressed on the lock screen.
*
* @param isA11yAction: Whether the action was performed as an a11y action
*/
@@ -174,6 +177,7 @@ constructor(
/** Notifies that the lockscreen has been clicked at position [x], [y]. */
fun onClick(x: Float, y: Float) {
pulsingGestureListener.onSingleTapUp(x, y)
+ faceAuthInteractor.onNotificationPanelClicked()
}
/** Notifies that the lockscreen has been double clicked. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index 0b7a3ed3a7c2..6aecc0e2b8fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -22,6 +22,7 @@ import android.hardware.biometrics.BiometricSourceType
import android.os.PowerManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
import com.android.keyguard.keyguardUpdateMonitor
import com.android.keyguard.trustManager
import com.android.systemui.SysuiTestCase
@@ -37,6 +38,7 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeFaceWakeUpTriggersConfig
import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
@@ -52,12 +54,15 @@ import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.mockito.eq
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -113,6 +118,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
powerInteractor,
fakeBiometricSettingsRepository,
trustManager,
+ { kosmos.sceneInteractor },
deviceEntryFaceAuthStatusInteractor,
)
}
@@ -279,6 +285,22 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableSceneContainer
+ fun withSceneContainerEnabled_faceAuthIsRequestedWhenPrimaryBouncerIsVisible() =
+ testScope.runTest {
+ underTest.start()
+
+ kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test")
+ kosmos.sceneInteractor.setTransitionState(
+ MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer))
+ )
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value)
+ .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN, false))
+ }
+
+ @Test
fun faceAuthIsRequestedWhenAlternateBouncerIsVisible() =
testScope.runTest {
underTest.start()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index fc7f69319261..d13419eed281 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.animation.Expandable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.dock.DockManagerFake
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.flags.FakeFeatureFlags
@@ -152,9 +153,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC
dockManager = DockManagerFake()
biometricSettingsRepository = FakeBiometricSettingsRepository()
val featureFlags =
- FakeFeatureFlags().apply {
- set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false)
- }
+ FakeFeatureFlags().apply { set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false) }
val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
val keyguardInteractor = withDeps.keyguardInteractor
@@ -223,6 +222,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManager,
pulsingGestureListener = kosmos.pulsingGestureListener,
+ faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor,
)
underTest =
KeyguardBottomAreaViewModel(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
index b9be04dc0a32..3dfe0eea500f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt
@@ -33,6 +33,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.user.data.repository.userRepository
import com.android.systemui.util.mockito.mock
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -57,6 +58,7 @@ val Kosmos.deviceEntryFaceAuthInteractor by
powerInteractor = powerInteractor,
biometricSettingsRepository = biometricSettingsRepository,
trustManager = trustManager,
+ sceneInteractor = { sceneInteractor },
deviceEntryFaceAuthStatusInteractor = deviceEntryFaceAuthStatusInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
index 73799b63a6fc..769612c988ba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
@@ -20,6 +20,7 @@ import android.content.applicationContext
import android.view.accessibility.accessibilityManagerWrapper
import com.android.internal.logging.uiEventLogger
import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
@@ -38,5 +39,6 @@ val Kosmos.keyguardTouchHandlingInteractor by
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManagerWrapper,
pulsingGestureListener = pulsingGestureListener,
+ faceAuthInteractor = deviceEntryFaceAuthInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index ae8b411a4b95..f84c3bdfdaf1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -24,7 +24,7 @@ import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.domain.resolver.sceneFamilyResolvers
import com.android.systemui.scene.shared.logger.sceneLogger
-val Kosmos.sceneInteractor by
+val Kosmos.sceneInteractor: SceneInteractor by
Kosmos.Fixture {
SceneInteractor(
applicationScope = applicationCoroutineScope,