Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before Loading Loading @@ -181,6 +182,7 @@ class SceneContainerStartableTest : SysuiTestCase() { kosmos.headsUpNotificationRepository.activeHeadsUpRows.value = buildNotificationRows(isPinned = false) advanceTimeBy(50L) // account for HeadsUpNotificationInteractor debounce assertThat(isVisible).isFalse() } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt +59 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository Loading Loading @@ -278,6 +279,64 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() { assertThat(pinnedHeadsUpRows).containsExactly(rows[0]) } @Test fun isHeadsUpOrAnimatingAway_falseOnStart() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isFalse() } @Test fun isHeadsUpOrAnimatingAway_hasPinnedRows() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) // WHEN a row is pinned headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true)) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isTrue() } @Test fun isHeadsUpOrAnimatingAway_headsUpAnimatingAway() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) // WHEN the last row is animating away headsUpRepository.setHeadsUpAnimatingAway(true) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isTrue() } @Test fun isHeadsUpOrAnimatingAway_headsUpAnimatingAwayDebounced() = testScope.runTest { val values by collectValues(underTest.isHeadsUpOrAnimatingAway) // GIVEN a row is pinned headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true)) runCurrent() assertThat(values.size).isEqualTo(2) assertThat(values.first()).isFalse() // initial value assertThat(values.last()).isTrue() // WHEN the last row is removed headsUpRepository.setNotifications(emptyList()) runCurrent() // AND starts to animate away headsUpRepository.setHeadsUpAnimatingAway(true) runCurrent() // THEN isHeadsUpOrAnimatingAway remained true assertThat(values.size).isEqualTo(2) assertThat(values.last()).isTrue() } @Test fun showHeadsUpStatusBar_true() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt +20 −5 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ @file:OptIn(ExperimentalCoroutinesApi::class) @file:OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) package com.android.systemui.statusbar.notification.domain.interactor Loading @@ -27,11 +27,15 @@ import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRep import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart class HeadsUpNotificationInteractor @Inject Loading Loading @@ -77,6 +81,17 @@ constructor( animatingAway -> hasPinnedRows || animatingAway } .debounce { isHeadsUpOrAnimatingAway -> if (isHeadsUpOrAnimatingAway) { 0 } else { // When the last pinned entry is removed from the [HeadsUpRepository], // there might be a delay before the View starts animating. 50L } } .onStart { emit(false) } // emit false, so we don't wait for the initial update .distinctUntilChanged() private val canShowHeadsUp: Flow<Boolean> = combine( Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before Loading Loading @@ -181,6 +182,7 @@ class SceneContainerStartableTest : SysuiTestCase() { kosmos.headsUpNotificationRepository.activeHeadsUpRows.value = buildNotificationRows(isPinned = false) advanceTimeBy(50L) // account for HeadsUpNotificationInteractor debounce assertThat(isVisible).isFalse() } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt +59 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository Loading Loading @@ -278,6 +279,64 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() { assertThat(pinnedHeadsUpRows).containsExactly(rows[0]) } @Test fun isHeadsUpOrAnimatingAway_falseOnStart() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isFalse() } @Test fun isHeadsUpOrAnimatingAway_hasPinnedRows() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) // WHEN a row is pinned headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true)) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isTrue() } @Test fun isHeadsUpOrAnimatingAway_headsUpAnimatingAway() = testScope.runTest { val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway) // WHEN the last row is animating away headsUpRepository.setHeadsUpAnimatingAway(true) runCurrent() assertThat(isHeadsUpOrAnimatingAway).isTrue() } @Test fun isHeadsUpOrAnimatingAway_headsUpAnimatingAwayDebounced() = testScope.runTest { val values by collectValues(underTest.isHeadsUpOrAnimatingAway) // GIVEN a row is pinned headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true)) runCurrent() assertThat(values.size).isEqualTo(2) assertThat(values.first()).isFalse() // initial value assertThat(values.last()).isTrue() // WHEN the last row is removed headsUpRepository.setNotifications(emptyList()) runCurrent() // AND starts to animate away headsUpRepository.setHeadsUpAnimatingAway(true) runCurrent() // THEN isHeadsUpOrAnimatingAway remained true assertThat(values.size).isEqualTo(2) assertThat(values.last()).isTrue() } @Test fun showHeadsUpStatusBar_true() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt +20 −5 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ @file:OptIn(ExperimentalCoroutinesApi::class) @file:OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) package com.android.systemui.statusbar.notification.domain.interactor Loading @@ -27,11 +27,15 @@ import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRep import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart class HeadsUpNotificationInteractor @Inject Loading Loading @@ -77,6 +81,17 @@ constructor( animatingAway -> hasPinnedRows || animatingAway } .debounce { isHeadsUpOrAnimatingAway -> if (isHeadsUpOrAnimatingAway) { 0 } else { // When the last pinned entry is removed from the [HeadsUpRepository], // there might be a delay before the View starts animating. 50L } } .onStart { emit(false) } // emit false, so we don't wait for the initial update .distinctUntilChanged() private val canShowHeadsUp: Flow<Boolean> = combine( Loading