summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt123
5 files changed, 166 insertions, 24 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
index f40bfbdeb54b..8d678ef00b4a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
@@ -506,7 +506,7 @@ class NotificationListViewModelTest(flags: FlagsParameterization) : SysuiTestCas
@EnableSceneContainer
fun pinnedHeadsUpRows_filtersForPinnedItems() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// WHEN there are no pinned rows
val rows =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index aa203d7c0aa9..e25127e3e0d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -39,10 +39,10 @@ class HeadsUpNotificationInteractor
@Inject
constructor(
private val headsUpRepository: HeadsUpRepository,
- private val faceAuthInteractor: DeviceEntryFaceAuthInteractor,
- private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
- private val notificationsKeyguardInteractor: NotificationsKeyguardInteractor,
- private val shadeInteractor: ShadeInteractor,
+ faceAuthInteractor: DeviceEntryFaceAuthInteractor,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ notificationsKeyguardInteractor: NotificationsKeyguardInteractor,
+ shadeInteractor: ShadeInteractor,
) {
/** The top-ranked heads up row, regardless of pinned state */
@@ -56,8 +56,7 @@ constructor(
}
.distinctUntilChanged()
- /** Set of currently pinned top-level heads up rows to be displayed. */
- val pinnedHeadsUpRows: Flow<Set<HeadsUpRowKey>> by lazy {
+ private val activeHeadsUpRows: Flow<Set<Pair<HeadsUpRowKey, Boolean>>> by lazy {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
flowOf(emptySet())
} else {
@@ -67,9 +66,7 @@ constructor(
repositories.map { repo ->
repo.isPinned.map { isPinned -> repo to isPinned }
}
- combine(toCombine) { pairs ->
- pairs.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet()
- }
+ combine(toCombine) { pairs -> pairs.toSet() }
} else {
// if the set is empty, there are no flows to combine
flowOf(emptySet())
@@ -78,6 +75,26 @@ constructor(
}
}
+ /** Set of currently active top-level heads up rows to be displayed. */
+ val activeHeadsUpRowKeys: Flow<Set<HeadsUpRowKey>> by lazy {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
+ flowOf(emptySet())
+ } else {
+ activeHeadsUpRows.map { it.map { (repo, _) -> repo }.toSet() }
+ }
+ }
+
+ /** Set of currently pinned top-level heads up rows to be displayed. */
+ val pinnedHeadsUpRowKeys: Flow<Set<HeadsUpRowKey>> by lazy {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
+ flowOf(emptySet())
+ } else {
+ activeHeadsUpRows.map {
+ it.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet()
+ }
+ }
+ }
+
/** Are there any pinned heads up rows to display? */
val hasPinnedRows: Flow<Boolean> by lazy {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
index 935e2a37b13c..38390e7bdb39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
@@ -356,11 +356,23 @@ constructor(
}
}
- val pinnedHeadsUpRows: Flow<Set<HeadsUpRowKey>> by lazy {
+ val activeHeadsUpRowKeys: Flow<Set<HeadsUpRowKey>> by lazy {
if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
flowOf(emptySet())
} else {
- headsUpNotificationInteractor.pinnedHeadsUpRows.dumpWhileCollecting("pinnedHeadsUpRows")
+ headsUpNotificationInteractor.activeHeadsUpRowKeys.dumpWhileCollecting(
+ "pinnedHeadsUpRows"
+ )
+ }
+ }
+
+ val pinnedHeadsUpRowKeys: Flow<Set<HeadsUpRowKey>> by lazy {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
+ flowOf(emptySet())
+ } else {
+ headsUpNotificationInteractor.pinnedHeadsUpRowKeys.dumpWhileCollecting(
+ "pinnedHeadsUpRows"
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
index dc15970b318b..e2e5c5970ff5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
@@ -26,6 +26,7 @@ import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
class HeadsUpNotificationViewBinder
@@ -35,18 +36,21 @@ constructor(private val viewModel: NotificationListViewModel) {
coroutineScope {
launch {
var previousKeys = emptySet<HeadsUpRowKey>()
- viewModel.pinnedHeadsUpRows
+ combine(viewModel.pinnedHeadsUpRowKeys, viewModel.activeHeadsUpRowKeys, ::Pair)
.sample(viewModel.headsUpAnimationsEnabled, ::Pair)
.collect { (newKeys, animationsEnabled) ->
- val added = newKeys - previousKeys
- val removed = previousKeys - newKeys
- previousKeys = newKeys
+ val pinned = newKeys.first
+ val all = newKeys.second
+ val added = all.union(pinned) - previousKeys
+ val removed = previousKeys - pinned
+ previousKeys = pinned
+ Pair(added, removed)
if (animationsEnabled) {
added.forEach { key ->
parentView.generateHeadsUpAnimation(
obtainView(key),
- /* isHeadsUp = */ true
+ /* isHeadsUp = */ true,
)
}
removed.forEach { key ->
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
index 7d5278ed1601..eb1bcc7fe147 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
@@ -146,9 +146,17 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun activeRows_noRows_isEmpty() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+
+ assertThat(activeHeadsUpRows).isEmpty()
+ }
+
+ @Test
fun pinnedRows_noRows_isEmpty() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
assertThat(pinnedHeadsUpRows).isEmpty()
}
@@ -156,7 +164,7 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
@Test
fun pinnedRows_noPinnedRows_isEmpty() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// WHEN no rows are pinned
headsUpRepository.setNotifications(
fakeHeadsUpRowRepository("key 0"),
@@ -170,9 +178,27 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun activeRows_noPinnedRows_containsAllRows() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+ // WHEN no rows are pinned
+ val rows =
+ arrayListOf(
+ fakeHeadsUpRowRepository("key 0"),
+ fakeHeadsUpRowRepository("key 1"),
+ fakeHeadsUpRowRepository("key 2"),
+ )
+ headsUpRepository.setNotifications(rows)
+ runCurrent()
+
+ // THEN all rows are present
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+ }
+
+ @Test
fun pinnedRows_hasPinnedRows_containsPinnedRows() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// WHEN some rows are pinned
val rows =
arrayListOf(
@@ -188,9 +214,27 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun pinnedRows_hasPinnedRows_containsAllRows() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+ // WHEN no rows are pinned
+ val rows =
+ arrayListOf(
+ fakeHeadsUpRowRepository("key 0", isPinned = true),
+ fakeHeadsUpRowRepository("key 1", isPinned = true),
+ fakeHeadsUpRowRepository("key 2"),
+ )
+ headsUpRepository.setNotifications(rows)
+ runCurrent()
+
+ // THEN all rows are present
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+ }
+
+ @Test
fun pinnedRows_rowGetsPinned_containsPinnedRows() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// GIVEN some rows are pinned
val rows =
arrayListOf(
@@ -210,9 +254,34 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun activeRows_rowGetsPinned_containsAllRows() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+ // GIVEN some rows are pinned
+ val rows =
+ arrayListOf(
+ fakeHeadsUpRowRepository("key 0", isPinned = true),
+ fakeHeadsUpRowRepository("key 1", isPinned = true),
+ fakeHeadsUpRowRepository("key 2"),
+ )
+ headsUpRepository.setNotifications(rows)
+ runCurrent()
+
+ // THEN all rows are present
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+
+ // WHEN all rows gets pinned
+ rows[2].isPinned.value = true
+ runCurrent()
+
+ // THEN no change
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+ }
+
+ @Test
fun pinnedRows_allRowsPinned_containsAllRows() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// WHEN all rows are pinned
val rows =
arrayListOf(
@@ -228,9 +297,27 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun activeRows_allRowsPinned_containsAllRows() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+ // WHEN all rows are pinned
+ val rows =
+ arrayListOf(
+ fakeHeadsUpRowRepository("key 0", isPinned = true),
+ fakeHeadsUpRowRepository("key 1", isPinned = true),
+ fakeHeadsUpRowRepository("key 2", isPinned = true),
+ )
+ headsUpRepository.setNotifications(rows)
+ runCurrent()
+
+ // THEN no rows are filtered
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+ }
+
+ @Test
fun pinnedRows_rowGetsUnPinned_containsPinnedRows() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
// GIVEN all rows are pinned
val rows =
arrayListOf(
@@ -250,9 +337,31 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() {
}
@Test
+ fun activeRows_rowGetsUnPinned_containsAllRows() =
+ testScope.runTest {
+ val activeHeadsUpRows by collectLastValue(underTest.activeHeadsUpRowKeys)
+ // GIVEN all rows are pinned
+ val rows =
+ arrayListOf(
+ fakeHeadsUpRowRepository("key 0", isPinned = true),
+ fakeHeadsUpRowRepository("key 1", isPinned = true),
+ fakeHeadsUpRowRepository("key 2", isPinned = true),
+ )
+ headsUpRepository.setNotifications(rows)
+ runCurrent()
+
+ // WHEN a row gets unpinned
+ rows[0].isPinned.value = false
+ runCurrent()
+
+ // THEN all rows are still present
+ assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
+ }
+
+ @Test
fun pinnedRows_rowGetsPinnedAndUnPinned_containsTheSameInstance() =
testScope.runTest {
- val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRows)
+ val pinnedHeadsUpRows by collectLastValue(underTest.pinnedHeadsUpRowKeys)
val rows =
arrayListOf(