diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt index 2d839704e0b73ad9c0a49a5a44b066457662397a..0c69a65b96af8ac046d0896ca95c679ab7ea57a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt @@ -37,8 +37,8 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider +import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider -import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.headsUpEvents import com.android.systemui.util.asIndenting @@ -85,7 +85,7 @@ constructor( @Application private val scope: CoroutineScope, private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider, private val secureSettings: SecureSettings, - private val notificationListInteractor: NotificationListInteractor, + private val seenNotificationsInteractor: SeenNotificationsInteractor, private val statusBarStateController: StatusBarStateController, ) : Coordinator, Dumpable { @@ -351,7 +351,7 @@ constructor( override fun onCleanup() { logger.logProviderHasFilteredOutSeenNotifs(hasFilteredAnyNotifs) - notificationListInteractor.setHasFilteredOutSeenNotifications(hasFilteredAnyNotifs) + seenNotificationsInteractor.setHasFilteredOutSeenNotifications(hasFilteredAnyNotifs) hasFilteredAnyNotifs = false } } @@ -389,7 +389,7 @@ constructor( with(pw.asIndenting()) { println( "notificationListInteractor.hasFilteredOutSeenNotifications.value=" + - notificationListInteractor.hasFilteredOutSeenNotifications.value + seenNotificationsInteractor.hasFilteredOutSeenNotifications.value ) println("unseen notifications:") indentIfPossible { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt index 4126c5eecba31909c5963a0c80010d05f8476289..5435fb5449cd81948d9ec7d71ff35fcbf05fe2fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt @@ -15,15 +15,8 @@ */ package com.android.systemui.statusbar.notification.data -import com.android.systemui.statusbar.notification.data.repository.NotificationStackRepositoryModule import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardStateRepositoryModule import dagger.Module -@Module( - includes = - [ - NotificationStackRepositoryModule::class, - NotificationsKeyguardStateRepositoryModule::class, - ] -) +@Module(includes = [NotificationsKeyguardStateRepositoryModule::class]) interface NotificationDataLayerModule diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationStackRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt similarity index 58% rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationStackRepository.kt rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt index c371f4fee59ec5326d75455fe04d423224a57ef9..8064f049c88e5722bf71f82eb3d3f3d359d53e93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationStackRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt @@ -16,40 +16,26 @@ package com.android.systemui.statusbar.notification.data.repository import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.notification.collection.ListEntry -import dagger.Binds -import dagger.Module +import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import javax.inject.Inject -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow /** - * Repository of notifications in the notification stack. + * Repository of "active" notifications in the notification list. * * This repository serves as the boundary between the * [com.android.systemui.statusbar.notification.collection.NotifPipeline] and the modern * notifications presentation codebase. */ -interface NotificationStackRepository { +@SysUISingleton +class ActiveNotificationListRepository @Inject constructor() { /** * Notifications actively presented to the user in the notification stack. * * @see com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener */ - val renderedEntries: Flow<List<ListEntry>> -} - -/** - * A mutable implementation of [NotificationStackRepository]. Like other "mutable" objects, the - * mutable type should only be exposed where necessary; most consumers should only have access to it - * from behind the immutable [NotificationStackRepository] interface. - */ -@SysUISingleton -class MutableNotificationStackRepository @Inject constructor() : NotificationStackRepository { - override val renderedEntries = MutableStateFlow(emptyList<ListEntry>()) -} + val activeNotifications = MutableStateFlow(emptyMap<String, ActiveNotificationModel>()) -@Module -interface NotificationStackRepositoryModule { - @Binds fun bindImpl(impl: MutableNotificationStackRepository): NotificationStackRepository + /** Are any already-seen notifications currently filtered out of the active list? */ + val hasFilteredOutSeenNotifications = MutableStateFlow(false) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt new file mode 100644 index 0000000000000000000000000000000000000000..bfec60bcd6db49e7303de191383c3f355dfd0cbf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.domain.interactor + +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class ActiveNotificationsInteractor +@Inject +constructor( + repository: ActiveNotificationListRepository, +) { + /** Notifications actively presented to the user in the notification stack, in order. */ + val notifications: Flow<Collection<ActiveNotificationModel>> = + repository.activeNotifications.map { it.values } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractor.kt similarity index 70% rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractor.kt index 02a667f9706d29b05edd87cfaed88d59bf702fd0..8079ce540e1b25f83102a6ab8f60326e9873b80f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractor.kt @@ -18,23 +18,16 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository -import com.android.systemui.statusbar.notification.collection.ListEntry -import com.android.systemui.statusbar.notification.data.repository.NotificationStackRepository import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -/** Interactor for notifications in general. */ +/** Interactor for notification alerting. */ @SysUISingleton -class NotificationsInteractor +class NotificationAlertsInteractor @Inject constructor( private val disableFlagsRepository: DisableFlagsRepository, - stackRepository: NotificationStackRepository, ) { /** Returns true if notification alerts are allowed. */ fun areNotificationAlertsEnabled(): Boolean = disableFlagsRepository.disableFlags.value.areNotificationAlertsEnabled() - - /** Notifications actively presented to the user in the notification stack. */ - val notifications: Flow<List<ListEntry>> = stackRepository.renderedEntries } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt index ea9b4e70c398e7e70fe9108696fd1ff6acb985be..c5396ddbe565a6c7a334aeac628463ff5f87eed7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt @@ -16,8 +16,10 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.statusbar.notification.collection.ListEntry -import com.android.systemui.statusbar.notification.data.repository.MutableNotificationStackRepository +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import javax.inject.Inject +import kotlinx.coroutines.flow.update /** * Logic for passing information from the @@ -27,15 +29,30 @@ import javax.inject.Inject class RenderNotificationListInteractor @Inject constructor( - private val repository: MutableNotificationStackRepository, + private val repository: ActiveNotificationListRepository, ) { /** * Sets the current list of rendered notification entries as displayed in the notification * stack. * - * @see com.android.systemui.statusbar.notification.data.repository.NotificationStackRepository.renderedEntries + * @see com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository.activeNotifications */ fun setRenderedList(entries: List<ListEntry>) { - repository.renderedEntries.value = entries.toList() + repository.activeNotifications.update { modelsByKey -> + entries.associateBy( + keySelector = { it.key }, + valueTransform = { it.toModel(modelsByKey[it.key]) } + ) + } + } + + private fun ListEntry.toModel(existing: ActiveNotificationModel?): ActiveNotificationModel { + val isCurrent = + when { + existing == null -> false + key == existing.key -> true + else -> false + } + return if (isCurrent) existing!! else ActiveNotificationModel(key = key) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt similarity index 67% rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt index 3fd68a8bdd7c3283bf9214a2d77c69d69a9eeb43..f3e122ce690b5ccdbcf928d3a02d63976698a192 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt @@ -14,25 +14,25 @@ * limitations under the License. */ -package com.android.systemui.statusbar.notification.stack.domain.interactor +package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import javax.inject.Inject import kotlinx.coroutines.flow.StateFlow /** Interactor for business logic associated with the notification stack. */ @SysUISingleton -class NotificationListInteractor +class SeenNotificationsInteractor @Inject constructor( - private val notificationListRepository: NotificationListRepository, + private val notificationListRepository: ActiveNotificationListRepository, ) { /** Are any already-seen notifications currently filtered out of the shade? */ - val hasFilteredOutSeenNotifications: StateFlow<Boolean> - get() = notificationListRepository.hasFilteredOutSeenNotifications + val hasFilteredOutSeenNotifications: StateFlow<Boolean> = + notificationListRepository.hasFilteredOutSeenNotifications fun setHasFilteredOutSeenNotifications(value: Boolean) { - notificationListRepository.setHasFilteredOutSeenNotifications(value) + notificationListRepository.hasFilteredOutSeenNotifications.value = value } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt index 40cc294016e558e7b82898e05a7c7d462b2696f0..ee01fcca82d47400cd305673ba8b668e6fa530ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt @@ -19,7 +19,7 @@ import android.graphics.Rect import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.shade.domain.interactor.ShadeInteractor -import com.android.systemui.statusbar.notification.domain.interactor.NotificationsInteractor +import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.ColorLookup import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconColors import com.android.systemui.statusbar.phone.domain.interactor.DarkIconInteractor @@ -35,7 +35,7 @@ class NotificationIconContainerStatusBarViewModel constructor( darkIconInteractor: DarkIconInteractor, keyguardInteractor: KeyguardInteractor, - notificationsInteractor: NotificationsInteractor, + notificationsInteractor: ActiveNotificationsInteractor, shadeInteractor: ShadeInteractor, ) : NotificationIconContainerViewModel { override val animationsEnabled: Flow<Boolean> = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..ea29cab3b7dcfc62b913c77c11564f306d8d1534 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.shared + +/** Model for entries in the notification stack. */ +data class ActiveNotificationModel( + /** Notification key associated with this entry. */ + val key: String, +) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 6a70815f82f382ed1e62b8923911ec0fa6c8f749..335458225e1d599632eb3713f5f775f5d8fb6a17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -106,6 +106,7 @@ import com.android.systemui.statusbar.notification.collection.render.NotifStats; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import com.android.systemui.statusbar.notification.dagger.SilentHeader; +import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor; import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; @@ -114,7 +115,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.NotificationGuts; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationSnooze; -import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor; import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder; import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; @@ -194,7 +194,7 @@ public class NotificationStackScrollLayoutController { private final GroupExpansionManager mGroupExpansionManager; private final NotifPipelineFlags mNotifPipelineFlags; - private final NotificationListInteractor mNotificationListInteractor; + private final SeenNotificationsInteractor mSeenNotificationsInteractor; private final KeyguardTransitionRepository mKeyguardTransitionRepo; private NotificationStackScrollLayout mView; @@ -662,7 +662,7 @@ public class NotificationStackScrollLayoutController { UiEventLogger uiEventLogger, NotificationRemoteInputManager remoteInputManager, VisibilityLocationProviderDelegator visibilityLocationProviderDelegator, - NotificationListInteractor notificationListInteractor, + SeenNotificationsInteractor seenNotificationsInteractor, ShadeController shadeController, InteractionJankMonitor jankMonitor, StackStateLogger stackLogger, @@ -715,7 +715,7 @@ public class NotificationStackScrollLayoutController { mUiEventLogger = uiEventLogger; mRemoteInputManager = remoteInputManager; mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator; - mNotificationListInteractor = notificationListInteractor; + mSeenNotificationsInteractor = seenNotificationsInteractor; mShadeController = shadeController; mNotifIconAreaController = notifIconAreaController; mFeatureFlags = featureFlags; @@ -2006,7 +2006,7 @@ public class NotificationStackScrollLayoutController { public void setNotifStats(@NonNull NotifStats notifStats) { mNotifStats = notifStats; mView.setHasFilteredOutSeenNotifications( - mNotificationListInteractor.getHasFilteredOutSeenNotifications().getValue()); + mSeenNotificationsInteractor.getHasFilteredOutSeenNotifications().getValue()); updateFooter(); updateShowEmptyShadeView(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt deleted file mode 100644 index f6ed8c884816aed3881d8de7464bc904986dc63b..0000000000000000000000000000000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.stack.data.repository - -import com.android.systemui.dagger.SysUISingleton -import javax.inject.Inject -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow - -/** Repository for information about the current notification list. */ -@SysUISingleton -class NotificationListRepository @Inject constructor() { - private val _hasFilteredOutSeenNotifications = MutableStateFlow(false) - val hasFilteredOutSeenNotifications: StateFlow<Boolean> = - _hasFilteredOutSeenNotifications.asStateFlow() - - fun setHasFilteredOutSeenNotifications(value: Boolean) { - _hasFilteredOutSeenNotifications.value = value - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index a5cd062f6f37b00e310f25c412293cb0d8ec1c3d..07e2571bcb3826f6ad0cde7077e959c9fb97e5d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -52,7 +52,7 @@ import com.android.systemui.statusbar.notification.AboveShelfObserver; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; -import com.android.systemui.statusbar.notification.domain.interactor.NotificationsInteractor; +import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -80,7 +80,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu private final HeadsUpManager mHeadsUpManager; private final AboveShelfObserver mAboveShelfObserver; private final DozeScrimController mDozeScrimController; - private final NotificationsInteractor mNotificationsInteractor; + private final NotificationAlertsInteractor mNotificationAlertsInteractor; private final NotificationStackScrollLayoutController mNsslController; private final LockscreenShadeTransitionController mShadeTransitionController; private final PowerInteractor mPowerInteractor; @@ -107,7 +107,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu NotificationShadeWindowController notificationShadeWindowController, DynamicPrivacyController dynamicPrivacyController, KeyguardStateController keyguardStateController, - NotificationsInteractor notificationsInteractor, + NotificationAlertsInteractor notificationAlertsInteractor, LockscreenShadeTransitionController shadeTransitionController, PowerInteractor powerInteractor, CommandQueue commandQueue, @@ -127,7 +127,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu mQsController = quickSettingsController; mHeadsUpManager = headsUp; mDynamicPrivacyController = dynamicPrivacyController; - mNotificationsInteractor = notificationsInteractor; + mNotificationAlertsInteractor = notificationAlertsInteractor; mNsslController = stackScrollerController; mShadeTransitionController = shadeTransitionController; mPowerInteractor = powerInteractor; @@ -303,7 +303,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu @Override public boolean suppressInterruptions(NotificationEntry entry) { - return !mNotificationsInteractor.areNotificationAlertsEnabled(); + return !mNotificationAlertsInteractor.areNotificationAlertsEnabled(); } }; } diff --git a/packages/SystemUI/tests/src/com/android/SysUITestModule.kt b/packages/SystemUI/tests/src/com/android/SysUITestModule.kt index ed0541ada77b79f2e8bbd192bceaea7ab8217f03..c4b43e1cbe77238642e56686a3ea66a63f9200e6 100644 --- a/packages/SystemUI/tests/src/com/android/SysUITestModule.kt +++ b/packages/SystemUI/tests/src/com/android/SysUITestModule.kt @@ -26,7 +26,6 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.broadcast.FakeBroadcastDispatcher import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.statusbar.notification.data.repository.NotificationStackRepositoryModule import dagger.Binds import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt index 546abd4ec79a4b29f36e4a84cb0fb87d660580b6..6c1f537e754f1e0b4fca950683c0ca2d65823f33 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt @@ -39,10 +39,10 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository -import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener import com.android.systemui.util.mockito.any @@ -246,7 +246,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { unseenFilter.onCleanup() // THEN: The SeenNotificationProvider has been updated to reflect the suppression - assertThat(notificationListInteractor.hasFilteredOutSeenNotifications.value).isTrue() + assertThat(seenNotificationsInteractor.hasFilteredOutSeenNotifications.value).isTrue() } } @@ -597,7 +597,8 @@ class KeyguardCoordinatorTest : SysuiTestCase() { FakeSettings().apply { putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1) } - val notificationListInteractor = NotificationListInteractor(NotificationListRepository()) + val seenNotificationsInteractor = + SeenNotificationsInteractor(ActiveNotificationListRepository()) val keyguardCoordinator = KeyguardCoordinator( testDispatcher, @@ -610,7 +611,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { testScope.backgroundScope, sectionHeaderVisibilityProvider, fakeSettings, - notificationListInteractor, + seenNotificationsInteractor, statusBarStateController, ) keyguardCoordinator.attach(notifPipeline) @@ -618,7 +619,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { KeyguardCoordinatorTestScope( keyguardCoordinator, testScope, - notificationListInteractor, + seenNotificationsInteractor, fakeSettings, ) .testBlock() @@ -628,7 +629,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { private inner class KeyguardCoordinatorTestScope( private val keyguardCoordinator: KeyguardCoordinator, private val scope: TestScope, - val notificationListInteractor: NotificationListInteractor, + val seenNotificationsInteractor: SeenNotificationsInteractor, private val fakeSettings: FakeSettings, ) : CoroutineScope by scope { val testScheduler: TestCoroutineScheduler diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt similarity index 92% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt index 6bf9e350cd50342b5859e58e0e62e3352ceb705d..683d0aa33d4ae7b2e08e3c709a62ac644562e944 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt @@ -27,12 +27,12 @@ import dagger.Component import org.junit.Test @SmallTest -class NotificationsInteractorTest : SysuiTestCase() { +class NotificationAlertsInteractorTest : SysuiTestCase() { @Component(modules = [SysUITestModule::class]) @SysUISingleton interface TestComponent { - val underTest: NotificationsInteractor + val underTest: NotificationAlertsInteractor val disableFlags: FakeDisableFlagsRepository @Component.Factory @@ -42,7 +42,7 @@ class NotificationsInteractorTest : SysuiTestCase() { } private val testComponent: TestComponent = - DaggerNotificationsInteractorTest_TestComponent.factory().create(test = this) + DaggerNotificationAlertsInteractorTest_TestComponent.factory().create(test = this) @Test fun disableFlags_notifAlertsNotDisabled_notifAlertsEnabledTrue() = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..8c5c43986f8ae30ded02fc311edb174d4c86ebd3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.domain.interactor + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.statusbar.notification.collection.ListEntry +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.android.systemui.statusbar.notification.shared.byKey +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@SmallTest +class RenderNotificationsListInteractorTest : SysuiTestCase() { + + private val notifsRepository = ActiveNotificationListRepository() + private val notifsInteractor = ActiveNotificationsInteractor(notifsRepository) + private val underTest = + RenderNotificationListInteractor( + notifsRepository, + ) + + @Test + fun setRenderedList_preservesOrdering() = runTest { + val notifs by collectLastValue(notifsInteractor.notifications) + val keys = (1..50).shuffled().map { "$it" } + val entries = keys.map { mock<ListEntry> { whenever(key).thenReturn(it) } } + underTest.setRenderedList(entries) + assertThat(notifs).comparingElementsUsing(byKey).containsExactlyElementsIn(keys).inOrder() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..2a3c1a53559eda1d89694a586fcce4e8a6441999 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.domain.interactor + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class SeenNotificationsInteractorTest : SysuiTestCase() { + + private val repository = ActiveNotificationListRepository() + private val underTest = SeenNotificationsInteractor(repository) + + @Test + fun testNoFilteredOutSeenNotifications() = runTest { + val hasFilteredOutSeenNotifications by + collectLastValue(underTest.hasFilteredOutSeenNotifications) + + underTest.setHasFilteredOutSeenNotifications(false) + + assertThat(hasFilteredOutSeenNotifications).isFalse() + } + + @Test + fun testHasFilteredOutSeenNotifications() = runTest { + val hasFilteredOutSeenNotifications by + collectLastValue(underTest.hasFilteredOutSeenNotifications) + + underTest.setHasFilteredOutSeenNotifications(true) + + assertThat(hasFilteredOutSeenNotifications).isTrue() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..ed9405814e6aa61baa96a3b85bd89784b09857c8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.shared + +import com.google.common.truth.Correspondence + +val byKey: Correspondence<ActiveNotificationModel, String> = + Correspondence.transforming({ it?.key }, "has a key of") diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java index 20197e3ed547d5c4f3ca3b4c643c6136f648cf6b..3dafb23c8a372e39641242cacc801727f2afe11d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java @@ -82,13 +82,13 @@ import com.android.systemui.statusbar.notification.collection.render.GroupExpans import com.android.systemui.statusbar.notification.collection.render.NotifStats; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository; +import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor; import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent; import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback; -import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository; -import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor; import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconAreaController; @@ -171,8 +171,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; - private final NotificationListInteractor mNotificationListInteractor = - new NotificationListInteractor(new NotificationListRepository()); + private final SeenNotificationsInteractor mSeenNotificationsInteractor = + new SeenNotificationsInteractor(new ActiveNotificationListRepository()); private NotificationStackScrollLayoutController mController; @@ -504,7 +504,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Test public void testSetNotifStats_updatesHasFilteredOutSeenNotifications() { initController(/* viewIsAttached= */ true); - mNotificationListInteractor.setHasFilteredOutSeenNotifications(true); + mSeenNotificationsInteractor.setHasFilteredOutSeenNotifications(true); mController.getNotifStackController().setNotifStats(NotifStats.getEmpty()); verify(mNotificationStackScrollLayout).setHasFilteredOutSeenNotifications(true); verify(mNotificationStackScrollLayout).updateFooter(); @@ -704,7 +704,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mUiEventLogger, mRemoteInputManager, mVisibilityLocationProviderDelegator, - mNotificationListInteractor, + mSeenNotificationsInteractor, mShadeController, mJankMonitor, mStackLogger, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index ee4f2089c05c66abb9032c033b01b869ebb2bace..53c621d246015ac64a48aff490e0cf164ee06b8a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -53,7 +53,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; -import com.android.systemui.statusbar.notification.domain.interactor.NotificationsInteractor; +import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; @@ -79,8 +79,8 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { private CommandQueue mCommandQueue; private FakeMetricsLogger mMetricsLogger; private final ShadeController mShadeController = mock(ShadeController.class); - private final NotificationsInteractor mNotificationsInteractor = - mock(NotificationsInteractor.class); + private final NotificationAlertsInteractor mNotificationAlertsInteractor = + mock(NotificationAlertsInteractor.class); private final KeyguardStateController mKeyguardStateController = mock(KeyguardStateController.class); private final InitController mInitController = new InitController(); @@ -116,7 +116,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mock(NotificationShadeWindowController.class), mock(DynamicPrivacyController.class), mKeyguardStateController, - mNotificationsInteractor, + mNotificationAlertsInteractor, mock(LockscreenShadeTransitionController.class), mock(PowerInteractor.class), mCommandQueue, @@ -226,7 +226,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { .setTag("a") .setNotification(n) .build(); - when(mNotificationsInteractor.areNotificationAlertsEnabled()).thenReturn(false); + when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false); assertTrue("When alerts aren't enabled, interruptions are suppressed", mInterruptSuppressor.suppressInterruptions(entry)); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt index 465b93a5b1e91e46ebbce32f0759498c8f8b76b5..788e3aa9c41a32e9a5fac897f43169838c796015 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt @@ -16,14 +16,7 @@ package com.android.systemui.statusbar.notification.data import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardStateRepositoryModule -import com.android.systemui.statusbar.notification.data.repository.NotificationStackRepositoryModule import dagger.Module -@Module( - includes = - [ - FakeNotificationsKeyguardStateRepositoryModule::class, - NotificationStackRepositoryModule::class, - ] -) +@Module(includes = [FakeNotificationsKeyguardStateRepositoryModule::class]) object FakeStatusBarNotificationsDataLayerModule