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

Commit 2e9f8c27 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov Committed by Android (Google) Code Review
Browse files

Merge "Update isSecureCameraActive flow to be false after unlock." into main

parents 5dc1f3a0 61e3f4fb
Loading
Loading
Loading
Loading
+51 −20
Original line number Diff line number Diff line
@@ -150,6 +150,53 @@ class KeyguardInteractorTest : SysuiTestCase() {
            assertThat(secureCameraActive()).isFalse()
        }

    /** Regression test for b/373700726. */
    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testSecureCameraStillFalseAfterDeviceUnlocked() =
        testScope.runTest {
            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
            runCurrent()

            // Launch camera
            underTest.onCameraLaunchDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
            assertThat(secureCameraActive()).isTrue()

            // Go back to keyguard
            repository.setKeyguardShowing(true)
            repository.setKeyguardOccluded(false)
            assertThat(secureCameraActive()).isFalse()

            // WHEN device is unlocked (and therefore keyguard is no longer showing)
            repository.setKeyguardShowing(false)

            // THEN we still show secure camera as *not* active
            assertThat(secureCameraActive()).isFalse()
        }

    /** Regression test for b/373700726. */
    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testSecureCameraStillFalseAfterBouncerDismissed() =
        testScope.runTest {
            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
            runCurrent()

            // Launch camera
            underTest.onCameraLaunchDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
            assertThat(secureCameraActive()).isTrue()

            // Show bouncer
            bouncerRepository.setPrimaryShow(true)
            assertThat(secureCameraActive()).isFalse()

            // WHEN device is unlocked (and therefore the bouncer is no longer showing)
            bouncerRepository.setPrimaryShow(false)

            // THEN we still show secure camera as *not* active
            assertThat(secureCameraActive()).isFalse()
        }

    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest {
@@ -182,11 +229,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
            val dismissAlpha by collectLastValue(underTest.dismissAlpha)
            assertThat(dismissAlpha).isEqualTo(1f)

            keyguardTransitionRepository.sendTransitionSteps(
                from = AOD,
                to = LOCKSCREEN,
                testScope,
            )
            keyguardTransitionRepository.sendTransitionSteps(from = AOD, to = LOCKSCREEN, testScope)

            repository.setStatusBarState(StatusBarState.KEYGUARD)
            // User begins to swipe up
@@ -208,11 +251,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
            assertThat(dismissAlpha[0]).isEqualTo(1f)
            assertThat(dismissAlpha.size).isEqualTo(1)

            keyguardTransitionRepository.sendTransitionSteps(
                from = AOD,
                to = LOCKSCREEN,
                testScope,
            )
            keyguardTransitionRepository.sendTransitionSteps(from = AOD, to = LOCKSCREEN, testScope)

            // User begins to swipe up
            repository.setStatusBarState(StatusBarState.KEYGUARD)
@@ -328,11 +367,7 @@ class KeyguardInteractorTest : SysuiTestCase() {

            shadeRepository.setLegacyShadeExpansion(0f)

            keyguardTransitionRepository.sendTransitionSteps(
                from = AOD,
                to = LOCKSCREEN,
                testScope,
            )
            keyguardTransitionRepository.sendTransitionSteps(from = AOD, to = LOCKSCREEN, testScope)

            assertThat(keyguardTranslationY).isEqualTo(0f)
        }
@@ -350,11 +385,7 @@ class KeyguardInteractorTest : SysuiTestCase() {

            shadeRepository.setLegacyShadeExpansion(1f)

            keyguardTransitionRepository.sendTransitionSteps(
                from = AOD,
                to = LOCKSCREEN,
                testScope,
            )
            keyguardTransitionRepository.sendTransitionSteps(from = AOD, to = LOCKSCREEN, testScope)

            assertThat(keyguardTranslationY).isEqualTo(0f)
        }
+29 −10
Original line number Diff line number Diff line
@@ -297,20 +297,39 @@ constructor(
    val isKeyguardVisible: Flow<Boolean> =
        combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded }

    /**
     * Event types that affect whether secure camera is active. Only used by [isSecureCameraActive].
     */
    private enum class SecureCameraRelatedEventType {
        KeyguardBecameVisible,
        PrimaryBouncerBecameVisible,
        SecureCameraLaunched,
    }

    /** Whether camera is launched over keyguard. */
    val isSecureCameraActive: Flow<Boolean> by lazy {
        combine(isKeyguardVisible, primaryBouncerShowing, onCameraLaunchDetected) {
                isKeyguardVisible,
                isPrimaryBouncerShowing,
                cameraLaunchEvent ->
                when {
                    isKeyguardVisible -> false
                    isPrimaryBouncerShowing -> false
                    else -> cameraLaunchEvent.type == CameraLaunchType.POWER_DOUBLE_TAP
    val isSecureCameraActive: Flow<Boolean> =
        merge(
                onCameraLaunchDetected
                    .filter { it.type == CameraLaunchType.POWER_DOUBLE_TAP }
                    .map { SecureCameraRelatedEventType.SecureCameraLaunched },
                isKeyguardVisible
                    .filter { it }
                    .map { SecureCameraRelatedEventType.KeyguardBecameVisible },
                primaryBouncerShowing
                    .filter { it }
                    .map { SecureCameraRelatedEventType.PrimaryBouncerBecameVisible },
            )
            .map {
                when (it) {
                    SecureCameraRelatedEventType.SecureCameraLaunched -> true
                    // When secure camera is closed, either the keyguard or the primary bouncer will
                    // have to show, so those events tell us that secure camera is no longer active.
                    SecureCameraRelatedEventType.KeyguardBecameVisible -> false
                    SecureCameraRelatedEventType.PrimaryBouncerBecameVisible -> false
                }
            }
            .onStart { emit(false) }
    }
            .distinctUntilChanged()

    /** The approximate location on the screen of the fingerprint sensor, if one is available. */
    val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation