Loading packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +9 −4 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn /** Encapsulates business-logic related to communal mode. */ @OptIn(ExperimentalCoroutinesApi::class) Loading Loading @@ -239,10 +240,14 @@ constructor( * This will not be true while transitioning to the hub and will turn false immediately when a * swipe to exit the hub starts. */ val isIdleOnCommunal: Flow<Boolean> = communalRepository.transitionState.map { it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal } val isIdleOnCommunal: StateFlow<Boolean> = communalRepository.transitionState .map { it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = false, ) /** * Flow that emits a boolean if any portion of the communal UI is visible at all. Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +45 −5 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ import androidx.core.animation.ObjectAnimator import com.android.app.animation.Interpolators import com.android.app.animation.InterpolatorsAndroidX import com.android.systemui.Dumpable import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionChangeEvent Loading @@ -47,11 +49,14 @@ import java.io.PrintWriter import javax.inject.Inject import kotlin.math.max import kotlin.math.min import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @SysUISingleton class NotificationWakeUpCoordinator @Inject constructor( @Application applicationScope: CoroutineScope, dumpManager: DumpManager, private val mHeadsUpManager: HeadsUpManager, private val statusBarStateController: StatusBarStateController, Loading @@ -60,6 +65,7 @@ constructor( private val screenOffAnimationController: ScreenOffAnimationController, private val logger: NotificationWakeUpCoordinatorLogger, private val notifsKeyguardInteractor: NotificationsKeyguardInteractor, private val communalInteractor: CommunalInteractor, ) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, Loading Loading @@ -201,6 +207,13 @@ constructor( } } ) applicationScope.launch { communalInteractor.isIdleOnCommunal.collect { if (!overrideDozeAmountIfCommunalShowing()) { maybeClearHardDozeAmountOverrideHidingNotifs() } } } } fun setStackScroller(stackScrollerController: NotificationStackScrollLayoutController) { Loading Loading @@ -302,6 +315,10 @@ constructor( return } if (overrideDozeAmountIfCommunalShowing()) { return } if (clearHardDozeAmountOverride()) { return } Loading @@ -311,10 +328,13 @@ constructor( private fun setHardDozeAmountOverride(dozing: Boolean, source: String) { logger.logSetDozeAmountOverride(dozing = dozing, source = source) val previousOverride = hardDozeAmountOverride hardDozeAmountOverride = if (dozing) 1f else 0f hardDozeAmountOverrideSource = source if (previousOverride != hardDozeAmountOverride) { updateDozeAmount() } } private fun clearHardDozeAmountOverride(): Boolean { if (hardDozeAmountOverride == null) return false Loading Loading @@ -434,6 +454,11 @@ constructor( return } if (overrideDozeAmountIfCommunalShowing()) { this.state = newState return } maybeClearHardDozeAmountOverrideHidingNotifs() this.state = newState Loading Loading @@ -471,6 +496,18 @@ constructor( return false } private fun overrideDozeAmountIfCommunalShowing(): Boolean { if (communalInteractor.isIdleOnCommunal.value) { if (statusBarStateController.state == StatusBarState.KEYGUARD) { setHardDozeAmountOverride(dozing = true, source = "Override: communal (keyguard)") } else { setHardDozeAmountOverride(dozing = false, source = "Override: communal (shade)") } return true } return false } /** * If the last [setDozeAmount] call was an override to hide notifications, then this call will * check for the set of states that may have caused that override, and if none of them still Loading @@ -483,20 +520,23 @@ constructor( val onKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD val dozing = statusBarStateController.isDozing val bypass = bypassController.bypassEnabled val idleOnCommunal = communalInteractor.isIdleOnCommunal.value val animating = screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard() // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff] and // [overrideDozeAmountIfBypass] based on 'animating' and 'bypass' respectively, so only // clear the override if both those conditions are cleared. But also require either // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff], // [overrideDozeAmountIfBypass] and [overrideDozeAmountIfCommunalShowing] based on // 'animating', 'bypass' and 'idleOnCommunal' respectively, so only clear the override // if all of those conditions are cleared. But also require either // !dozing or !onKeyguard because those conditions should indicate that we intend // notifications to be visible, and thus it is safe to unhide them. val willRemove = (!onKeyguard || !dozing) && !bypass && !animating val willRemove = (!onKeyguard || !dozing) && !bypass && !animating && !idleOnCommunal logger.logMaybeClearHardDozeAmountOverrideHidingNotifs( willRemove = willRemove, onKeyguard = onKeyguard, dozing = dozing, bypass = bypass, animating = animating, idleOnCommunal = idleOnCommunal, ) if (willRemove) { clearHardDozeAmountOverride() Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt +2 −1 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) { onKeyguard: Boolean, dozing: Boolean, bypass: Boolean, idleOnCommunal: Boolean, animating: Boolean, ) { buffer.log( Loading @@ -103,7 +104,7 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) { { str1 = "willRemove=$willRemove onKeyguard=$onKeyguard dozing=$dozing" + " bypass=$bypass animating=$animating" " bypass=$bypass animating=$animating idleOnCommunal=$idleOnCommunal" }, { "maybeClearHardDozeAmountOverrideHidingNotifs() $str1" } ) Loading packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -604,6 +604,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { new NotificationsKeyguardInteractor(notifsKeyguardViewStateRepository); NotificationWakeUpCoordinator coordinator = new NotificationWakeUpCoordinator( mKosmos.getTestScope().getBackgroundScope(), mDumpManager, mock(HeadsUpManager.class), new StatusBarStateControllerImpl( Loading @@ -618,7 +619,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mDozeParameters, mScreenOffAnimationController, new NotificationWakeUpCoordinatorLogger(logcatLogBuffer()), notifsKeyguardInteractor); notifsKeyguardInteractor, mKosmos.getCommunalInteractor()); mConfigurationController = new ConfigurationControllerImpl(mContext); PulseExpansionHandler expansionHandler = new PulseExpansionHandler( mContext, Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt +49 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ package com.android.systemui.statusbar.notification import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.communal.data.repository.communalRepository import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dump.DumpManager import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeViewController.Companion.WAKEUP_ANIMATION_DELAY_MS Loading @@ -34,11 +39,16 @@ import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.testKosmos import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -49,6 +59,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidTestingRunner::class) @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) Loading @@ -56,7 +67,8 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { @get:Rule val animatorTestRule = AnimatorTestRule(this) private val kosmos = Kosmos() private val kosmos = testKosmos() private val testScope = kosmos.testScope private val dumpManager: DumpManager = mock() private val headsUpManager: HeadsUpManager = mock() Loading Loading @@ -97,6 +109,7 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { whenever(statusBarStateController.state).then { statusBarState } notificationWakeUpCoordinator = NotificationWakeUpCoordinator( kosmos.applicationCoroutineScope, dumpManager, headsUpManager, statusBarStateController, Loading @@ -105,6 +118,7 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { screenOffAnimationController, logger, kosmos.notificationsKeyguardInteractor, kosmos.communalInteractor, ) statusBarStateCallback = withArgCaptor { verify(statusBarStateController).addCallback(capture()) Loading Loading @@ -160,6 +174,39 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse() } @Test fun setDozeToZeroWhenCommunalShowingWillFullyHideNotifications() = testScope.runTest { val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(CommunalScenes.Communal) ) kosmos.communalRepository.setTransitionState(transitionState) runCurrent() setDozeAmount(0f) verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue() } @Test fun closingCommunalWillShowNotifications() = testScope.runTest { val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(CommunalScenes.Communal) ) kosmos.communalRepository.setTransitionState(transitionState) runCurrent() setDozeAmount(0f) verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue() transitionState.value = ObservableTransitionState.Idle(CommunalScenes.Blank) runCurrent() verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse() } @Test fun switchingToShadeWithBypassEnabledWillShowNotifications() { setDozeToZeroWithBypassWillFullyHideNotifications() Loading Loading
packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +9 −4 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn /** Encapsulates business-logic related to communal mode. */ @OptIn(ExperimentalCoroutinesApi::class) Loading Loading @@ -239,10 +240,14 @@ constructor( * This will not be true while transitioning to the hub and will turn false immediately when a * swipe to exit the hub starts. */ val isIdleOnCommunal: Flow<Boolean> = communalRepository.transitionState.map { it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal } val isIdleOnCommunal: StateFlow<Boolean> = communalRepository.transitionState .map { it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = false, ) /** * Flow that emits a boolean if any portion of the communal UI is visible at all. Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +45 −5 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ import androidx.core.animation.ObjectAnimator import com.android.app.animation.Interpolators import com.android.app.animation.InterpolatorsAndroidX import com.android.systemui.Dumpable import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionChangeEvent Loading @@ -47,11 +49,14 @@ import java.io.PrintWriter import javax.inject.Inject import kotlin.math.max import kotlin.math.min import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @SysUISingleton class NotificationWakeUpCoordinator @Inject constructor( @Application applicationScope: CoroutineScope, dumpManager: DumpManager, private val mHeadsUpManager: HeadsUpManager, private val statusBarStateController: StatusBarStateController, Loading @@ -60,6 +65,7 @@ constructor( private val screenOffAnimationController: ScreenOffAnimationController, private val logger: NotificationWakeUpCoordinatorLogger, private val notifsKeyguardInteractor: NotificationsKeyguardInteractor, private val communalInteractor: CommunalInteractor, ) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, Loading Loading @@ -201,6 +207,13 @@ constructor( } } ) applicationScope.launch { communalInteractor.isIdleOnCommunal.collect { if (!overrideDozeAmountIfCommunalShowing()) { maybeClearHardDozeAmountOverrideHidingNotifs() } } } } fun setStackScroller(stackScrollerController: NotificationStackScrollLayoutController) { Loading Loading @@ -302,6 +315,10 @@ constructor( return } if (overrideDozeAmountIfCommunalShowing()) { return } if (clearHardDozeAmountOverride()) { return } Loading @@ -311,10 +328,13 @@ constructor( private fun setHardDozeAmountOverride(dozing: Boolean, source: String) { logger.logSetDozeAmountOverride(dozing = dozing, source = source) val previousOverride = hardDozeAmountOverride hardDozeAmountOverride = if (dozing) 1f else 0f hardDozeAmountOverrideSource = source if (previousOverride != hardDozeAmountOverride) { updateDozeAmount() } } private fun clearHardDozeAmountOverride(): Boolean { if (hardDozeAmountOverride == null) return false Loading Loading @@ -434,6 +454,11 @@ constructor( return } if (overrideDozeAmountIfCommunalShowing()) { this.state = newState return } maybeClearHardDozeAmountOverrideHidingNotifs() this.state = newState Loading Loading @@ -471,6 +496,18 @@ constructor( return false } private fun overrideDozeAmountIfCommunalShowing(): Boolean { if (communalInteractor.isIdleOnCommunal.value) { if (statusBarStateController.state == StatusBarState.KEYGUARD) { setHardDozeAmountOverride(dozing = true, source = "Override: communal (keyguard)") } else { setHardDozeAmountOverride(dozing = false, source = "Override: communal (shade)") } return true } return false } /** * If the last [setDozeAmount] call was an override to hide notifications, then this call will * check for the set of states that may have caused that override, and if none of them still Loading @@ -483,20 +520,23 @@ constructor( val onKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD val dozing = statusBarStateController.isDozing val bypass = bypassController.bypassEnabled val idleOnCommunal = communalInteractor.isIdleOnCommunal.value val animating = screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard() // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff] and // [overrideDozeAmountIfBypass] based on 'animating' and 'bypass' respectively, so only // clear the override if both those conditions are cleared. But also require either // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff], // [overrideDozeAmountIfBypass] and [overrideDozeAmountIfCommunalShowing] based on // 'animating', 'bypass' and 'idleOnCommunal' respectively, so only clear the override // if all of those conditions are cleared. But also require either // !dozing or !onKeyguard because those conditions should indicate that we intend // notifications to be visible, and thus it is safe to unhide them. val willRemove = (!onKeyguard || !dozing) && !bypass && !animating val willRemove = (!onKeyguard || !dozing) && !bypass && !animating && !idleOnCommunal logger.logMaybeClearHardDozeAmountOverrideHidingNotifs( willRemove = willRemove, onKeyguard = onKeyguard, dozing = dozing, bypass = bypass, animating = animating, idleOnCommunal = idleOnCommunal, ) if (willRemove) { clearHardDozeAmountOverride() Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt +2 −1 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) { onKeyguard: Boolean, dozing: Boolean, bypass: Boolean, idleOnCommunal: Boolean, animating: Boolean, ) { buffer.log( Loading @@ -103,7 +104,7 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) { { str1 = "willRemove=$willRemove onKeyguard=$onKeyguard dozing=$dozing" + " bypass=$bypass animating=$animating" " bypass=$bypass animating=$animating idleOnCommunal=$idleOnCommunal" }, { "maybeClearHardDozeAmountOverrideHidingNotifs() $str1" } ) Loading
packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -604,6 +604,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { new NotificationsKeyguardInteractor(notifsKeyguardViewStateRepository); NotificationWakeUpCoordinator coordinator = new NotificationWakeUpCoordinator( mKosmos.getTestScope().getBackgroundScope(), mDumpManager, mock(HeadsUpManager.class), new StatusBarStateControllerImpl( Loading @@ -618,7 +619,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mDozeParameters, mScreenOffAnimationController, new NotificationWakeUpCoordinatorLogger(logcatLogBuffer()), notifsKeyguardInteractor); notifsKeyguardInteractor, mKosmos.getCommunalInteractor()); mConfigurationController = new ConfigurationControllerImpl(mContext); PulseExpansionHandler expansionHandler = new PulseExpansionHandler( mContext, Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt +49 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ package com.android.systemui.statusbar.notification import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.communal.data.repository.communalRepository import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dump.DumpManager import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeViewController.Companion.WAKEUP_ANIMATION_DELAY_MS Loading @@ -34,11 +39,16 @@ import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.testKosmos import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -49,6 +59,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidTestingRunner::class) @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) Loading @@ -56,7 +67,8 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { @get:Rule val animatorTestRule = AnimatorTestRule(this) private val kosmos = Kosmos() private val kosmos = testKosmos() private val testScope = kosmos.testScope private val dumpManager: DumpManager = mock() private val headsUpManager: HeadsUpManager = mock() Loading Loading @@ -97,6 +109,7 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { whenever(statusBarStateController.state).then { statusBarState } notificationWakeUpCoordinator = NotificationWakeUpCoordinator( kosmos.applicationCoroutineScope, dumpManager, headsUpManager, statusBarStateController, Loading @@ -105,6 +118,7 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { screenOffAnimationController, logger, kosmos.notificationsKeyguardInteractor, kosmos.communalInteractor, ) statusBarStateCallback = withArgCaptor { verify(statusBarStateController).addCallback(capture()) Loading Loading @@ -160,6 +174,39 @@ class NotificationWakeUpCoordinatorTest : SysuiTestCase() { assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse() } @Test fun setDozeToZeroWhenCommunalShowingWillFullyHideNotifications() = testScope.runTest { val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(CommunalScenes.Communal) ) kosmos.communalRepository.setTransitionState(transitionState) runCurrent() setDozeAmount(0f) verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue() } @Test fun closingCommunalWillShowNotifications() = testScope.runTest { val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(CommunalScenes.Communal) ) kosmos.communalRepository.setTransitionState(transitionState) runCurrent() setDozeAmount(0f) verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue() transitionState.value = ObservableTransitionState.Idle(CommunalScenes.Blank) runCurrent() verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f) assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse() } @Test fun switchingToShadeWithBypassEnabledWillShowNotifications() { setDozeToZeroWithBypassWillFullyHideNotifications() Loading