Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt +11 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.wm.shell.bubbles.Bubbles import java.util.Optional Loading @@ -37,10 +38,12 @@ class NotificationIconsInteractor constructor( private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val bubbles: Optional<Bubbles>, private val headsUpNotificationIconInteractor: HeadsUpNotificationIconInteractor, private val keyguardViewStateRepository: NotificationsKeyguardViewStateRepository, ) { /** Returns a subset of all active notifications based on the supplied filtration parameters. */ fun filteredNotifSet( forceShowHeadsUp: Boolean = false, showAmbient: Boolean = true, showLowPriority: Boolean = true, showDismissed: Boolean = true, Loading @@ -49,18 +52,21 @@ constructor( ): Flow<Set<ActiveNotificationModel>> { return combine( activeNotificationsInteractor.topLevelRepresentativeNotifications, headsUpNotificationIconInteractor.isolatedNotification, keyguardViewStateRepository.areNotificationsFullyHidden, ) { notifications, notifsFullyHidden -> ) { notifications, isolatedNotifKey, notifsFullyHidden -> notifications .asSequence() .filter { model: ActiveNotificationModel -> shouldShowNotificationIcon( model = model, forceShowHeadsUp = forceShowHeadsUp, showAmbient = showAmbient, showLowPriority = showLowPriority, showDismissed = showDismissed, showRepliedMessages = showRepliedMessages, showPulsing = showPulsing, isolatedNotifKey = isolatedNotifKey, notifsFullyHidden = notifsFullyHidden, ) } Loading @@ -70,14 +76,17 @@ constructor( private fun shouldShowNotificationIcon( model: ActiveNotificationModel, forceShowHeadsUp: Boolean, showAmbient: Boolean, showLowPriority: Boolean, showDismissed: Boolean, showRepliedMessages: Boolean, showPulsing: Boolean, isolatedNotifKey: String?, notifsFullyHidden: Boolean, ): Boolean { return when { forceShowHeadsUp && model.key == isolatedNotifKey -> true !showAmbient && model.isAmbient -> false !showLowPriority && model.isSilent -> false !showDismissed && model.isRowDismissed -> false Loading Loading @@ -118,6 +127,7 @@ constructor( val statusBarNotifs: Flow<Set<ActiveNotificationModel>> = settingsRepository.showSilentStatusIcons.flatMapLatest { showSilentIcons -> iconsInteractor.filteredNotifSet( forceShowHeadsUp = true, showAmbient = false, showLowPriority = showSilentIcons, showDismissed = false, Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ constructor( iconsViewData.visibleIcons.firstOrNull { it.notifKey == isolatedNotif } } } .pairwise(initialValue = null) .distinctUntilChanged() .pairwise(initialValue = null) .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion -> val animate = when { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.notification.data.model.activeNotification import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.shared.byIsAmbient import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply import com.android.systemui.statusbar.notification.shared.byIsPulsing Loading Loading @@ -264,6 +265,7 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() { interface TestComponent : SysUITestComponent<StatusBarNotificationIconsInteractor> { val activeNotificationListRepository: ActiveNotificationListRepository val headsUpIconsInteractor: HeadsUpNotificationIconInteractor val keyguardViewStateRepository: FakeNotificationsKeyguardViewStateRepository val notificationListenerSettingsRepository: NotificationListenerSettingsRepository Loading Loading @@ -336,6 +338,14 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() { .comparingElementsUsing(byIsLastMessageFromReply) .doesNotContain(true) } @Test fun filteredEntrySet_includesIsolatedIcon() = testComponent.runTest { val filteredSet by collectLastValue(underTest.statusBarNotifs) headsUpIconsInteractor.setIsolatedIconNotificationKey("notif5") assertThat(filteredSet).comparingElementsUsing(byKey).contains("notif5") } } private val testIcons = Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,31 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() { .build() runCurrent() assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1") } @Test fun isolatedIcon_lastMessageIsFromReply_notNull() = testComponent.runTest { val icon: Icon = mock() headsUpViewStateRepository.isolatedNotification.value = "notif1" activeNotificationsRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "notif1", groupKey = "group", statusBarIcon = icon, isLastMessageFromReply = true, ) ) } .build() val isolatedIcon by collectLastValue(underTest.isolatedIcon) runCurrent() assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1") } } packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.statusbar.data.repository.notificationListenerSettingsRepository import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor import com.android.wm.shell.bubbles.bubblesOptional import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -43,6 +44,7 @@ val Kosmos.notificationIconsInteractor by Fixture { NotificationIconsInteractor( activeNotificationsInteractor = activeNotificationsInteractor, bubbles = bubblesOptional, headsUpNotificationIconInteractor = headsUpNotificationIconInteractor, keyguardViewStateRepository = notificationsKeyguardViewStateRepository, ) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt +11 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.wm.shell.bubbles.Bubbles import java.util.Optional Loading @@ -37,10 +38,12 @@ class NotificationIconsInteractor constructor( private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val bubbles: Optional<Bubbles>, private val headsUpNotificationIconInteractor: HeadsUpNotificationIconInteractor, private val keyguardViewStateRepository: NotificationsKeyguardViewStateRepository, ) { /** Returns a subset of all active notifications based on the supplied filtration parameters. */ fun filteredNotifSet( forceShowHeadsUp: Boolean = false, showAmbient: Boolean = true, showLowPriority: Boolean = true, showDismissed: Boolean = true, Loading @@ -49,18 +52,21 @@ constructor( ): Flow<Set<ActiveNotificationModel>> { return combine( activeNotificationsInteractor.topLevelRepresentativeNotifications, headsUpNotificationIconInteractor.isolatedNotification, keyguardViewStateRepository.areNotificationsFullyHidden, ) { notifications, notifsFullyHidden -> ) { notifications, isolatedNotifKey, notifsFullyHidden -> notifications .asSequence() .filter { model: ActiveNotificationModel -> shouldShowNotificationIcon( model = model, forceShowHeadsUp = forceShowHeadsUp, showAmbient = showAmbient, showLowPriority = showLowPriority, showDismissed = showDismissed, showRepliedMessages = showRepliedMessages, showPulsing = showPulsing, isolatedNotifKey = isolatedNotifKey, notifsFullyHidden = notifsFullyHidden, ) } Loading @@ -70,14 +76,17 @@ constructor( private fun shouldShowNotificationIcon( model: ActiveNotificationModel, forceShowHeadsUp: Boolean, showAmbient: Boolean, showLowPriority: Boolean, showDismissed: Boolean, showRepliedMessages: Boolean, showPulsing: Boolean, isolatedNotifKey: String?, notifsFullyHidden: Boolean, ): Boolean { return when { forceShowHeadsUp && model.key == isolatedNotifKey -> true !showAmbient && model.isAmbient -> false !showLowPriority && model.isSilent -> false !showDismissed && model.isRowDismissed -> false Loading Loading @@ -118,6 +127,7 @@ constructor( val statusBarNotifs: Flow<Set<ActiveNotificationModel>> = settingsRepository.showSilentStatusIcons.flatMapLatest { showSilentIcons -> iconsInteractor.filteredNotifSet( forceShowHeadsUp = true, showAmbient = false, showLowPriority = showSilentIcons, showDismissed = false, Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ constructor( iconsViewData.visibleIcons.firstOrNull { it.notifKey == isolatedNotif } } } .pairwise(initialValue = null) .distinctUntilChanged() .pairwise(initialValue = null) .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion -> val animate = when { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.notification.data.model.activeNotification import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.shared.byIsAmbient import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply import com.android.systemui.statusbar.notification.shared.byIsPulsing Loading Loading @@ -264,6 +265,7 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() { interface TestComponent : SysUITestComponent<StatusBarNotificationIconsInteractor> { val activeNotificationListRepository: ActiveNotificationListRepository val headsUpIconsInteractor: HeadsUpNotificationIconInteractor val keyguardViewStateRepository: FakeNotificationsKeyguardViewStateRepository val notificationListenerSettingsRepository: NotificationListenerSettingsRepository Loading Loading @@ -336,6 +338,14 @@ class StatusBarNotificationIconsInteractorTest : SysuiTestCase() { .comparingElementsUsing(byIsLastMessageFromReply) .doesNotContain(true) } @Test fun filteredEntrySet_includesIsolatedIcon() = testComponent.runTest { val filteredSet by collectLastValue(underTest.statusBarNotifs) headsUpIconsInteractor.setIsolatedIconNotificationKey("notif5") assertThat(filteredSet).comparingElementsUsing(byKey).contains("notif5") } } private val testIcons = Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,31 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() { .build() runCurrent() assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1") } @Test fun isolatedIcon_lastMessageIsFromReply_notNull() = testComponent.runTest { val icon: Icon = mock() headsUpViewStateRepository.isolatedNotification.value = "notif1" activeNotificationsRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "notif1", groupKey = "group", statusBarIcon = icon, isLastMessageFromReply = true, ) ) } .build() val isolatedIcon by collectLastValue(underTest.isolatedIcon) runCurrent() assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1") } }
packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.statusbar.data.repository.notificationListenerSettingsRepository import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor import com.android.wm.shell.bubbles.bubblesOptional import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -43,6 +44,7 @@ val Kosmos.notificationIconsInteractor by Fixture { NotificationIconsInteractor( activeNotificationsInteractor = activeNotificationsInteractor, bubbles = bubblesOptional, headsUpNotificationIconInteractor = headsUpNotificationIconInteractor, keyguardViewStateRepository = notificationsKeyguardViewStateRepository, ) }