Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -32,8 +32,12 @@ import com.android.systemui.statusbar.notification.data.repository.activeNotific 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.promoted.domain.interactor.aodPromotedNotificationInteractor import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style.Base import com.android.systemui.statusbar.notification.shared.byIsAmbient import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply import com.android.systemui.statusbar.notification.shared.byIsPromoted import com.android.systemui.statusbar.notification.shared.byIsPulsing import com.android.systemui.statusbar.notification.shared.byIsRowDismissed import com.android.systemui.statusbar.notification.shared.byIsSilent Loading @@ -58,12 +62,14 @@ class NotificationIconsInteractorTest : SysuiTestCase() { private val testScope = kosmos.testScope private val activeNotificationListRepository = kosmos.activeNotificationListRepository private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor private val aodPromotedNotificationInteractor = kosmos.aodPromotedNotificationInteractor private val underTest = NotificationIconsInteractor( kosmos.activeNotificationsInteractor, kosmos.bubblesOptional, kosmos.headsUpNotificationIconInteractor, kosmos.aodPromotedNotificationInteractor, kosmos.notificationsKeyguardViewStateRepository, ) Loading Loading @@ -141,6 +147,22 @@ class NotificationIconsInteractorTest : SysuiTestCase() { notificationsKeyguardInteractor.setNotificationsFullyHidden(true) assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true) } @Test fun filteredEntrySet_showAodPromoted() { testScope.runTest { val filteredSet by collectLastValue(underTest.filteredNotifSet(showAodPromoted = true)) assertThat(filteredSet).comparingElementsUsing(byIsPromoted).contains(true) } } @Test fun filteredEntrySet_noAodPromoted() { testScope.runTest { val filteredSet by collectLastValue(underTest.filteredNotifSet(showAodPromoted = false)) assertThat(filteredSet).comparingElementsUsing(byIsPromoted).doesNotContain(true) } } } @SmallTest Loading Loading @@ -326,4 +348,12 @@ private val testIcons = activeNotificationModel(key = "notif5", isLastMessageFromReply = true), activeNotificationModel(key = "notif6", isSuppressedFromStatusBar = true), activeNotificationModel(key = "notif7", isPulsing = true), activeNotificationModel(key = "notif8", promotedContent = promotedContent("notif8", Base)), ) private fun promotedContent( key: String, style: PromotedNotificationContentModel.Style, ): PromotedNotificationContentModel { return PromotedNotificationContentModel.Builder(key).apply { this.style = style }.build() } packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt +6 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,12 @@ val byIsRowDismissed: Correspondence<ActiveNotificationModel, Boolean> = val byIsLastMessageFromReply: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming( { it?.isLastMessageFromReply }, "has an isLastMessageFromReply value of" "has an isLastMessageFromReply value of", ) val byIsPulsing: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming({ it?.isPulsing }, "has an isPulsing value of") val byIsPromoted: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming( { it?.promotedContent != null }, "has (or doesn't have) a promoted content model", ) packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt +22 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.statusbar.data.repository.NotificationListenerSettin 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.promoted.domain.interactor.AODPromotedNotificationInteractor import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.wm.shell.bubbles.Bubbles import java.util.Optional Loading @@ -30,6 +31,7 @@ import kotlin.jvm.optionals.getOrNull import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn /** Domain logic related to notification icons. */ Loading @@ -39,8 +41,21 @@ constructor( private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val bubbles: Optional<Bubbles>, private val headsUpNotificationIconInteractor: HeadsUpNotificationIconInteractor, private val aodPromotedNotificationInteractor: AODPromotedNotificationInteractor, private val keyguardViewStateRepository: NotificationsKeyguardViewStateRepository, ) { private val aodPromotedKeyToHide: Flow<String?> = combine( aodPromotedNotificationInteractor.content, aodPromotedNotificationInteractor.isPresent, ) { content, isPresent -> when { !isPresent -> null content == null -> null else -> content.identity.key } } /** Returns a subset of all active notifications based on the supplied filtration parameters. */ fun filteredNotifSet( forceShowHeadsUp: Boolean = false, Loading @@ -49,12 +64,14 @@ constructor( showDismissed: Boolean = true, showRepliedMessages: Boolean = true, showPulsing: Boolean = true, showAodPromoted: Boolean = true, ): Flow<Set<ActiveNotificationModel>> { return combine( activeNotificationsInteractor.topLevelRepresentativeNotifications, headsUpNotificationIconInteractor.isolatedNotification, if (showAodPromoted) flowOf(null) else aodPromotedKeyToHide, keyguardViewStateRepository.areNotificationsFullyHidden, ) { notifications, isolatedNotifKey, notifsFullyHidden -> ) { notifications, isolatedNotifKey, aodPromotedKeyToHide, notifsFullyHidden -> notifications .asSequence() .filter { model: ActiveNotificationModel -> Loading @@ -67,6 +84,7 @@ constructor( showRepliedMessages = showRepliedMessages, showPulsing = showPulsing, isolatedNotifKey = isolatedNotifKey, aodPromotedKeyToHide = aodPromotedKeyToHide, notifsFullyHidden = notifsFullyHidden, ) } Loading @@ -83,6 +101,7 @@ constructor( showRepliedMessages: Boolean, showPulsing: Boolean, isolatedNotifKey: String?, aodPromotedKeyToHide: String?, notifsFullyHidden: Boolean, ): Boolean { return when { Loading @@ -93,6 +112,7 @@ constructor( !showRepliedMessages && model.isLastMessageFromReply -> false !showAmbient && model.isSuppressedFromStatusBar -> false !showPulsing && model.isPulsing && !notifsFullyHidden -> false model.key == aodPromotedKeyToHide -> false bubbles.getOrNull()?.isBubbleExpanded(model.key) == true -> false else -> true } Loading @@ -115,6 +135,7 @@ constructor( showDismissed = false, showRepliedMessages = false, showPulsing = !isBypassEnabled, showAodPromoted = false, ) } .flowOn(bgContext) Loading 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.statusbar.data.repository.notificationListenerSettin 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.promoted.domain.interactor.aodPromotedNotificationInteractor import com.android.wm.shell.bubbles.bubblesOptional val Kosmos.alwaysOnDisplayNotificationIconsInteractor by Fixture { Loading @@ -47,6 +48,7 @@ val Kosmos.notificationIconsInteractor by Fixture { activeNotificationsInteractor = activeNotificationsInteractor, bubbles = bubblesOptional, headsUpNotificationIconInteractor = headsUpNotificationIconInteractor, aodPromotedNotificationInteractor = aodPromotedNotificationInteractor, keyguardViewStateRepository = notificationsKeyguardViewStateRepository, ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -32,8 +32,12 @@ import com.android.systemui.statusbar.notification.data.repository.activeNotific 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.promoted.domain.interactor.aodPromotedNotificationInteractor import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style.Base import com.android.systemui.statusbar.notification.shared.byIsAmbient import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply import com.android.systemui.statusbar.notification.shared.byIsPromoted import com.android.systemui.statusbar.notification.shared.byIsPulsing import com.android.systemui.statusbar.notification.shared.byIsRowDismissed import com.android.systemui.statusbar.notification.shared.byIsSilent Loading @@ -58,12 +62,14 @@ class NotificationIconsInteractorTest : SysuiTestCase() { private val testScope = kosmos.testScope private val activeNotificationListRepository = kosmos.activeNotificationListRepository private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor private val aodPromotedNotificationInteractor = kosmos.aodPromotedNotificationInteractor private val underTest = NotificationIconsInteractor( kosmos.activeNotificationsInteractor, kosmos.bubblesOptional, kosmos.headsUpNotificationIconInteractor, kosmos.aodPromotedNotificationInteractor, kosmos.notificationsKeyguardViewStateRepository, ) Loading Loading @@ -141,6 +147,22 @@ class NotificationIconsInteractorTest : SysuiTestCase() { notificationsKeyguardInteractor.setNotificationsFullyHidden(true) assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true) } @Test fun filteredEntrySet_showAodPromoted() { testScope.runTest { val filteredSet by collectLastValue(underTest.filteredNotifSet(showAodPromoted = true)) assertThat(filteredSet).comparingElementsUsing(byIsPromoted).contains(true) } } @Test fun filteredEntrySet_noAodPromoted() { testScope.runTest { val filteredSet by collectLastValue(underTest.filteredNotifSet(showAodPromoted = false)) assertThat(filteredSet).comparingElementsUsing(byIsPromoted).doesNotContain(true) } } } @SmallTest Loading Loading @@ -326,4 +348,12 @@ private val testIcons = activeNotificationModel(key = "notif5", isLastMessageFromReply = true), activeNotificationModel(key = "notif6", isSuppressedFromStatusBar = true), activeNotificationModel(key = "notif7", isPulsing = true), activeNotificationModel(key = "notif8", promotedContent = promotedContent("notif8", Base)), ) private fun promotedContent( key: String, style: PromotedNotificationContentModel.Style, ): PromotedNotificationContentModel { return PromotedNotificationContentModel.Builder(key).apply { this.style = style }.build() }
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt +6 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,12 @@ val byIsRowDismissed: Correspondence<ActiveNotificationModel, Boolean> = val byIsLastMessageFromReply: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming( { it?.isLastMessageFromReply }, "has an isLastMessageFromReply value of" "has an isLastMessageFromReply value of", ) val byIsPulsing: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming({ it?.isPulsing }, "has an isPulsing value of") val byIsPromoted: Correspondence<ActiveNotificationModel, Boolean> = Correspondence.transforming( { it?.promotedContent != null }, "has (or doesn't have) a promoted content model", )
packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt +22 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.statusbar.data.repository.NotificationListenerSettin 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.promoted.domain.interactor.AODPromotedNotificationInteractor import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.wm.shell.bubbles.Bubbles import java.util.Optional Loading @@ -30,6 +31,7 @@ import kotlin.jvm.optionals.getOrNull import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn /** Domain logic related to notification icons. */ Loading @@ -39,8 +41,21 @@ constructor( private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val bubbles: Optional<Bubbles>, private val headsUpNotificationIconInteractor: HeadsUpNotificationIconInteractor, private val aodPromotedNotificationInteractor: AODPromotedNotificationInteractor, private val keyguardViewStateRepository: NotificationsKeyguardViewStateRepository, ) { private val aodPromotedKeyToHide: Flow<String?> = combine( aodPromotedNotificationInteractor.content, aodPromotedNotificationInteractor.isPresent, ) { content, isPresent -> when { !isPresent -> null content == null -> null else -> content.identity.key } } /** Returns a subset of all active notifications based on the supplied filtration parameters. */ fun filteredNotifSet( forceShowHeadsUp: Boolean = false, Loading @@ -49,12 +64,14 @@ constructor( showDismissed: Boolean = true, showRepliedMessages: Boolean = true, showPulsing: Boolean = true, showAodPromoted: Boolean = true, ): Flow<Set<ActiveNotificationModel>> { return combine( activeNotificationsInteractor.topLevelRepresentativeNotifications, headsUpNotificationIconInteractor.isolatedNotification, if (showAodPromoted) flowOf(null) else aodPromotedKeyToHide, keyguardViewStateRepository.areNotificationsFullyHidden, ) { notifications, isolatedNotifKey, notifsFullyHidden -> ) { notifications, isolatedNotifKey, aodPromotedKeyToHide, notifsFullyHidden -> notifications .asSequence() .filter { model: ActiveNotificationModel -> Loading @@ -67,6 +84,7 @@ constructor( showRepliedMessages = showRepliedMessages, showPulsing = showPulsing, isolatedNotifKey = isolatedNotifKey, aodPromotedKeyToHide = aodPromotedKeyToHide, notifsFullyHidden = notifsFullyHidden, ) } Loading @@ -83,6 +101,7 @@ constructor( showRepliedMessages: Boolean, showPulsing: Boolean, isolatedNotifKey: String?, aodPromotedKeyToHide: String?, notifsFullyHidden: Boolean, ): Boolean { return when { Loading @@ -93,6 +112,7 @@ constructor( !showRepliedMessages && model.isLastMessageFromReply -> false !showAmbient && model.isSuppressedFromStatusBar -> false !showPulsing && model.isPulsing && !notifsFullyHidden -> false model.key == aodPromotedKeyToHide -> false bubbles.getOrNull()?.isBubbleExpanded(model.key) == true -> false else -> true } Loading @@ -115,6 +135,7 @@ constructor( showDismissed = false, showRepliedMessages = false, showPulsing = !isBypassEnabled, showAodPromoted = false, ) } .flowOn(bgContext) Loading
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.statusbar.data.repository.notificationListenerSettin 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.promoted.domain.interactor.aodPromotedNotificationInteractor import com.android.wm.shell.bubbles.bubblesOptional val Kosmos.alwaysOnDisplayNotificationIconsInteractor by Fixture { Loading @@ -47,6 +48,7 @@ val Kosmos.notificationIconsInteractor by Fixture { activeNotificationsInteractor = activeNotificationsInteractor, bubbles = bubblesOptional, headsUpNotificationIconInteractor = headsUpNotificationIconInteractor, aodPromotedNotificationInteractor = aodPromotedNotificationInteractor, keyguardViewStateRepository = notificationsKeyguardViewStateRepository, ) }