diff options
2 files changed, 80 insertions, 30 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt index 3fb3eead6469..b3417b9de36d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt @@ -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) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index d7f96b55c4a3..6ecbc6175e40 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -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 |