Merge "Fix hub<->occluded transition when undocked" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index dfc04ff..456fb79 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -57,6 +57,8 @@
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.activityStarter
@@ -1090,6 +1092,78 @@
.isEqualTo(USER_INFO_WORK.id)
}
+ @Test
+ fun showCommunalFromOccluded_enteredOccludedFromHub() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+ val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded)
+ assertThat(showCommunalFromOccluded).isFalse()
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ testScope
+ )
+
+ assertThat(showCommunalFromOccluded).isTrue()
+ }
+
+ @Test
+ fun showCommunalFromOccluded_enteredOccludedFromLockscreen() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+ val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded)
+ assertThat(showCommunalFromOccluded).isFalse()
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ testScope
+ )
+
+ assertThat(showCommunalFromOccluded).isFalse()
+ }
+
+ @Test
+ fun showCommunalFromOccluded_communalBecomesUnavailableWhileOccluded() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+ val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded)
+ assertThat(showCommunalFromOccluded).isFalse()
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ testScope
+ )
+ runCurrent()
+ kosmos.setCommunalAvailable(false)
+
+ assertThat(showCommunalFromOccluded).isFalse()
+ }
+
+ @Test
+ fun showCommunalFromOccluded_showBouncerWhileOccluded() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+ val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded)
+ assertThat(showCommunalFromOccluded).isFalse()
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ testScope
+ )
+ runCurrent()
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.OCCLUDED,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ testScope
+ )
+
+ assertThat(showCommunalFromOccluded).isTrue()
+ }
+
private fun smartspaceTimer(id: String, timestamp: Long = 0L): SmartspaceTarget {
val timer = mock(SmartspaceTarget::class.java)
whenever(timer.smartspaceTargetId).thenReturn(id)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
index 55e46dc..e1be6b0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
@@ -24,16 +24,17 @@
import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel
import com.android.systemui.communal.util.fakeCommunalColors
import com.android.systemui.concurrency.fakeExecutor
-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.keyguard.ScreenLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.wakefulnessLifecycle
import com.android.systemui.kosmos.testScope
import com.android.systemui.model.SysUiState
@@ -63,7 +64,6 @@
import java.util.Optional
import java.util.concurrent.Executor
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -186,29 +186,18 @@
verify(mRecentTasks).setTransitionBackgroundColor(null)
verify(mRecentTasks, never()).setTransitionBackgroundColor(black)
- setDocked(true)
- // Make communal available
- kosmos.fakeKeyguardRepository.setIsEncryptedOrLockdown(false)
- kosmos.fakeUserRepository.setSelectedUserInfo(MAIN_USER_INFO)
- kosmos.fakeKeyguardRepository.setKeyguardShowing(true)
-
+ // Transition to occluded from the glanceable hub.
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ testScope
+ )
+ kosmos.setCommunalAvailable(true)
runCurrent()
verify(mRecentTasks).setTransitionBackgroundColor(black)
}
- private fun TestScope.setDocked(docked: Boolean) {
- kosmos.fakeDockManager.setIsDocked(docked)
- val event =
- if (docked) {
- DockManager.STATE_DOCKED
- } else {
- DockManager.STATE_NONE
- }
- kosmos.fakeDockManager.setDockEvent(event)
- runCurrent()
- }
-
private companion object {
val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 5cf68b7..0042915 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -44,9 +44,10 @@
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dock.DockManager
-import com.android.systemui.dock.retrieveIsDocked
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
@@ -64,6 +65,7 @@
import com.android.systemui.util.kotlin.BooleanFlowOperators.or
import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BufferOverflow
@@ -77,9 +79,11 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.shareIn
@@ -92,6 +96,7 @@
@Inject
constructor(
@Application val applicationScope: CoroutineScope,
+ @Background val bgDispatcher: CoroutineDispatcher,
broadcastDispatcher: BroadcastDispatcher,
private val communalRepository: CommunalRepository,
private val widgetRepository: CommunalWidgetRepository,
@@ -99,13 +104,13 @@
mediaRepository: CommunalMediaRepository,
smartspaceRepository: SmartspaceRepository,
keyguardInteractor: KeyguardInteractor,
- private val communalSettingsInteractor: CommunalSettingsInteractor,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ communalSettingsInteractor: CommunalSettingsInteractor,
private val appWidgetHost: CommunalAppWidgetHost,
private val editWidgetsActivityStarter: EditWidgetsActivityStarter,
private val userTracker: UserTracker,
private val activityStarter: ActivityStarter,
private val userManager: UserManager,
- private val dockManager: DockManager,
sceneInteractor: SceneInteractor,
@CommunalLog logBuffer: LogBuffer,
@CommunalTableLog tableLogBuffer: TableLogBuffer,
@@ -145,8 +150,18 @@
replay = 1,
)
- /** Whether to show communal by default */
- val showByDefault: Flow<Boolean> = and(isCommunalAvailable, dockManager.retrieveIsDocked())
+ /** Whether to show communal when exiting the occluded state. */
+ val showCommunalFromOccluded: Flow<Boolean> =
+ keyguardTransitionInteractor.startedKeyguardTransitionStep
+ .filter { step -> step.to == KeyguardState.OCCLUDED }
+ .combine(isCommunalAvailable, ::Pair)
+ .map { (step, available) -> available && step.from == KeyguardState.GLANCEABLE_HUB }
+ .flowOn(bgDispatcher)
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = false,
+ )
/**
* Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene].
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
index 1bee83b..337d873 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
@@ -63,8 +63,8 @@
)
.distinctUntilChanged()
- /** Whether to show communal by default */
- val showByDefault: Flow<Boolean> = communalInteractor.showByDefault
+ /** Whether to show communal when exiting the occluded state. */
+ val showCommunalFromOccluded: Flow<Boolean> = communalInteractor.showCommunalFromOccluded
val transitionFromOccludedEnded =
keyguardTransitionInteractor.transitionStepsFromState(KeyguardState.OCCLUDED).filter { step
@@ -74,8 +74,11 @@
}
val recentsBackgroundColor: Flow<Color?> =
- combine(showByDefault, communalColors.backgroundColor) { showByDefault, backgroundColor ->
- if (showByDefault) {
+ combine(showCommunalFromOccluded, communalColors.backgroundColor) {
+ showCommunalFromOccluded,
+ backgroundColor,
+ ->
+ if (showCommunalFromOccluded) {
backgroundColor
} else {
null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6ef39f3..d6fd354 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -177,10 +177,6 @@
import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
import com.android.wm.shell.keyguard.KeyguardTransitions;
-import dagger.Lazy;
-
-import kotlinx.coroutines.CoroutineDispatcher;
-
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -190,6 +186,9 @@
import java.util.concurrent.Executor;
import java.util.function.Consumer;
+import dagger.Lazy;
+import kotlinx.coroutines.CoroutineDispatcher;
+
/**
* Mediates requests related to the keyguard. This includes queries about the
* state of the keyguard, power management events that effect whether the keyguard
@@ -1234,7 +1233,7 @@
mUnoccludeAnimator.cancel();
}
- if (isDream || mShowCommunalByDefault) {
+ if (isDream || mShowCommunalWhenUnoccluding) {
initAlphaForAnimationTargets(wallpapers);
if (isDream) {
mDreamViewModel.get().startTransitionFromDream();
@@ -1372,7 +1371,7 @@
private final Lazy<DreamViewModel> mDreamViewModel;
private final Lazy<CommunalTransitionViewModel> mCommunalTransitionViewModel;
private RemoteAnimationTarget mRemoteAnimationTarget;
- private boolean mShowCommunalByDefault = false;
+ private boolean mShowCommunalWhenUnoccluding = false;
private final Lazy<WindowManagerLockscreenVisibilityManager> mWmLockscreenVisibilityManager;
@@ -1630,8 +1629,10 @@
getRemoteSurfaceAlphaApplier());
mJavaAdapter.alwaysCollectFlow(dreamViewModel.getTransitionEnded(),
getFinishedCallbackConsumer());
- mJavaAdapter.alwaysCollectFlow(communalViewModel.getShowByDefault(),
- (showByDefault) -> mShowCommunalByDefault = showByDefault);
+ mJavaAdapter.alwaysCollectFlow(communalViewModel.getShowCommunalFromOccluded(),
+ (showCommunalFromOccluded) -> {
+ mShowCommunalWhenUnoccluding = showCommunalFromOccluded;
+ });
mJavaAdapter.alwaysCollectFlow(communalViewModel.getTransitionFromOccludedEnded(),
getFinishedCallbackConsumer());
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index ee589f4..e51ba83 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -87,12 +87,15 @@
scope.launch {
keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
.filterRelevantKeyguardStateAnd { onTop -> !onTop }
- .sample(communalInteractor.isIdleOnCommunal, communalInteractor.showByDefault)
- .collect { (_, isIdleOnCommunal, showCommunalByDefault) ->
+ .sample(
+ communalInteractor.isIdleOnCommunal,
+ communalInteractor.showCommunalFromOccluded,
+ )
+ .collect { (_, isIdleOnCommunal, showCommunalFromOccluded) ->
// Occlusion signals come from the framework, and should interrupt any
// existing transition
val to =
- if (isIdleOnCommunal || showCommunalByDefault) {
+ if (isIdleOnCommunal || showCommunalFromOccluded) {
KeyguardState.GLANCEABLE_HUB
} else {
KeyguardState.LOCKSCREEN
@@ -106,16 +109,16 @@
.sample(
keyguardInteractor.isKeyguardShowing,
communalInteractor.isIdleOnCommunal,
- communalInteractor.showByDefault,
+ communalInteractor.showCommunalFromOccluded,
)
.filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _, _) ->
!isOccluded && isShowing
}
- .collect { (_, _, isIdleOnCommunal, showCommunalByDefault) ->
+ .collect { (_, _, isIdleOnCommunal, showCommunalFromOccluded) ->
// Occlusion signals come from the framework, and should interrupt any
// existing transition
val to =
- if (isIdleOnCommunal || showCommunalByDefault) {
+ if (isIdleOnCommunal || showCommunalFromOccluded) {
KeyguardState.GLANCEABLE_HUB
} else {
KeyguardState.LOCKSCREEN
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 325e7bf..6b1d39a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -241,7 +241,7 @@
.thenReturn(mock(Flow.class));
when(mDreamViewModel.getTransitionEnded())
.thenReturn(mock(Flow.class));
- when(mCommunalTransitionViewModel.getShowByDefault())
+ when(mCommunalTransitionViewModel.getShowCommunalFromOccluded())
.thenReturn(mock(Flow.class));
when(mCommunalTransitionViewModel.getTransitionFromOccludedEnded())
.thenReturn(mock(Flow.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 691d48f..1dc58d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -26,8 +26,8 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.dock.DockManager
import com.android.systemui.dock.fakeDockManager
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -1229,23 +1229,22 @@
}
@Test
- fun occludedToGlanceableHubWhenDocked() =
+ fun occludedToGlanceableHubWhenInitiallyOnHub() =
testScope.runTest {
- // GIVEN a device on lockscreen
+ // GIVEN a device on lockscreen and communal is available
keyguardRepository.setKeyguardShowing(true)
+ kosmos.setCommunalAvailable(true)
runCurrent()
- // GIVEN a prior transition has run to OCCLUDED
+ // GIVEN a prior transition has run to OCCLUDED from GLANCEABLE_HUB
runTransitionAndSetWakefulness(KeyguardState.GLANCEABLE_HUB, KeyguardState.OCCLUDED)
keyguardRepository.setKeyguardOccluded(true)
runCurrent()
- // GIVEN device is docked/communal is available
- dockManager.setIsDocked(true)
- dockManager.setDockEvent(DockManager.STATE_DOCKED)
+ // GIVEN on blank scene
val idleTransitionState =
MutableStateFlow<ObservableTransitionState>(
- ObservableTransitionState.Idle(CommunalScenes.Communal)
+ ObservableTransitionState.Idle(CommunalScenes.Blank)
)
communalInteractor.setTransitionState(idleTransitionState)
runCurrent()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 3dd382f..3fe6973 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -23,14 +23,15 @@
import com.android.systemui.communal.data.repository.communalRepository
import com.android.systemui.communal.data.repository.communalWidgetRepository
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
-import com.android.systemui.dock.fakeDockManager
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -42,6 +43,7 @@
val Kosmos.communalInteractor by Fixture {
CommunalInteractor(
applicationScope = applicationCoroutineScope,
+ bgDispatcher = testDispatcher,
broadcastDispatcher = broadcastDispatcher,
communalRepository = communalRepository,
widgetRepository = communalWidgetRepository,
@@ -49,13 +51,13 @@
mediaRepository = communalMediaRepository,
smartspaceRepository = smartspaceRepository,
keyguardInteractor = keyguardInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
communalSettingsInteractor = communalSettingsInteractor,
appWidgetHost = mock(),
editWidgetsActivityStarter = editWidgetsActivityStarter,
userTracker = userTracker,
activityStarter = activityStarter,
userManager = userManager,
- dockManager = fakeDockManager,
sceneInteractor = sceneInteractor,
logBuffer = logcatLogBuffer("CommunalInteractor"),
tableLogBuffer = mock(),