Loading packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -856,6 +856,16 @@ flag { } } flag { name: "restart_dream_on_unocclude" namespace: "systemui" description: "re-enters dreaming upon unocclude when dreaming when originally occluding" bug: "338051457" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "communal_bouncer_do_not_modify_plugin_open" namespace: "systemui" Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt +31 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,16 @@ package com.android.systemui.communal import android.platform.test.annotations.EnableFlags import android.service.dream.dreamManager 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.communal.domain.interactor.communalInteractor import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -62,6 +66,7 @@ class CommunalDreamStartableTest : SysuiTestCase() { powerInteractor = kosmos.powerInteractor, keyguardInteractor = kosmos.keyguardInteractor, keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, communalInteractor = kosmos.communalInteractor, dreamManager = dreamManager, bgScope = kosmos.applicationCoroutineScope, ) Loading @@ -83,6 +88,32 @@ class CommunalDreamStartableTest : SysuiTestCase() { verify(dreamManager).startDream() } @Test @EnableFlags(Flags.FLAG_RESTART_DREAM_ON_UNOCCLUDE) fun restartDreamingWhenTransitioningFromDreamingToOccludedToDreaming() = testScope.runTest { keyguardRepository.setDreaming(false) powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true) runCurrent() verify(dreamManager, never()).startDream() kosmos.fakeKeyguardRepository.setKeyguardOccluded(true) kosmos.fakeKeyguardRepository.setDreaming(true) runCurrent() transition(from = KeyguardState.DREAMING, to = KeyguardState.OCCLUDED) kosmos.fakeKeyguardRepository.setKeyguardOccluded(false) kosmos.fakeKeyguardRepository.setDreaming(false) runCurrent() transition(from = KeyguardState.OCCLUDED, to = KeyguardState.DREAMING) runCurrent() verify(dreamManager).startDream() } @Test fun shouldNotStartDreamWhenIneligibleToDream() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt +18 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.SuppressLint import android.app.DreamManager import com.android.systemui.CoreStartable import com.android.systemui.Flags.communalHub import com.android.systemui.Flags.restartDreamOnUnocclude import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor Loading @@ -27,8 +29,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.kotlin.Utils.Companion.sample import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach Loading @@ -43,6 +47,7 @@ constructor( private val powerInteractor: PowerInteractor, private val keyguardInteractor: KeyguardInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val communalInteractor: CommunalInteractor, private val dreamManager: DreamManager, @Background private val bgScope: CoroutineScope, ) : CoreStartable { Loading @@ -52,6 +57,19 @@ constructor( return } // Return to dream from occluded when not already dreaming. if (restartDreamOnUnocclude()) { keyguardTransitionInteractor.startedKeyguardTransitionStep .sample(keyguardInteractor.isDreaming, ::Pair) .filter { it.first.from == KeyguardState.OCCLUDED && it.first.to == KeyguardState.DREAMING && !it.second } .onEach { dreamManager.startDream() } .launchIn(bgScope) } // Restart the dream underneath the hub in order to support the ability to swipe // away the hub to enter the dream. keyguardTransitionInteractor.finishedKeyguardState Loading packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +7 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,13 @@ constructor( initialValue = false, ) /** Whether to start dreaming when returning from occluded */ val dreamFromOccluded: Flow<Boolean> = keyguardTransitionInteractor .transitionStepsToState(KeyguardState.OCCLUDED) .map { it.from == KeyguardState.DREAMING } .stateIn(scope = applicationScope, SharingStarted.Eagerly, false) /** * Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene]. * Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +13 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import android.animation.ValueAnimator import com.android.app.animation.Interpolators import com.android.systemui.Flags.restartDreamOnUnocclude import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background Loading Loading @@ -90,12 +91,15 @@ constructor( .sample( communalInteractor.isIdleOnCommunal, communalInteractor.showCommunalFromOccluded, communalInteractor.dreamFromOccluded ) .collect { (_, isIdleOnCommunal, showCommunalFromOccluded) -> .collect { (_, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> // Occlusion signals come from the framework, and should interrupt any // existing transition val to = if (isIdleOnCommunal || showCommunalFromOccluded) { if (restartDreamOnUnocclude() && dreamFromOccluded) { KeyguardState.DREAMING } else if (isIdleOnCommunal || showCommunalFromOccluded) { KeyguardState.GLANCEABLE_HUB } else { KeyguardState.LOCKSCREEN Loading @@ -110,15 +114,19 @@ constructor( keyguardInteractor.isKeyguardShowing, communalInteractor.isIdleOnCommunal, communalInteractor.showCommunalFromOccluded, communalInteractor.dreamFromOccluded, ) .filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _, _) -> .filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _, _, _) -> !isOccluded && isShowing } .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded) -> .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> // Occlusion signals come from the framework, and should interrupt any // existing transition val to = if (isIdleOnCommunal || showCommunalFromOccluded) { if (restartDreamOnUnocclude() && dreamFromOccluded) { KeyguardState.DREAMING } else if (isIdleOnCommunal || showCommunalFromOccluded) { KeyguardState.GLANCEABLE_HUB } else { KeyguardState.LOCKSCREEN Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -856,6 +856,16 @@ flag { } } flag { name: "restart_dream_on_unocclude" namespace: "systemui" description: "re-enters dreaming upon unocclude when dreaming when originally occluding" bug: "338051457" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "communal_bouncer_do_not_modify_plugin_open" namespace: "systemui" Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt +31 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,16 @@ package com.android.systemui.communal import android.platform.test.annotations.EnableFlags import android.service.dream.dreamManager 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.communal.domain.interactor.communalInteractor import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -62,6 +66,7 @@ class CommunalDreamStartableTest : SysuiTestCase() { powerInteractor = kosmos.powerInteractor, keyguardInteractor = kosmos.keyguardInteractor, keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, communalInteractor = kosmos.communalInteractor, dreamManager = dreamManager, bgScope = kosmos.applicationCoroutineScope, ) Loading @@ -83,6 +88,32 @@ class CommunalDreamStartableTest : SysuiTestCase() { verify(dreamManager).startDream() } @Test @EnableFlags(Flags.FLAG_RESTART_DREAM_ON_UNOCCLUDE) fun restartDreamingWhenTransitioningFromDreamingToOccludedToDreaming() = testScope.runTest { keyguardRepository.setDreaming(false) powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true) runCurrent() verify(dreamManager, never()).startDream() kosmos.fakeKeyguardRepository.setKeyguardOccluded(true) kosmos.fakeKeyguardRepository.setDreaming(true) runCurrent() transition(from = KeyguardState.DREAMING, to = KeyguardState.OCCLUDED) kosmos.fakeKeyguardRepository.setKeyguardOccluded(false) kosmos.fakeKeyguardRepository.setDreaming(false) runCurrent() transition(from = KeyguardState.OCCLUDED, to = KeyguardState.DREAMING) runCurrent() verify(dreamManager).startDream() } @Test fun shouldNotStartDreamWhenIneligibleToDream() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt +18 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.SuppressLint import android.app.DreamManager import com.android.systemui.CoreStartable import com.android.systemui.Flags.communalHub import com.android.systemui.Flags.restartDreamOnUnocclude import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor Loading @@ -27,8 +29,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.kotlin.Utils.Companion.sample import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach Loading @@ -43,6 +47,7 @@ constructor( private val powerInteractor: PowerInteractor, private val keyguardInteractor: KeyguardInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val communalInteractor: CommunalInteractor, private val dreamManager: DreamManager, @Background private val bgScope: CoroutineScope, ) : CoreStartable { Loading @@ -52,6 +57,19 @@ constructor( return } // Return to dream from occluded when not already dreaming. if (restartDreamOnUnocclude()) { keyguardTransitionInteractor.startedKeyguardTransitionStep .sample(keyguardInteractor.isDreaming, ::Pair) .filter { it.first.from == KeyguardState.OCCLUDED && it.first.to == KeyguardState.DREAMING && !it.second } .onEach { dreamManager.startDream() } .launchIn(bgScope) } // Restart the dream underneath the hub in order to support the ability to swipe // away the hub to enter the dream. keyguardTransitionInteractor.finishedKeyguardState Loading
packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +7 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,13 @@ constructor( initialValue = false, ) /** Whether to start dreaming when returning from occluded */ val dreamFromOccluded: Flow<Boolean> = keyguardTransitionInteractor .transitionStepsToState(KeyguardState.OCCLUDED) .map { it.from == KeyguardState.DREAMING } .stateIn(scope = applicationScope, SharingStarted.Eagerly, false) /** * Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene]. * Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +13 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import android.animation.ValueAnimator import com.android.app.animation.Interpolators import com.android.systemui.Flags.restartDreamOnUnocclude import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background Loading Loading @@ -90,12 +91,15 @@ constructor( .sample( communalInteractor.isIdleOnCommunal, communalInteractor.showCommunalFromOccluded, communalInteractor.dreamFromOccluded ) .collect { (_, isIdleOnCommunal, showCommunalFromOccluded) -> .collect { (_, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> // Occlusion signals come from the framework, and should interrupt any // existing transition val to = if (isIdleOnCommunal || showCommunalFromOccluded) { if (restartDreamOnUnocclude() && dreamFromOccluded) { KeyguardState.DREAMING } else if (isIdleOnCommunal || showCommunalFromOccluded) { KeyguardState.GLANCEABLE_HUB } else { KeyguardState.LOCKSCREEN Loading @@ -110,15 +114,19 @@ constructor( keyguardInteractor.isKeyguardShowing, communalInteractor.isIdleOnCommunal, communalInteractor.showCommunalFromOccluded, communalInteractor.dreamFromOccluded, ) .filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _, _) -> .filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _, _, _) -> !isOccluded && isShowing } .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded) -> .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded, dreamFromOccluded) -> // Occlusion signals come from the framework, and should interrupt any // existing transition val to = if (isIdleOnCommunal || showCommunalFromOccluded) { if (restartDreamOnUnocclude() && dreamFromOccluded) { KeyguardState.DREAMING } else if (isIdleOnCommunal || showCommunalFromOccluded) { KeyguardState.GLANCEABLE_HUB } else { KeyguardState.LOCKSCREEN Loading