summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt23
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt46
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt4
6 files changed, 164 insertions, 9 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index cf145471e55f..0de036988337 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -27,6 +27,9 @@ import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dock.dockManager
import com.android.systemui.dock.fakeDockManager
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
@@ -66,6 +69,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
fun setUp() {
with(kosmos) {
fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT)
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
underTest =
CommunalSceneStartable(
@@ -76,6 +80,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
keyguardInteractor = keyguardInteractor,
systemSettings = fakeSettings,
notificationShadeWindowController = notificationShadeWindowController,
+ featureFlagsClassic = kosmos.fakeFeatureFlagsClassic,
applicationScope = applicationCoroutineScope,
bgScope = applicationCoroutineScope,
mainDispatcher = testDispatcher,
@@ -451,6 +456,24 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
}
+ @Test
+ fun transitionFromDozingToGlanceableHub_forcesCommunal() =
+ with(kosmos) {
+ testScope.runTest {
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
+ assertThat(scene).isEqualTo(CommunalScenes.Blank)
+
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope = this
+ )
+
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ }
+ }
+
private fun TestScope.updateDocked(docked: Boolean) =
with(kosmos) {
runCurrent()
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 612f2e73e4bb..ec4fd79b399a 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
@@ -34,12 +34,14 @@ package com.android.systemui.keyguard.domain.interactor
import android.os.PowerManager
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.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
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.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -64,8 +66,10 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
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
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -120,6 +124,66 @@ class FromDozingTransitionInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testTransitionToLockscreen_onPowerButtonPress_canDream_glanceableHubAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is possible and communal is available, then we should transition to
+ // GLANCEABLE_HUB when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testTransitionToLockscreen_onPowerButtonPress_canNotDream_glanceableHubAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(false)
+ kosmos.setCommunalAvailable(true)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is NOT possible but communal is available, then we should transition to
+ // LOCKSCREEN when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.LOCKSCREEN,
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ fun testTransitionToLockscreen_onPowerButtonPress_canNDream_glanceableHubNotAvailable() =
+ testScope.runTest {
+ whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
+ kosmos.setCommunalAvailable(false)
+ runCurrent()
+
+ powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON)
+ runCurrent()
+
+ // If dreaming is possible but communal is NOT available, then we should transition to
+ // LOCKSCREEN when waking up due to power button press.
+ assertThat(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.LOCKSCREEN,
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() =
testScope.runTest {
kosmos.fakeCommunalSceneRepository.setTransitionState(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 88c3f9f6af2e..bde6f42b16af 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -18,7 +18,9 @@ package com.android.systemui.communal
import android.provider.Settings
import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.CoreStartable
+import com.android.systemui.Flags.communalHub
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -28,6 +30,8 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dock.DockManager
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -74,6 +78,7 @@ constructor(
private val systemSettings: SystemSettings,
centralSurfacesOpt: Optional<CentralSurfaces>,
private val notificationShadeWindowController: NotificationShadeWindowController,
+ private val featureFlagsClassic: FeatureFlagsClassic,
@Application private val applicationScope: CoroutineScope,
@Background private val bgScope: CoroutineScope,
@Main private val mainDispatcher: CoroutineDispatcher,
@@ -86,13 +91,21 @@ constructor(
private val centralSurfaces: CentralSurfaces? by centralSurfacesOpt
+ private val flagEnabled: Boolean by lazy {
+ featureFlagsClassic.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) && communalHub()
+ }
+
override fun start() {
+ if (!flagEnabled) {
+ return
+ }
+
// Handle automatically switching based on keyguard state.
keyguardTransitionInteractor.startedKeyguardTransitionStep
.mapLatest(::determineSceneAfterTransition)
.filterNotNull()
- .onEach { nextScene ->
- communalSceneInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
+ .onEach { (nextScene, nextTransition) ->
+ communalSceneInteractor.changeScene(nextScene, nextTransition)
}
.launchIn(applicationScope)
@@ -188,7 +201,7 @@ constructor(
private suspend fun determineSceneAfterTransition(
lastStartedTransition: TransitionStep,
- ): SceneKey? {
+ ): Pair<SceneKey, TransitionKey>? {
val to = lastStartedTransition.to
val from = lastStartedTransition.from
val docked = dockManager.isDocked
@@ -201,22 +214,27 @@ constructor(
// underneath the hub is shown. When launching activities over lockscreen, we only
// change scenes once the activity launch animation is finished, so avoid
// changing the scene here.
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
}
to == KeyguardState.GLANCEABLE_HUB && from == KeyguardState.OCCLUDED -> {
// When transitioning to the hub from an occluded state, fade out the hub without
// doing any translation.
- CommunalScenes.Communal
+ Pair(CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade)
}
// Transitioning to Blank scene when entering the edit mode will be handled separately
// with custom animations.
to == KeyguardState.GONE && !communalInteractor.editModeOpen.value ->
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
!docked && !KeyguardState.deviceIsAwakeInState(to) -> {
// If the user taps the screen and wakes the device within this timeout, we don't
// want to dismiss the hub
delay(AWAKE_DEBOUNCE_DELAY)
- CommunalScenes.Blank
+ Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
+ }
+ from == KeyguardState.DOZING && to == KeyguardState.GLANCEABLE_HUB -> {
+ // Make sure the communal hub is showing (immediately, not fading in) when
+ // transitioning from dozing to hub.
+ Pair(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
}
else -> null
}
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 aee65a81880d..cd28bec938b8 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
@@ -17,8 +17,11 @@
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.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -28,6 +31,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion.isWakeAndUnlock
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.sample
@@ -53,9 +57,11 @@ constructor(
keyguardInteractor: KeyguardInteractor,
powerInteractor: PowerInteractor,
private val communalInteractor: CommunalInteractor,
+ private val communalSceneInteractor: CommunalSceneInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
val deviceEntryRepository: DeviceEntryRepository,
private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
+ private val dreamManager: DreamManager,
) :
TransitionInteractor(
fromState = KeyguardState.DOZING,
@@ -115,6 +121,7 @@ constructor(
}
}
+ @SuppressLint("MissingPermission")
private fun listenForDozingToAny() {
if (KeyguardWmStateRefactor.isEnabled) {
return
@@ -126,7 +133,8 @@ constructor(
.filterRelevantKeyguardStateAnd { isAwake -> isAwake }
.sample(
keyguardInteractor.isKeyguardOccluded,
- communalInteractor.isIdleOnCommunal,
+ communalInteractor.isCommunalAvailable,
+ communalSceneInteractor.isIdleOnCommunal,
canTransitionToGoneOnWake,
keyguardInteractor.primaryBouncerShowing,
)
@@ -134,6 +142,7 @@ constructor(
(
_,
occluded,
+ isCommunalAvailable,
isIdleOnCommunal,
canTransitionToGoneOnWake,
primaryBouncerShowing) ->
@@ -163,6 +172,19 @@ constructor(
} else {
startTransitionTo(KeyguardState.GLANCEABLE_HUB)
}
+ } else if (
+ powerInteractor.detailedWakefulness.value.lastWakeReason ==
+ WakeSleepReason.POWER_BUTTON &&
+ isCommunalAvailable &&
+ dreamManager.canStartDreaming(true)
+ ) {
+ // This case handles tapping the power button to transition through
+ // dream -> off -> hub.
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is needed
+ } else {
+ startTransitionTo(KeyguardState.GLANCEABLE_HUB)
+ }
} else {
startTransitionTo(KeyguardState.LOCKSCREEN)
}
@@ -171,6 +193,7 @@ constructor(
}
/** Figure out what state to transition to when we awake from DOZING. */
+ @SuppressLint("MissingPermission")
private fun listenForWakeFromDozing() {
if (!KeyguardWmStateRefactor.isEnabled) {
return
@@ -180,7 +203,8 @@ constructor(
powerInteractor.detailedWakefulness
.filterRelevantKeyguardStateAnd { it.isAwake() }
.sample(
- communalInteractor.isIdleOnCommunal,
+ communalInteractor.isCommunalAvailable,
+ communalSceneInteractor.isIdleOnCommunal,
keyguardInteractor.biometricUnlockState,
wakeToGoneInteractor.canWakeDirectlyToGone,
keyguardInteractor.primaryBouncerShowing,
@@ -188,6 +212,7 @@ constructor(
.collect {
(
_,
+ isCommunalAvailable,
isIdleOnCommunal,
biometricUnlockState,
canWakeDirectlyToGone,
@@ -227,6 +252,23 @@ constructor(
ownerReason = "waking from dozing"
)
}
+ } else if (
+ powerInteractor.detailedWakefulness.value.lastWakeReason ==
+ WakeSleepReason.POWER_BUTTON &&
+ isCommunalAvailable &&
+ dreamManager.canStartDreaming(true)
+ ) {
+ // This case handles tapping the power button to transition through
+ // dream -> off -> hub.
+ if (SceneContainerFlag.isEnabled) {
+ // TODO(b/336576536): Check if adaptation for scene framework is
+ // needed
+ } else {
+ startTransitionTo(
+ KeyguardState.GLANCEABLE_HUB,
+ ownerReason = "waking from dozing"
+ )
+ }
} else {
startTransitionTo(
KeyguardState.LOCKSCREEN,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 7c53639a85a6..0f8833cfe9f7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui
import android.app.ActivityManager
+import android.app.DreamManager
import android.app.admin.DevicePolicyManager
import android.app.trust.TrustManager
import android.hardware.fingerprint.FingerprintManager
@@ -33,6 +34,7 @@ import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.biometrics.AuthController
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.ScreenLifecycle
@@ -94,6 +96,7 @@ data class TestMocksModule(
@get:Provides val demoModeController: DemoModeController = mock(),
@get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(),
@get:Provides val dozeParameters: DozeParameters = mock(),
+ @get:Provides val dreamManager: DreamManager = mock(),
@get:Provides val dumpManager: DumpManager = mock(),
@get:Provides val fingerprintManager: FingerprintManager = mock(),
@get:Provides val headsUpManager: HeadsUpManager = mock(),
@@ -132,6 +135,7 @@ data class TestMocksModule(
@get:Provides val systemUIDialogManager: SystemUIDialogManager = mock(),
@get:Provides val deviceEntryIconTransitions: Set<DeviceEntryIconTransition> = emptySet(),
@get:Provides val communalInteractor: CommunalInteractor = mock(),
+ @get:Provides val communalSceneInteractor: CommunalSceneInteractor = mock(),
@get:Provides val sceneLogger: SceneLogger = mock(),
@get:Provides val trustManager: TrustManager = mock(),
@get:Provides val primaryBouncerInteractor: PrimaryBouncerInteractor = mock(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
index 446652c7c6d8..126d85890531 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
@@ -16,7 +16,9 @@
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.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
@@ -36,9 +38,11 @@ var Kosmos.fromDozingTransitionInteractor by
mainDispatcher = testDispatcher,
keyguardInteractor = keyguardInteractor,
communalInteractor = communalInteractor,
+ communalSceneInteractor = communalSceneInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
deviceEntryRepository = deviceEntryRepository,
wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
+ dreamManager = dreamManager
)
}