Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c7c1cc3 authored by Chandru S's avatar Chandru S
Browse files

Trigger face auth as we expand from the quick settings scene to shade.

Other changes: fix typo in method `onQsExpansionStarted`

Fixes: 361673279
Test: atest DeviceEntryFaceAuthInteractorTest
Test: manually,
 1. enroll face auth
 2. open quick settings
 3. start expansion to full shade
 4. face auth should run without affecting the shade expansion
Flag: com.android.systemui.scene_container
Change-Id: Icefdda8e76368af423dcdcc18fb7fe8f43d3b0d5
parent 905d0cdf
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -60,14 +60,23 @@ interface DeviceEntryFaceAuthInteractor : CoreStartable {
    fun unregisterListener(listener: FaceAuthenticationListener)

    fun onUdfpsSensorTouched()

    fun onAssistantTriggeredOnLockScreen()

    fun onDeviceLifted()
    fun onQsExpansionStared()

    fun onQsExpansionStarted()

    fun onNotificationPanelClicked()

    fun onSwipeUpOnBouncer()

    fun onPrimaryBouncerUserInput()

    fun onAccessibilityAction()

    fun onWalletLaunched()

    fun onDeviceUnfolded()

    /** Whether face auth is considered class 3 */
+6 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ class NoopDeviceEntryFaceAuthInteractor @Inject constructor() : DeviceEntryFaceA
    override fun isFaceAuthEnabledAndEnrolled(): Boolean = false

    override fun isFaceAuthStrong(): Boolean = false

    override fun start() = Unit

    override fun registerListener(listener: FaceAuthenticationListener) {}
@@ -59,13 +60,17 @@ class NoopDeviceEntryFaceAuthInteractor @Inject constructor() : DeviceEntryFaceA

    override fun onDeviceLifted() {}

    override fun onQsExpansionStared() {}
    override fun onQsExpansionStarted() {}

    override fun onNotificationPanelClicked() {}

    override fun onSwipeUpOnBouncer() {}

    override fun onPrimaryBouncerUserInput() {}

    override fun onAccessibilityAction() {}

    override fun onWalletLaunched() = Unit

    override fun onDeviceUnfolded() {}
}
+12 −1
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
@@ -214,6 +215,16 @@ constructor(
                }
            }
            .launchIn(applicationScope)

        if (SceneContainerFlag.isEnabled) {
            sceneInteractor
                .get()
                .transitionState
                .filter { it.isTransitioning(from = Scenes.QuickSettings, to = Scenes.Shade) }
                .distinctUntilChanged()
                .onEach { onQsExpansionStarted() }
                .launchIn(applicationScope)
        }
    }

    private val isBouncerVisible: Flow<Boolean> by lazy {
@@ -239,7 +250,7 @@ constructor(
        runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED, true)
    }

    override fun onQsExpansionStared() {
    override fun onQsExpansionStarted() {
        runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true)
    }

+1 −1
Original line number Diff line number Diff line
@@ -1005,7 +1005,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
        // When expanding QS, let's authenticate the user if possible,
        // this will speed up notification actions.
        if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) {
            mDeviceEntryFaceAuthInteractor.onQsExpansionStared();
            mDeviceEntryFaceAuthInteractor.onQsExpansionStarted();
        }
    }

+75 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ 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.flow.flowOf
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -365,13 +366,86 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
        testScope.runTest {
            underTest.start()

            underTest.onQsExpansionStared()
            underTest.onQsExpansionStarted()

            runCurrent()
            assertThat(faceAuthRepository.runningAuthRequest.value)
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true))
        }

    @Test
    @EnableSceneContainer
    fun faceAuthIsRequestedWhenQuickSettingsIsExpandedToTheShade() =
        testScope.runTest {
            underTest.start()
            faceAuthRepository.canRunFaceAuth.value = true
            kosmos.sceneInteractor.snapToScene(toScene = Scenes.QuickSettings, "for-test")
            runCurrent()

            kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "for-test")
            kosmos.sceneInteractor.setTransitionState(
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = Scenes.QuickSettings,
                        toScene = Scenes.Shade,
                        currentScene = flowOf(Scenes.QuickSettings),
                        progress = MutableStateFlow(0.2f),
                        isInitiatedByUserInput = true,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            )

            runCurrent()
            assertThat(faceAuthRepository.runningAuthRequest.value)
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true))
        }

    @Test
    @EnableSceneContainer
    fun faceAuthIsRequestedOnlyOnceWhenQuickSettingsIsExpandedToTheShade() =
        testScope.runTest {
            underTest.start()
            faceAuthRepository.canRunFaceAuth.value = true
            kosmos.sceneInteractor.snapToScene(toScene = Scenes.QuickSettings, "for-test")
            runCurrent()

            kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "for-test")
            kosmos.sceneInteractor.setTransitionState(
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = Scenes.QuickSettings,
                        toScene = Scenes.Shade,
                        currentScene = flowOf(Scenes.QuickSettings),
                        progress = MutableStateFlow(0.2f),
                        isInitiatedByUserInput = true,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            )

            runCurrent()
            assertThat(faceAuthRepository.runningAuthRequest.value)
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED, true))
            faceAuthRepository.runningAuthRequest.value = null

            // expansion progress shouldn't trigger face auth again
            kosmos.sceneInteractor.setTransitionState(
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = Scenes.QuickSettings,
                        toScene = Scenes.Shade,
                        currentScene = flowOf(Scenes.QuickSettings),
                        progress = MutableStateFlow(0.5f),
                        isInitiatedByUserInput = true,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            )

            assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
        }

    @Test
    fun faceAuthIsRequestedWhenNotificationPanelClicked() =
        testScope.runTest {
Loading