Merge changes Ida1ee588,Ib5a356ad into main
* changes:
Fix misc issues for transition to hub when turning screen on
Fix glanceable hub not showing when waking from doze
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
index 2ba4bf9..e25c1a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
@@ -34,8 +34,6 @@
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.realKeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.DozeStateModel
-import com.android.systemui.keyguard.shared.model.DozeTransitionModel
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
@@ -50,8 +48,6 @@
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
-import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
-import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.seconds
@@ -220,15 +216,11 @@
@Test
fun transition_from_hub_end_in_dream() =
testScope.runTest {
- // Device is dreaming and not dozing.
- kosmos.powerInteractor.setAwakeForTest()
- kosmos.fakeKeyguardRepository.setDozeTransitionModel(
- DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
- )
+ // Device is dreaming and occluded.
kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
kosmos.fakeKeyguardRepository.setDreaming(true)
kosmos.fakeKeyguardRepository.setDreamingWithOverlay(true)
- advanceTimeBy(600L)
+ runCurrent()
sceneTransitions.value = hubToBlank
@@ -663,7 +655,7 @@
from = LOCKSCREEN,
to = OCCLUDED,
animator = null,
- modeOnCanceled = TransitionModeOnCanceled.RESET
+ modeOnCanceled = TransitionModeOnCanceled.RESET,
)
)
@@ -750,7 +742,7 @@
from = LOCKSCREEN,
to = OCCLUDED,
animator = null,
- modeOnCanceled = TransitionModeOnCanceled.RESET
+ modeOnCanceled = TransitionModeOnCanceled.RESET,
)
)
@@ -852,8 +844,8 @@
to = ALTERNATE_BOUNCER,
animator = null,
ownerName = "external",
- modeOnCanceled = TransitionModeOnCanceled.RESET
- ),
+ modeOnCanceled = TransitionModeOnCanceled.RESET,
+ )
)
val allSteps by collectValues(keyguardTransitionRepository.transitions)
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 fac9312..ff0a4a1 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
@@ -26,8 +26,10 @@
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR
import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
+import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -50,10 +52,12 @@
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
+import com.google.common.truth.Truth
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -219,6 +223,28 @@
}
@Test
+ @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR, FLAG_SCENE_CONTAINER)
+ @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ fun testTransitionToGlanceableHub_onWakeup_ifAvailable() =
+ testScope.runTest {
+ // Hub is available.
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ // Device turns on.
+ powerInteractor.setAwakeForTest()
+ advanceTimeBy(50L)
+ runCurrent()
+
+ // We transition to the hub when waking up.
+ Truth.assertThat(kosmos.communalSceneRepository.currentScene.value)
+ .isEqualTo(CommunalScenes.Communal)
+ // No transitions are directly started by this interactor.
+ assertThat(transitionRepository).noTransitionsStarted()
+ }
+
+ @Test
@EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToOccluded_onWakeup_whenOccludingActivityOnTop() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
index 638c957..a08fbbf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
@@ -16,12 +16,19 @@
package com.android.systemui.keyguard.domain.interactor
+import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.flag.junit.FlagsParameterization
+import android.service.dream.dreamManager
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
+import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
+import com.android.systemui.communal.data.repository.communalSceneRepository
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -36,6 +43,7 @@
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -43,26 +51,52 @@
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class FromDreamingTransitionInteractorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiTestCase() {
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ .andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags!!)
+ }
+
private val kosmos =
testKosmos().apply {
this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository())
}
private val testScope = kosmos.testScope
- private val underTest = kosmos.fromDreamingTransitionInteractor
+ private val underTest by lazy { kosmos.fromDreamingTransitionInteractor }
private val powerInteractor = kosmos.powerInteractor
private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
@Before
fun setup() {
+ runBlocking {
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DREAMING,
+ testScope,
+ )
+ reset(transitionRepository)
+ kosmos.setCommunalAvailable(true)
+ }
underTest.start()
}
@@ -86,10 +120,7 @@
runCurrent()
assertThat(transitionRepository)
- .startedTransition(
- from = KeyguardState.DREAMING,
- to = KeyguardState.OCCLUDED,
- )
+ .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.OCCLUDED)
}
@Test
@@ -126,7 +157,7 @@
transitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.DREAMING,
- testScope
+ testScope,
)
kosmos.fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE)
@@ -139,10 +170,7 @@
advanceTimeBy(60L)
assertThat(transitionRepository)
- .startedTransition(
- from = KeyguardState.DREAMING,
- to = KeyguardState.LOCKSCREEN,
- )
+ .startedTransition(from = KeyguardState.DREAMING, to = KeyguardState.LOCKSCREEN)
}
@Test
@@ -164,4 +192,25 @@
to = KeyguardState.ALTERNATE_BOUNCER,
)
}
+
+ @Test
+ @EnableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
+ fun testTransitionToGlanceableHubOnWake() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ // Device wakes up.
+ powerInteractor.setAwakeForTest()
+ advanceTimeBy(150L)
+ runCurrent()
+
+ // We transition to the hub when waking up.
+ assertThat(kosmos.communalSceneRepository.currentScene.value)
+ .isEqualTo(CommunalScenes.Communal)
+ // No transitions are directly started by this interactor.
+ assertThat(transitionRepository).noTransitionsStarted()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 77106ae..a617484 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -1465,10 +1465,8 @@
// WHEN the keyguard is occluded and device wakes up and is no longer dreaming
keyguardRepository.setDreaming(false)
- testScheduler.advanceTimeBy(150) // The dreaming signal is debounced.
- runCurrent()
keyguardRepository.setKeyguardOccluded(true)
- powerInteractor.setAwakeForTest()
+ testScheduler.advanceTimeBy(150) // The dreaming and occluded signals are debounced.
runCurrent()
// THEN a transition to OCCLUDED should occur
@@ -2059,12 +2057,7 @@
fun glanceableHubToOccluded_communalKtfRefactor() =
testScope.runTest {
// GIVEN device is not dreaming
- powerInteractor.setAwakeForTest()
keyguardRepository.setDreaming(false)
- keyguardRepository.setDozeTransitionModel(
- DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
- )
- advanceTimeBy(600.milliseconds)
// GIVEN a prior transition has run to GLANCEABLE_HUB
communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")
@@ -2073,6 +2066,7 @@
// WHEN the keyguard is occluded
keyguardRepository.setKeyguardOccluded(true)
+ advanceTimeBy(200.milliseconds)
runCurrent()
assertThat(transitionRepository)
@@ -2218,6 +2212,7 @@
advanceTimeBy(10.milliseconds)
keyguardRepository.setKeyguardOccluded(true)
advanceTimeBy(200.milliseconds)
+ runCurrent()
assertThat(transitionRepository)
.startedTransition(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 425f16e..4adf693 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -44,6 +44,7 @@
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
+import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
@@ -363,6 +364,69 @@
showLockscreen()
assertThat(alpha).isEqualTo(1f)
+ // Go to dozing
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = LOCKSCREEN,
+ to = DOZING,
+ testScope,
+ )
+ assertThat(alpha).isEqualTo(1f)
+
+ // Start transitioning to glanceable hub
+ val progress = 0.6f
+ kosmos.setTransition(
+ sceneTransition = Transition(from = Scenes.Lockscreen, to = Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ transitionState = TransitionState.STARTED,
+ from = DOZING,
+ to = GLANCEABLE_HUB,
+ value = 0f,
+ ),
+ )
+ runCurrent()
+ kosmos.setTransition(
+ sceneTransition =
+ Transition(
+ from = Scenes.Lockscreen,
+ to = Scenes.Communal,
+ progress = flowOf(progress),
+ ),
+ stateTransition =
+ TransitionStep(
+ transitionState = TransitionState.RUNNING,
+ from = DOZING,
+ to = GLANCEABLE_HUB,
+ value = progress,
+ ),
+ )
+ runCurrent()
+ // Keep notifications hidden during the transition from dream to hub
+ assertThat(alpha).isEqualTo(0)
+
+ // Finish transition to glanceable hub
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ transitionState = TransitionState.FINISHED,
+ from = DOZING,
+ to = GLANCEABLE_HUB,
+ value = 1f,
+ ),
+ )
+ assertThat(alpha).isEqualTo(0f)
+ }
+
+ @Test
+ fun glanceableHubAlpha_dozingToHub() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.glanceableHubAlpha)
+
+ // Start on lockscreen, notifications should be unhidden.
+ showLockscreen()
+ assertThat(alpha).isEqualTo(1f)
+
// Transition to dream, notifications should be hidden so that transition
// from dream->hub doesn't cause notification flicker.
showDream()
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
index 04393fe..1bd541e 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
@@ -65,7 +65,9 @@
keyguardTransitionInteractor
.transitionValue(Scenes.Communal, KeyguardState.GLANCEABLE_HUB)
.map { it == 1f },
- not(keyguardInteractor.isDreaming),
+ // Use isDreamingAny because isDreaming is false in doze and doesn't change again
+ // when the screen turns on, which causes the dream to not start underneath the hub.
+ not(keyguardInteractor.isDreamingAny),
// TODO(b/362830856): Remove this workaround.
keyguardInteractor.isKeyguardShowing,
not(communalSceneInteractor.isLaunchingWidget),
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 c7538bb4..905eda1 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
@@ -87,7 +87,9 @@
*/
private val nextKeyguardStateInternal =
combine(
- keyguardInteractor.isAbleToDream,
+ // Don't use delayed dreaming signal as otherwise we might go to occluded or lock
+ // screen when closing hub if dream just started under the hub.
+ keyguardInteractor.isDreamingWithOverlay,
keyguardInteractor.isKeyguardOccluded,
keyguardInteractor.isKeyguardGoingAway,
keyguardInteractor.isKeyguardShowing,
@@ -156,7 +158,7 @@
private suspend fun handleIdle(
prevTransition: ObservableTransitionState,
- idle: ObservableTransitionState.Idle
+ idle: ObservableTransitionState.Idle,
) {
if (
prevTransition is ObservableTransitionState.Transition &&
@@ -186,7 +188,7 @@
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
1f,
- TransitionState.FINISHED
+ TransitionState.FINISHED,
)
resetTransitionData()
}
@@ -204,7 +206,7 @@
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
1f,
- TransitionState.FINISHED
+ TransitionState.FINISHED,
)
resetTransitionData()
}
@@ -217,7 +219,7 @@
private suspend fun handleTransition(
prevTransition: ObservableTransitionState,
- transition: ObservableTransitionState.Transition
+ transition: ObservableTransitionState.Transition,
) {
if (
prevTransition.isTransitioning(from = transition.fromContent, to = transition.toContent)
@@ -295,7 +297,7 @@
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
progress.coerceIn(0f, 1f),
- TransitionState.RUNNING
+ TransitionState.RUNNING,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index b0820a7..8c7fe5f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -150,7 +150,9 @@
if (!SceneContainerFlag.isEnabled) {
startTransitionTo(KeyguardState.GLANCEABLE_HUB)
}
- } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
+ } else if (isCommunalAvailable && dreamManager.canStartDreaming(false)) {
+ // Using false for isScreenOn as canStartDreaming returns false if any
+ // dream, including doze, is active.
// This case handles tapping the power button to transition through
// dream -> off -> hub.
if (!SceneContainerFlag.isEnabled) {
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 2434b29..9a0a858 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
@@ -17,9 +17,12 @@
package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
+import android.annotation.SuppressLint
+import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
import com.android.systemui.Flags.communalSceneKtfRefactor
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -60,10 +63,12 @@
@Main mainDispatcher: CoroutineDispatcher,
keyguardInteractor: KeyguardInteractor,
private val glanceableHubTransitions: GlanceableHubTransitions,
+ private val communalInteractor: CommunalInteractor,
private val communalSceneInteractor: CommunalSceneInteractor,
private val communalSettingsInteractor: CommunalSettingsInteractor,
powerInteractor: PowerInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+ private val dreamManager: DreamManager,
private val deviceEntryInteractor: DeviceEntryInteractor,
) :
TransitionInteractor(
@@ -76,6 +81,7 @@
keyguardInteractor = keyguardInteractor,
) {
+ @SuppressLint("MissingPermission")
override fun start() {
listenForDreamingToAlternateBouncer()
listenForDreamingToOccluded()
@@ -86,6 +92,8 @@
listenForTransitionToCamera(scope, keyguardInteractor)
if (!communalSceneKtfRefactor()) {
listenForDreamingToGlanceableHub()
+ } else {
+ listenForDreamingToGlanceableHubFromPowerButton()
}
listenForDreamingToPrimaryBouncer()
}
@@ -112,6 +120,34 @@
}
}
+ /**
+ * Normally when pressing power button from the dream, the devices goes from DREAMING to DOZING,
+ * then [FromDozingTransitionInteractor] handles the transition to GLANCEABLE_HUB. However if
+ * the power button is pressed quickly, we may need to go directly from DREAMING to
+ * GLANCEABLE_HUB as the transition to DOZING has not occurred yet.
+ */
+ @SuppressLint("MissingPermission")
+ private fun listenForDreamingToGlanceableHubFromPowerButton() {
+ if (!communalSettingsInteractor.isCommunalFlagEnabled()) return
+ if (SceneContainerFlag.isEnabled) return
+ scope.launch {
+ powerInteractor.isAwake
+ .debounce(50L)
+ .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
+ .sample(communalInteractor.isCommunalAvailable)
+ .collect { isCommunalAvailable ->
+ if (isCommunalAvailable && dreamManager.canStartDreaming(false)) {
+ // This case handles tapping the power button to transition through
+ // dream -> off -> hub.
+ communalSceneInteractor.snapToScene(
+ newScene = CommunalScenes.Communal,
+ loggingReason = "from dreaming to hub",
+ )
+ }
+ }
+ }
+ }
+
private fun listenForDreamingToPrimaryBouncer() {
// TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
@@ -144,7 +180,7 @@
} else {
startTransitionTo(
KeyguardState.LOCKSCREEN,
- ownerReason = "Dream has ended and device is awake"
+ ownerReason = "Dream has ended and device is awake",
)
}
}
@@ -158,15 +194,14 @@
scope.launch {
combine(
keyguardInteractor.isKeyguardOccluded,
- keyguardInteractor.isAbleToDream
- // Debounce the dreaming signal since there is a race condition between
- // the occluded and dreaming signals. We therefore add a small delay
- // to give enough time for occluded to flip to false when the dream
- // ends, to avoid transitioning to OCCLUDED erroneously when exiting
- // the dream.
- .debounce(100.milliseconds),
- ::Pair
+ keyguardInteractor.isDreaming,
+ ::Pair,
)
+ // Debounce signals since there is a race condition between the occluded and
+ // dreaming signals when starting or stopping dreaming. We therefore add a small
+ // delay to give enough time for occluded to flip to false when the dream
+ // ends, to avoid transitioning to OCCLUDED erroneously when exiting the dream.
+ .debounce(100.milliseconds)
.filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) ->
isOccluded && !isDreaming
}
@@ -194,12 +229,12 @@
if (dismissable) {
startTransitionTo(
KeyguardState.GONE,
- ownerReason = "No longer dreaming; dismissable"
+ ownerReason = "No longer dreaming; dismissable",
)
} else {
startTransitionTo(
KeyguardState.LOCKSCREEN,
- ownerReason = "No longer dreaming"
+ ownerReason = "No longer dreaming",
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index 7759298..6b6a3dce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -202,15 +202,15 @@
scope.launch {
combine(
keyguardInteractor.isKeyguardOccluded,
- keyguardInteractor.isAbleToDream
- // Debounce the dreaming signal since there is a race condition between
- // the occluded and dreaming signals. We therefore add a small delay
- // to give enough time for occluded to flip to false when the dream
- // ends, to avoid transitioning to OCCLUDED erroneously when exiting
- // the dream.
- .debounce(100.milliseconds),
+ keyguardInteractor.isDreaming,
::Pair,
)
+ // Debounce signals since there is a race condition between the occluded and
+ // dreaming signals when starting or stopping dreaming. We therefore add a small
+ // delay to give enough time for occluded to flip to false when the dream
+ // ends, to avoid transitioning to OCCLUDED erroneously when exiting the dream
+ // or when the dream starts underneath the hub.
+ .debounce(200.milliseconds)
.sampleFilter(
// When launching activities from widgets on the hub, we have a
// custom occlusion animation.
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 822ee9b..e6ee112 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
@@ -175,8 +175,8 @@
val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
/**
- * Whether the system is dreaming. [isDreaming] will be always be true when [isDozing] is true,
- * but not vice-versa. Also accounts for [isDreamingWithOverlay]
+ * Whether the system is dreaming. [KeyguardRepository.isDreaming] will be always be true when
+ * [isDozing] is true, but not vice-versa. Also accounts for [isDreamingWithOverlay].
*/
val isDreaming: StateFlow<Boolean> =
merge(repository.isDreaming, repository.isDreamingWithOverlay)
@@ -186,6 +186,9 @@
initialValue = false,
)
+ /** Whether any dreaming is running, including the doze dream. */
+ val isDreamingAny: Flow<Boolean> = repository.isDreaming
+
/** Whether the system is dreaming and the active dream is hosted in lockscreen */
val isActiveDreamLockscreenHosted: StateFlow<Boolean> = repository.isActiveDreamLockscreenHosted
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt
index aee34e1..1e42e19 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt
@@ -26,6 +26,7 @@
import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
@SysUISingleton
class DozingToGlanceableHubTransitionViewModel
@@ -35,10 +36,16 @@
animationFlow
.setup(
duration = TO_GLANCEABLE_HUB_DURATION,
- edge = Edge.create(DOZING, Scenes.Communal)
+ edge = Edge.create(DOZING, Scenes.Communal),
)
.setupWithoutSceneContainer(edge = Edge.create(DOZING, GLANCEABLE_HUB))
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
+
+ /**
+ * Hide notifications when transitioning directly from dozing to hub, such as when pressing
+ * power button when dozing and docked.
+ */
+ val notificationAlpha: Flow<Float> = flowOf(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index e34eb61..8ca26be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -45,6 +45,7 @@
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
+import com.android.systemui.keyguard.ui.viewmodel.DozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
@@ -112,6 +113,7 @@
private val aodToGoneTransitionViewModel: AodToGoneTransitionViewModel,
private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
private val aodToOccludedTransitionViewModel: AodToOccludedTransitionViewModel,
+ dozingToGlanceableHubTransitionViewModel: DozingToGlanceableHubTransitionViewModel,
private val dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
private val dozingToOccludedTransitionViewModel: DozingToOccludedTransitionViewModel,
private val dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
@@ -506,6 +508,7 @@
merge(
lockscreenToGlanceableHubTransitionViewModel.notificationAlpha,
glanceableHubToLockscreenTransitionViewModel.notificationAlpha,
+ dozingToGlanceableHubTransitionViewModel.notificationAlpha,
)
// Manually emit on start because [notificationAlpha] only starts emitting
// when transitions start.
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
index 64ae051..e6c98cd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
@@ -16,6 +16,8 @@
package com.android.systemui.keyguard.domain.interactor
+import android.service.dream.dreamManager
+import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -39,10 +41,12 @@
mainDispatcher = testDispatcher,
keyguardInteractor = keyguardInteractor,
glanceableHubTransitions = glanceableHubTransitions,
+ communalInteractor = communalInteractor,
communalSceneInteractor = communalSceneInteractor,
communalSettingsInteractor = communalSettingsInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
+ dreamManager = dreamManager,
deviceEntryInteractor = deviceEntryInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..ef10459
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModelKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@ExperimentalCoroutinesApi
+val Kosmos.dozingToGlanceableHubTransitionViewModel by Fixture {
+ DozingToGlanceableHubTransitionViewModel(animationFlow = keyguardTransitionAnimationFlow)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index ffd8aab..a9e117a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -25,6 +25,7 @@
import com.android.systemui.keyguard.ui.viewmodel.aodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToOccludedTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.dozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dreamingToLockscreenTransitionViewModel
@@ -66,6 +67,7 @@
aodToGoneTransitionViewModel = aodToGoneTransitionViewModel,
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel,
+ dozingToGlanceableHubTransitionViewModel = dozingToGlanceableHubTransitionViewModel,
dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
dozingToOccludedTransitionViewModel = dozingToOccludedTransitionViewModel,
dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,