diff options
26 files changed, 188 insertions, 350 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt index 6eb9862fb4f1..9273dcef0de0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt @@ -39,12 +39,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat @@ -53,6 +56,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor 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.shared.model.Scenes import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.testKosmos import junit.framework.Assert.assertEquals @@ -166,6 +170,10 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeUp_ifPowerButtonGestureDetected_fromGone() = testScope.runTest { + val isGone by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.AOD, @@ -175,7 +183,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { runCurrent() // Make sure we're GONE. - assertEquals(KeyguardState.GONE, kosmos.keyguardTransitionInteractor.getFinishedState()) + assertEquals(true, isGone) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) @@ -204,6 +212,10 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetectedAfterFinishedInAod_fromGone() = testScope.runTest { + val isGone by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.AOD, @@ -213,7 +225,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { runCurrent() // Make sure we're GONE. - assertEquals(KeyguardState.GONE, kosmos.keyguardTransitionInteractor.getFinishedState()) + assertEquals(true, isGone) // Get all the way to AOD powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) @@ -239,6 +251,10 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetected_fromLockscreen() = testScope.runTest { + val isLockscreen by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Lockscreen, LOCKSCREEN) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.AOD, @@ -248,10 +264,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { runCurrent() // Make sure we're in LOCKSCREEN. - assertEquals( - KeyguardState.LOCKSCREEN, - kosmos.keyguardTransitionInteractor.getFinishedState() - ) + assertEquals(true, isLockscreen) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) @@ -327,6 +340,10 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeUp_ifPowerButtonGestureDetectedInAod_fromGone() = testScope.runTest { + val isGone by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.AOD, @@ -336,7 +353,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { runCurrent() // Make sure we're GONE. - assertEquals(KeyguardState.GONE, kosmos.keyguardTransitionInteractor.getFinishedState()) + assertEquals(true, isGone) // Start going to AOD on first button push powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt index ee4a0d2d4e75..c18deb134075 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt @@ -48,12 +48,15 @@ import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.domain.interactor.setCommunalAvailable import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.CommunalTransitionKeys +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat import com.android.systemui.kosmos.applicationCoroutineScope @@ -62,6 +65,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor 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.shared.model.Scenes import com.android.systemui.testKosmos import junit.framework.Assert.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -316,6 +320,10 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGone_onWakeUp_ifPowerButtonGestureDetected_fromGone() = testScope.runTest { + val isGone by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.DOZING, @@ -325,7 +333,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT runCurrent() // Make sure we're GONE. - assertEquals(KeyguardState.GONE, kosmos.keyguardTransitionInteractor.getFinishedState()) + assertEquals(true, isGone) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) @@ -355,6 +363,10 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Suppress("ktlint:standard:max-line-length") fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetectedAfterFinishedInAod_fromGone() = testScope.runTest { + val isGone by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Gone, GONE) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.DOZING, @@ -364,7 +376,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT runCurrent() // Make sure we're GONE. - assertEquals(KeyguardState.GONE, kosmos.keyguardTransitionInteractor.getFinishedState()) + assertEquals(true, isGone) // Get all the way to AOD powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) @@ -390,6 +402,10 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetected_fromLockscreen() = testScope.runTest { + val isLockscreen by + collectLastValue( + kosmos.keyguardTransitionInteractor.isFinishedIn(Scenes.Lockscreen, LOCKSCREEN) + ) powerInteractor.setAwakeForTest() transitionRepository.sendTransitionSteps( from = KeyguardState.DOZING, @@ -399,10 +415,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT runCurrent() // Make sure we're in LOCKSCREEN. - assertEquals( - KeyguardState.LOCKSCREEN, - kosmos.keyguardTransitionInteractor.getFinishedState() - ) + assertEquals(true, isLockscreen) // Get part way to AOD. powerInteractor.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt index 6e76cbce95f1..6708ffa2a091 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt @@ -90,52 +90,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { } @Test - fun finishedKeyguardStateTests() = - testScope.runTest { - val finishedSteps by collectValues(underTest.finishedKeyguardState) - runCurrent() - val steps = mutableListOf<TransitionStep>() - - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0f, STARTED)) - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0.5f, RUNNING)) - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 1f, FINISHED)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0f, STARTED)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0.9f, RUNNING)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 1f, FINISHED)) - steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) - - steps.forEach { - repository.sendTransitionStep(it) - runCurrent() - } - - assertThat(finishedSteps).isEqualTo(listOf(LOCKSCREEN, PRIMARY_BOUNCER, AOD)) - } - - @Test - fun startedKeyguardStateTests() = - testScope.runTest { - val startedStates by collectValues(underTest.startedKeyguardState) - runCurrent() - val steps = mutableListOf<TransitionStep>() - - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0f, STARTED)) - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0.5f, RUNNING)) - steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 1f, FINISHED)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0f, STARTED)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0.9f, RUNNING)) - steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 1f, FINISHED)) - steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) - - steps.forEach { - repository.sendTransitionStep(it) - runCurrent() - } - - assertThat(startedStates).isEqualTo(listOf(LOCKSCREEN, PRIMARY_BOUNCER, AOD, GONE)) - } - - @Test fun startedKeyguardTransitionStepTests() = testScope.runTest { val startedSteps by collectValues(underTest.startedKeyguardTransitionStep) @@ -1206,95 +1160,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { } @Test - fun finishedKeyguardState_emitsAgainIfCancelledAndReversed() = - testScope.runTest { - val finishedStates by collectValues(underTest.finishedKeyguardState) - - // We default FINISHED in LOCKSCREEN. - assertEquals(listOf(LOCKSCREEN), finishedStates) - - sendSteps( - TransitionStep(LOCKSCREEN, AOD, 0f, STARTED), - TransitionStep(LOCKSCREEN, AOD, 0.5f, RUNNING), - TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED), - ) - - // We're FINISHED in AOD. - assertEquals( - listOf( - LOCKSCREEN, - AOD, - ), - finishedStates - ) - - // Transition back to LOCKSCREEN. - sendSteps( - TransitionStep(AOD, LOCKSCREEN, 0f, STARTED), - TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING), - TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED), - ) - - // We're FINISHED in LOCKSCREEN. - assertEquals( - listOf( - LOCKSCREEN, - AOD, - LOCKSCREEN, - ), - finishedStates - ) - - sendSteps( - TransitionStep(LOCKSCREEN, GONE, 0f, STARTED), - TransitionStep(LOCKSCREEN, GONE, 0.5f, RUNNING), - ) - - // We've STARTED a transition to GONE but not yet finished it so we're still FINISHED in - // LOCKSCREEN. - assertEquals( - listOf( - LOCKSCREEN, - AOD, - LOCKSCREEN, - ), - finishedStates - ) - - sendSteps( - TransitionStep(LOCKSCREEN, GONE, 0.6f, CANCELED), - ) - - // We've CANCELED a transition to GONE, we're still FINISHED in LOCKSCREEN. - assertEquals( - listOf( - LOCKSCREEN, - AOD, - LOCKSCREEN, - ), - finishedStates - ) - - sendSteps( - TransitionStep(GONE, LOCKSCREEN, 0.6f, STARTED), - TransitionStep(GONE, LOCKSCREEN, 0.9f, RUNNING), - TransitionStep(GONE, LOCKSCREEN, 1f, FINISHED), - ) - - // Expect another emission of LOCKSCREEN, as we have FINISHED a second transition to - // LOCKSCREEN after the cancellation. - assertEquals( - listOf( - LOCKSCREEN, - AOD, - LOCKSCREEN, - LOCKSCREEN, - ), - finishedStates - ) - } - - @Test fun testCurrentState() = testScope.runTest { val currentStates by collectValues(underTest.currentKeyguardState) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt index 3e0a1f31302d..073ed61a949b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt @@ -19,18 +19,20 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.fakeLightRevealScrimRepository +import com.android.systemui.keyguard.data.repository.DEFAULT_REVEAL_EFFECT import com.android.systemui.keyguard.data.repository.FakeLightRevealScrimRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.LightRevealEffect import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.testKosmos import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Test @@ -64,35 +66,45 @@ class LightRevealScrimInteractorTest : SysuiTestCase() { @Test fun lightRevealEffect_doesNotChangeDuringKeyguardTransition() = - runTest(UnconfinedTestDispatcher()) { - val values = mutableListOf<LightRevealEffect>() - val job = underTest.lightRevealEffect.onEach(values::add).launchIn(this) + kosmos.testScope.runTest { + val values by collectValues(underTest.lightRevealEffect) + runCurrent() + assertEquals(listOf(DEFAULT_REVEAL_EFFECT), values) fakeLightRevealScrimRepository.setRevealEffect(reveal1) - + runCurrent() // The reveal effect shouldn't emit anything until a keyguard transition starts. - assertEquals(values.size, 0) + assertEquals(listOf(DEFAULT_REVEAL_EFFECT), values) // Once it starts, it should emit reveal1. fakeKeyguardTransitionRepository.sendTransitionStep( - TransitionStep(transitionState = TransitionState.STARTED) + TransitionStep(to = KeyguardState.AOD, transitionState = TransitionState.STARTED) ) - assertEquals(values, listOf(reveal1)) + runCurrent() + assertEquals(listOf(DEFAULT_REVEAL_EFFECT, reveal1), values) // Until the next transition starts, reveal2 should not be emitted. fakeLightRevealScrimRepository.setRevealEffect(reveal2) + runCurrent() fakeKeyguardTransitionRepository.sendTransitionStep( - TransitionStep(transitionState = TransitionState.RUNNING) + TransitionStep( + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.RUNNING + ) ) + runCurrent() fakeKeyguardTransitionRepository.sendTransitionStep( - TransitionStep(transitionState = TransitionState.FINISHED) + TransitionStep(to = KeyguardState.AOD, transitionState = TransitionState.FINISHED) ) - assertEquals(values, listOf(reveal1)) + runCurrent() + assertEquals(listOf(DEFAULT_REVEAL_EFFECT, reveal1), values) fakeKeyguardTransitionRepository.sendTransitionStep( - TransitionStep(transitionState = TransitionState.STARTED) + TransitionStep( + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED + ) ) - assertEquals(values, listOf(reveal1, reveal2)) - - job.cancel() + runCurrent() + assertEquals(listOf(DEFAULT_REVEAL_EFFECT, reveal1, reveal2), values) } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt index 5077e8d35267..e04d3095d68d 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt @@ -225,7 +225,7 @@ constructor( collectProgress(transition) } else if (transition.toScene == CommunalScenes.Communal) { if (currentToState == KeyguardState.GLANCEABLE_HUB) { - transitionKtfTo(transitionInteractor.getStartedFromState()) + transitionKtfTo(transitionInteractor.startedKeyguardTransitionStep.value.from) } startTransitionToGlanceableHub() collectProgress(transition) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt index 6e04133dcb4a..4cf9ec8890d4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt @@ -89,7 +89,7 @@ constructor( .filterRelevantKeyguardStateAnd { wakefulness -> wakefulness.isAwake() } .debounce(50L) .sample( - startedKeyguardTransitionStep, + transitionInteractor.startedKeyguardTransitionStep, wakeToGoneInteractor.canWakeDirectlyToGone, ) .collect { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt index 4666430398ec..2434b29c0cdd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt @@ -117,7 +117,7 @@ constructor( if (SceneContainerFlag.isEnabled) return scope.launch { keyguardInteractor.primaryBouncerShowing - .sample(startedKeyguardTransitionStep, ::Pair) + .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair) .collect { pair -> val (isBouncerShowing, lastStartedTransitionStep) = pair if ( @@ -132,7 +132,7 @@ constructor( fun startToLockscreenOrGlanceableHubTransition(openHub: Boolean) { scope.launch { if ( - transitionInteractor.startedKeyguardState.replayCache.last() == + transitionInteractor.startedKeyguardTransitionStep.value.to == KeyguardState.DREAMING ) { if (powerInteractor.detailedWakefulness.value.isAwake()) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt index fc70ea5cd526..228e01edc99b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt @@ -134,16 +134,12 @@ constructor( .filterRelevantKeyguardState() .sampleCombine( internalTransitionInteractor.currentTransitionInfoInternal, - finishedKeyguardState, + transitionInteractor.isFinishedIn(KeyguardState.LOCKSCREEN), keyguardInteractor.isActiveDreamLockscreenHosted, ) .collect { - ( - isAbleToDream, - transitionInfo, - finishedKeyguardState, - isActiveDreamLockscreenHosted) -> - val isOnLockscreen = finishedKeyguardState == KeyguardState.LOCKSCREEN + (isAbleToDream, transitionInfo, isOnLockscreen, isActiveDreamLockscreenHosted) + -> val isTransitionInterruptible = transitionInfo.to == KeyguardState.LOCKSCREEN && !invalidFromStates.contains(transitionInfo.from) @@ -189,7 +185,7 @@ constructor( scope.launch("$TAG#listenForLockscreenToPrimaryBouncerDragging") { shadeRepository.legacyShadeExpansion .sampleCombine( - startedKeyguardTransitionStep, + transitionInteractor.startedKeyguardTransitionStep, internalTransitionInteractor.currentTransitionInfoInternal, keyguardInteractor.statusBarState, keyguardInteractor.isKeyguardDismissible, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt index f9ab1bbcc741..bde0f56aa691 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt @@ -62,16 +62,16 @@ constructor( communalInteractor .transitionProgressToScene(toScene) .sample( - transitionInteractor.startedKeyguardState, + transitionInteractor.startedKeyguardTransitionStep, ::Pair, ) - .collect { (transitionProgress, lastStartedState) -> + .collect { (transitionProgress, lastStartedStep) -> val id = transitionId if (id == null) { // No transition started. if ( transitionProgress is CommunalTransitionProgressModel.Transition && - lastStartedState == fromState + lastStartedStep.to == fromState ) { transitionId = transitionRepository.startTransition( @@ -84,7 +84,7 @@ constructor( ) } } else { - if (lastStartedState != toState) { + if (lastStartedStep.to != toState) { return@collect } // An existing `id` means a transition is started, and calls to 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 4a8ada7f1184..505c749d9e44 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 @@ -48,7 +48,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -74,9 +73,7 @@ constructor( val isLongPressHandlingEnabled: StateFlow<Boolean> = if (isFeatureEnabled()) { combine( - transitionInteractor.finishedKeyguardState.map { - it == KeyguardState.LOCKSCREEN - }, + transitionInteractor.isFinishedIn(KeyguardState.LOCKSCREEN), repository.isQuickSettingsVisible, ) { isFullyTransitionedToLockScreen, isQuickSettingsVisible -> isFullyTransitionedToLockScreen && !isQuickSettingsVisible diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index c10bacf32a5a..92e2a911317f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -49,7 +49,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -58,7 +57,6 @@ import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.transform import kotlinx.coroutines.launch /** Encapsulates business-logic related to the keyguard transitions. */ @@ -286,67 +284,10 @@ constructor( } /** The last [TransitionStep] with a [TransitionState] of STARTED */ - val startedKeyguardTransitionStep: Flow<TransitionStep> = - repository.transitions.filter { step -> step.transitionState == TransitionState.STARTED } - - /** The destination state of the last [TransitionState.STARTED] transition. */ - @SuppressLint("SharedFlowCreation") - val startedKeyguardState: SharedFlow<KeyguardState> = - startedKeyguardTransitionStep - .map { step -> step.to } - .buffer(2, BufferOverflow.DROP_OLDEST) - .shareIn(scope, SharingStarted.Eagerly, replay = 1) - - /** The from state of the last [TransitionState.STARTED] transition. */ - // TODO: is it performant to have several SharedFlows side by side instead of one? - @SuppressLint("SharedFlowCreation") - val startedKeyguardFromState: SharedFlow<KeyguardState> = - startedKeyguardTransitionStep - .map { step -> step.from } - .buffer(2, BufferOverflow.DROP_OLDEST) - .shareIn(scope, SharingStarted.Eagerly, replay = 1) - - /** - * The last [KeyguardState] to which we [TransitionState.FINISHED] a transition. - * - * WARNING: This will NOT emit a value if a transition is CANCELED, and will also not emit a - * value when a subsequent transition is STARTED. It will *only* emit once we have finally - * FINISHED in a state. This can have unintuitive implications. - * - * For example, if we're transitioning from GONE -> DOZING, and that transition is CANCELED in - * favor of a DOZING -> LOCKSCREEN transition, the FINISHED state is still GONE, and will remain - * GONE throughout the DOZING -> LOCKSCREEN transition until the DOZING -> LOCKSCREEN transition - * finishes (at which point we'll be FINISHED in LOCKSCREEN). - * - * Since there's no real limit to how many consecutive transitions can be canceled, it's even - * possible for the FINISHED state to be the same as the STARTED state while still - * transitioning. - * - * For example: - * 1. We're finished in GONE. - * 2. The user presses the power button, starting a GONE -> DOZING transition. We're still - * FINISHED in GONE. - * 3. The user changes their mind, pressing the power button to wake up; this starts a DOZING -> - * LOCKSCREEN transition. We're still FINISHED in GONE. - * 4. The user quickly swipes away the lockscreen prior to DOZING -> LOCKSCREEN finishing; this - * starts a LOCKSCREEN -> GONE transition. We're still FINISHED in GONE, but we've also - * STARTED a transition *to* GONE. - * 5. We'll emit KeyguardState.GONE again once the transition finishes. - * - * If you just need to know when we eventually settle into a state, this flow is likely - * sufficient. However, if you're having issues with state *during* transitions started after - * one or more canceled transitions, you probably need to use [currentKeyguardState]. - */ - @SuppressLint("SharedFlowCreation") - val finishedKeyguardState: SharedFlow<KeyguardState> = + val startedKeyguardTransitionStep: StateFlow<TransitionStep> = repository.transitions - .transform { step -> - if (step.transitionState == TransitionState.FINISHED) { - emit(step.to) - } - } - .buffer(2, BufferOverflow.DROP_OLDEST) - .shareIn(scope, SharingStarted.Eagerly, replay = 1) + .filter { step -> step.transitionState == TransitionState.STARTED } + .stateIn(scope, SharingStarted.Eagerly, TransitionStep()) /** * The [KeyguardState] we're currently in. @@ -412,7 +353,6 @@ constructor( it.from } } - .distinctUntilChanged() .stateIn(scope, SharingStarted.Eagerly, OFF) val isInTransition = @@ -509,12 +449,13 @@ constructor( fun isFinishedIn(scene: SceneKey, stateWithoutSceneContainer: KeyguardState): Flow<Boolean> { return if (SceneContainerFlag.isEnabled) { - sceneInteractor.transitionState - .map { it.isIdle(scene) || it.isTransitioning(from = scene) } - .distinctUntilChanged() - } else { - isFinishedIn(stateWithoutSceneContainer) - } + sceneInteractor.transitionState.map { + it.isIdle(scene) || it.isTransitioning(from = scene) + } + } else { + isFinishedIn(stateWithoutSceneContainer) + } + .distinctUntilChanged() } /** Whether we've FINISHED a transition to a state */ @@ -527,13 +468,11 @@ constructor( return currentKeyguardState.replayCache.last() } - fun getStartedFromState(): KeyguardState { - return startedKeyguardFromState.replayCache.last() - } - - fun getFinishedState(): KeyguardState { - return finishedKeyguardState.replayCache.last() - } + private val finishedKeyguardState: StateFlow<KeyguardState> = + repository.transitions + .filter { it.transitionState == TransitionState.FINISHED } + .map { it.to } + .stateIn(scope, SharingStarted.Eagerly, OFF) companion object { private val TAG = KeyguardTransitionInteractor::class.simpleName diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt index 47818cbfd2f2..e00e33df62eb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt @@ -45,6 +45,7 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -76,7 +77,7 @@ constructor( private val disableFlagsForUserId = combine( selectedUserInteractor.selectedUser, - keyguardTransitionInteractor.startedKeyguardState, + keyguardTransitionInteractor.startedKeyguardTransitionStep.map { it.to }, deviceConfigInteractor.property( namespace = DeviceConfig.NAMESPACE_SYSTEMUI, name = SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractor.kt index 906d58664de9..e404f273a768 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractor.kt @@ -22,12 +22,12 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.util.kotlin.Utils.Companion.sample +import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import javax.inject.Inject /** * Handles logic around the swipe to dismiss gesture, where the user swipes up on the dismissable @@ -53,15 +53,15 @@ constructor( val dismissFling = shadeRepository.currentFling .sample( - transitionInteractor.startedKeyguardState, + transitionInteractor.startedKeyguardTransitionStep, keyguardInteractor.isKeyguardDismissible, keyguardInteractor.statusBarState, ) - .filter { (flingInfo, startedState, keyguardDismissable, statusBarState) -> + .filter { (flingInfo, startedStep, keyguardDismissable, statusBarState) -> flingInfo != null && - !flingInfo.expand && - statusBarState != StatusBarState.SHADE_LOCKED && - startedState == KeyguardState.LOCKSCREEN && + !flingInfo.expand && + statusBarState != StatusBarState.SHADE_LOCKED && + startedStep.to == KeyguardState.LOCKSCREEN && keyguardDismissable } .map { (flingInfo, _) -> flingInfo } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt index 950eafa23043..ba12e9356ed7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt @@ -32,7 +32,6 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -62,17 +61,6 @@ sealed class TransitionInteractor( abstract fun start() - /* Use background dispatcher for all [KeyguardTransitionInteractor] flows. Necessary because - * the [sample] utility internally runs a collect on the Unconfined dispatcher, resulting - * in continuations on the main thread. We don't want that for classes that inherit from this. - */ - val startedKeyguardTransitionStep = - transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher) - // The following are MutableSharedFlows, and do not require flowOn - val startedKeyguardState = transitionInteractor.startedKeyguardState - val finishedKeyguardState = transitionInteractor.finishedKeyguardState - val currentKeyguardState = transitionInteractor.currentKeyguardState - suspend fun startTransitionTo( toState: KeyguardState, animator: ValueAnimator? = getDefaultAnimatorForTransitionsToState(toState), @@ -92,17 +80,6 @@ sealed class TransitionInteractor( " $fromState. This should never happen - check currentTransitionInfoInternal" + " or use filterRelevantKeyguardState before starting transitions." ) - - if (fromState == transitionInteractor.finishedKeyguardState.replayCache.last()) { - Log.e( - name, - "This transition would not have been ignored prior to ag/26681239, since we " + - "are FINISHED in $fromState (but have since started another transition). " + - "If ignoring this transition has caused a regression, fix it by ensuring " + - "that transitions are exclusively started from the most recently started " + - "state." - ) - } return null } @@ -207,7 +184,7 @@ sealed class TransitionInteractor( powerInteractor.isAsleep .filter { isAsleep -> isAsleep } .filterRelevantKeyguardState() - .sample(startedKeyguardTransitionStep) + .sample(transitionInteractor.startedKeyguardTransitionStep) .map(modeOnCanceledFromStartedStep) .collect { modeOnCanceled -> startTransitionTo( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt index 25b2b7cad7ec..ac874005b612 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt @@ -63,10 +63,13 @@ constructor( ) { private val defaultSurfaceBehindVisibility = combine( - transitionInteractor.finishedKeyguardState, + transitionInteractor.isFinishedIn( + scene = Scenes.Gone, + stateWithoutSceneContainer = KeyguardState.GONE + ), wakeToGoneInteractor.canWakeDirectlyToGone, - ) { finishedState, canWakeDirectlyToGone -> - isSurfaceVisible(finishedState) || canWakeDirectlyToGone + ) { isOnGone, canWakeDirectlyToGone -> + isOnGone || canWakeDirectlyToGone } /** @@ -196,18 +199,20 @@ constructor( edge = Edge.create(to = Scenes.Gone), edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE) ), - transitionInteractor.finishedKeyguardState, + transitionInteractor.isFinishedIn( + scene = Scenes.Gone, + stateWithoutSceneContainer = KeyguardState.GONE + ), surfaceBehindInteractor.isAnimatingSurface, notificationLaunchAnimationInteractor.isLaunchAnimationRunning, - ) { isInTransitionToGone, finishedState, isAnimatingSurface, notifLaunchRunning -> + ) { isInTransitionToGone, isOnGone, isAnimatingSurface, notifLaunchRunning -> // Using the animation if we're animating it directly, or if the // ActivityLaunchAnimator is in the process of animating it. val animationsRunning = isAnimatingSurface || notifLaunchRunning // We may still be animating the surface after the keyguard is fully GONE, since // some animations (like the translation spring) are not tied directly to the // transition step amount. - isInTransitionToGone || - (finishedState == KeyguardState.GONE && animationsRunning) + isInTransitionToGone || (isOnGone && animationsRunning) } .distinctUntilChanged() } @@ -248,7 +253,7 @@ constructor( // transition. Same for waking directly to gone, due to the lockscreen being // disabled or because the device was woken back up before the lock timeout // duration elapsed. - KeyguardState.lockscreenVisibleInState(KeyguardState.GONE) + false } else if (canWakeDirectlyToGone) { // Never show the lockscreen if we can wake directly to GONE. This means // that the lock timeout has not yet elapsed, or the keyguard is disabled. @@ -274,8 +279,7 @@ constructor( // *not* play the going away animation or related animations. false } else { - // Otherwise, use the visibility of the current state. - KeyguardState.lockscreenVisibleInState(currentState) + currentState != KeyguardState.GONE } } .distinctUntilChanged() @@ -302,10 +306,4 @@ constructor( !BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode) } .distinctUntilChanged() - - companion object { - fun isSurfaceVisible(state: KeyguardState): Boolean { - return !KeyguardState.lockscreenVisibleInState(state) - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt index b8500952d90a..ffd7812166db 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt @@ -116,7 +116,7 @@ constructor( } else { val targetState = if (idle.currentScene == Scenes.Lockscreen) { - transitionInteractor.getStartedFromState() + transitionInteractor.startedKeyguardTransitionStep.value.from } else { UNDEFINED } @@ -155,7 +155,7 @@ constructor( val currentToState = internalTransitionInteractor.currentTransitionInfoInternal.value.to if (currentToState == UNDEFINED) { - transitionKtfTo(transitionInteractor.getStartedFromState()) + transitionKtfTo(transitionInteractor.startedKeyguardTransitionStep.value.from) } } startTransitionFromLockscreen() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt index 24db3c2c70a2..080ddfd18370 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt @@ -156,12 +156,6 @@ enum class KeyguardState { companion object { - /** Whether the lockscreen is visible when we're FINISHED in the given state. */ - fun lockscreenVisibleInState(state: KeyguardState): Boolean { - // TODO(b/349784682): Transform deprecated states for Flexiglass - return state != GONE - } - /** * Whether the device is awake ([PowerInteractor.isAwake]) when we're FINISHED in the given * keyguard state. diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt index 06b76b3c0f37..87c32a54438e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt @@ -53,10 +53,10 @@ constructor( ) { private val isShowingAodOrDozing: Flow<Boolean> = combine( - transitionInteractor.startedKeyguardState, + transitionInteractor.startedKeyguardTransitionStep, transitionInteractor.transitionValue(KeyguardState.DOZING), - ) { startedKeyguardState, dozingTransitionValue -> - startedKeyguardState == KeyguardState.AOD || dozingTransitionValue == 1f + ) { startedKeyguardStep, dozingTransitionValue -> + startedKeyguardStep.to == KeyguardState.AOD || dozingTransitionValue == 1f } private fun getColor(usingBackgroundProtection: Boolean): Int { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt index 5ce1b5e3dcc5..d3bb4f5d7508 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt @@ -83,8 +83,8 @@ constructor( private val intEvaluator = IntEvaluator() private val floatEvaluator = FloatEvaluator() private val showingAlternateBouncer: Flow<Boolean> = - transitionInteractor.startedKeyguardState.map { keyguardState -> - keyguardState == KeyguardState.ALTERNATE_BOUNCER + transitionInteractor.startedKeyguardTransitionStep.map { keyguardStep -> + keyguardStep.to == KeyguardState.ALTERNATE_BOUNCER } private val qsProgress: Flow<Float> = shadeInteractor.qsExpansion.onStart { emit(0f) } private val shadeExpansion: Flow<Float> = shadeInteractor.shadeExpansion.onStart { emit(0f) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt index c885c9a5a29b..fe4ebfedee40 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt @@ -85,9 +85,7 @@ constructor( private val previewMode = MutableStateFlow(PreviewMode()) private val showingLockscreen: Flow<Boolean> = - transitionInteractor.finishedKeyguardState.map { keyguardState -> - keyguardState == KeyguardState.LOCKSCREEN - } + transitionInteractor.isFinishedIn(KeyguardState.LOCKSCREEN) /** The only time the expansion is important is while lockscreen is actively displayed */ private val shadeExpansionAlpha = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt index a96869df001a..ebdcaa0c91a6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt @@ -132,8 +132,8 @@ constructor( val burnInModel = _burnInModel.asStateFlow() val burnInLayerVisibility: Flow<Int> = - keyguardTransitionInteractor.startedKeyguardState - .filter { it == AOD || it == LOCKSCREEN } + keyguardTransitionInteractor.startedKeyguardTransitionStep + .filter { it.to == AOD || it.to == LOCKSCREEN } .map { VISIBLE } val goneToAodTransition = @@ -333,16 +333,17 @@ constructor( .transitionValue(LOCKSCREEN) .map { it > 0f } .onStart { emit(false) }, - keyguardTransitionInteractor.finishedKeyguardState.map { - KeyguardState.lockscreenVisibleInState(it) - }, + keyguardTransitionInteractor.isFinishedIn( + scene = Scenes.Gone, + stateWithoutSceneContainer = GONE + ), deviceEntryInteractor.isBypassEnabled, areNotifsFullyHiddenAnimated(), isPulseExpandingAnimated(), ) { flows -> val goneToAodTransitionRunning = flows[0] as Boolean val isOnLockscreen = flows[1] as Boolean - val onKeyguard = flows[2] as Boolean + val isOnGone = flows[2] as Boolean val isBypassEnabled = flows[3] as Boolean val notifsFullyHidden = flows[4] as AnimatedValue<Boolean> val pulseExpanding = flows[5] as AnimatedValue<Boolean> @@ -352,8 +353,7 @@ constructor( // animation is playing, in which case we want them to be visible if we're // animating in the AOD UI and will be switching to KEYGUARD shortly. goneToAodTransitionRunning || - (!onKeyguard && - !screenOffAnimationController.shouldShowAodIconsWhenShade()) -> + (isOnGone && !screenOffAnimationController.shouldShowAodIconsWhenShade()) -> AnimatedValue.NotAnimating(false) else -> zip(notifsFullyHidden, pulseExpanding) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/ShadeDependentFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/ShadeDependentFlows.kt index e45d537155fd..708b4085da7f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/ShadeDependentFlows.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/ShadeDependentFlows.kt @@ -34,7 +34,9 @@ constructor( ) { /** When the last keyguard state transition started, was the shade fully expanded? */ private val lastStartedTransitionHadShadeFullyExpanded: Flow<Boolean> = - transitionInteractor.startedKeyguardState.sample(shadeInteractor.isAnyFullyExpanded) + transitionInteractor.startedKeyguardTransitionStep.sample( + shadeInteractor.isAnyFullyExpanded + ) /** * Decide which flow to use depending on the shade expansion state at the start of the last diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt index f5a7966b7c1e..bf9ef8c5d24e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt @@ -49,7 +49,6 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.Edge -import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState @@ -105,12 +104,14 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -332,6 +333,11 @@ constructor( private val controllerById = mutableMapOf<String, MediaViewController>() private val commonViewModels = mutableListOf<MediaCommonViewModel>() + private val isOnGone = + keyguardTransitionInteractor + .isFinishedIn(Scenes.Gone, GONE) + .stateIn(applicationScope, SharingStarted.Eagerly, true) + init { dumpManager.registerDumpable(TAG, this) mediaFrame = inflateMediaCarousel() @@ -913,9 +919,7 @@ constructor( if (SceneContainerFlag.isEnabled) { !deviceEntryInteractor.isDeviceEntered.value } else { - KeyguardState.lockscreenVisibleInState( - keyguardTransitionInteractor.getFinishedState() - ) + !isOnGone.value } return !allowMediaPlayerOnLockScreen && isOnLockscreen } diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index c7fc44513473..9c8ef0421888 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -89,6 +89,9 @@ import com.android.systemui.util.settings.SecureSettings; import com.google.ux.material.libmonet.dynamiccolor.DynamicColor; import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; +import kotlinx.coroutines.flow.Flow; +import kotlinx.coroutines.flow.StateFlow; + import org.json.JSONException; import org.json.JSONObject; @@ -162,6 +165,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { private final WakefulnessLifecycle mWakefulnessLifecycle; private final JavaAdapter mJavaAdapter; private final KeyguardTransitionInteractor mKeyguardTransitionInteractor; + private final StateFlow<Boolean> mIsKeyguardOnAsleepState; private final UiModeManager mUiModeManager; private ColorScheme mDarkColorScheme; private ColorScheme mLightColorScheme; @@ -202,8 +206,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { } boolean currentUser = userId == mUserTracker.getUserId(); boolean isAsleep = themeOverlayControllerWakefulnessDeprecation() - ? KeyguardState.Companion.deviceIsAsleepInState( - mKeyguardTransitionInteractor.getFinishedState()) + ? ThemeOverlayController.this.mIsKeyguardOnAsleepState.getValue() : mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP; if (currentUser && !mAcceptColorEvents && isAsleep) { @@ -434,6 +437,10 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { mUiModeManager = uiModeManager; mActivityManager = activityManager; dumpManager.registerDumpable(TAG, this); + + Flow<Boolean> isFinishedInAsleepStateFlow = mKeyguardTransitionInteractor + .isFinishedInStateWhere(KeyguardState.Companion::deviceIsAsleepInState); + mIsKeyguardOnAsleepState = mJavaAdapter.stateInApp(isFinishedInAsleepStateFlow, false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt index 055671cf32ca..64e056da97d4 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt @@ -31,7 +31,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch /** A class allowing Java classes to collect on Kotlin flows. */ @@ -58,6 +61,15 @@ constructor( ): Job { return scope.launch { flow.collect { consumer.accept(it) } } } + + @JvmOverloads + fun <T> stateInApp( + flow: Flow<T>, + initialValue: T, + started: SharingStarted = SharingStarted.Eagerly + ): StateFlow<T> { + return flow.stateIn(scope, started, initialValue) + } } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt index 73b9f5783004..07f7557d965a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt @@ -47,8 +47,11 @@ import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepo import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.AOD +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN +import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.shared.quickaffordance.ActivationState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger @@ -56,7 +59,10 @@ import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter import com.android.systemui.res.R +import com.android.systemui.scene.data.repository.Idle +import com.android.systemui.scene.data.repository.setTransition import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -144,7 +150,6 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Mock private lateinit var glanceableHubToLockscreenTransitionViewModel: GlanceableHubToLockscreenTransitionViewModel - @Mock private lateinit var transitionInteractor: KeyguardTransitionInteractor private val kosmos = testKosmos() @@ -163,8 +168,6 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { // the viewModel does a `map { 1 - it }` on this value, which is why it's different private val intendedShadeAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(0f) - private val intendedFinishedKeyguardStateFlow = MutableStateFlow(KeyguardState.LOCKSCREEN) - @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -256,7 +259,6 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { intendedAlphaMutableStateFlow.value = 1f intendedShadeAlphaMutableStateFlow.value = 0f - intendedFinishedKeyguardStateFlow.value = KeyguardState.LOCKSCREEN whenever(aodToLockscreenTransitionViewModel.shortcutsAlpha) .thenReturn(intendedAlphaMutableStateFlow) whenever(dozingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow()) @@ -283,8 +285,6 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { whenever(glanceableHubToLockscreenTransitionViewModel.shortcutsAlpha) .thenReturn(emptyFlow()) whenever(shadeInteractor.anyExpansion).thenReturn(intendedShadeAlphaMutableStateFlow) - whenever(transitionInteractor.finishedKeyguardState) - .thenReturn(intendedFinishedKeyguardStateFlow) underTest = KeyguardQuickAffordancesCombinedViewModel( @@ -334,7 +334,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { lockscreenToPrimaryBouncerTransitionViewModel, lockscreenToGlanceableHubTransitionViewModel = lockscreenToGlanceableHubTransitionViewModel, - transitionInteractor = transitionInteractor, + transitionInteractor = kosmos.keyguardTransitionInteractor, ) } @@ -776,7 +776,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Test fun shadeExpansionAlpha_changes_whenOnLockscreen() = testScope.runTest { - intendedFinishedKeyguardStateFlow.value = KeyguardState.LOCKSCREEN + kosmos.setTransition( + sceneTransition = Idle(Scenes.Lockscreen), + stateTransition = TransitionStep(from = AOD, to = LOCKSCREEN) + ) intendedShadeAlphaMutableStateFlow.value = 0.25f val underTest = collectLastValue(underTest.transitionAlpha) assertEquals(0.75f, underTest()) @@ -788,7 +791,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Test fun shadeExpansionAlpha_alwaysZero_whenNotOnLockscreen() = testScope.runTest { - intendedFinishedKeyguardStateFlow.value = KeyguardState.GONE + kosmos.setTransition( + sceneTransition = Idle(Scenes.Gone), + stateTransition = TransitionStep(from = AOD, to = GONE) + ) intendedShadeAlphaMutableStateFlow.value = 0.5f val underTest = collectLastValue(underTest.transitionAlpha) assertEquals(0f, underTest()) |