Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt +22 −10 Original line number Diff line number Diff line Loading @@ -15,37 +15,48 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map class ActiveNotificationsInteractor @Inject constructor( private val repository: ActiveNotificationListRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) { /** Notifications actively presented to the user in the notification stack, in order. */ val topLevelRepresentativeNotifications: Flow<List<ActiveNotificationModel>> = repository.activeNotifications.map { store -> repository.activeNotifications .map { store -> store.renderList.map { key -> val entry = store[key] ?: error("Could not find notification with key $key in active notif store.") ?: error( "Could not find notification with key $key in active notif store." ) when (entry) { is ActiveNotificationGroupModel -> entry.summary is ActiveNotificationModel -> entry } } } .flowOn(backgroundDispatcher) /** Are any notifications being actively presented in the notification stack? */ val areAnyNotificationsPresent: Flow<Boolean> = repository.activeNotifications.map { it.renderList.isNotEmpty() }.distinctUntilChanged() repository.activeNotifications .map { it.renderList.isNotEmpty() } .distinctUntilChanged() .flowOn(backgroundDispatcher) /** * The same as [areAnyNotificationsPresent], but without flows, for easy access in synchronous Loading @@ -59,6 +70,7 @@ constructor( repository.notifStats .map { it.hasClearableAlertingNotifs || it.hasClearableSilentNotifs } .distinctUntilChanged() .flowOn(backgroundDispatcher) fun setNotifStats(notifStats: NotifStats) { repository.notifStats.value = notifStats Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt +7 −2 Original line number Diff line number Diff line Loading @@ -15,19 +15,24 @@ */ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn /** Domain logic pertaining to notifications on the keyguard. */ class NotificationsKeyguardInteractor @Inject constructor( repository: NotificationsKeyguardViewStateRepository, @Background backgroundDispatcher: CoroutineDispatcher, ) { /** Is a pulse expansion occurring? */ val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding.flowOn(backgroundDispatcher) /** Are notifications fully hidden from view? */ val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden.flowOn(backgroundDispatcher) } packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +6 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; import android.content.res.Resources; import android.os.Handler; import android.os.Looper; Loading Loading @@ -293,8 +295,10 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { ) ); mActiveNotificationsInteractor = new ActiveNotificationsInteractor(new ActiveNotificationListRepository()); mActiveNotificationsInteractor = new ActiveNotificationsInteractor( new ActiveNotificationListRepository(), StandardTestDispatcher(/* scheduler = */ null, /* name = */ null) ); KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext); keyguardStatusView.setId(R.id.keyguard_status_view); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt +26 −16 Original line number Diff line number Diff line Loading @@ -25,14 +25,19 @@ 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.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @SmallTest class RenderNotificationsListInteractorTest : SysuiTestCase() { private val backgroundDispatcher = StandardTestDispatcher() private val testScope = TestScope(backgroundDispatcher) private val notifsRepository = ActiveNotificationListRepository() private val notifsInteractor = ActiveNotificationsInteractor(notifsRepository) private val notifsInteractor = ActiveNotificationsInteractor(notifsRepository, backgroundDispatcher) private val underTest = RenderNotificationListInteractor( notifsRepository, Loading @@ -40,13 +45,15 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { ) @Test fun setRenderedList_preservesOrdering() = runTest { fun setRenderedList_preservesOrdering() = testScope.runTest { val notifs by collectLastValue(notifsInteractor.topLevelRepresentativeNotifications) val keys = (1..50).shuffled().map { "$it" } val entries = keys.map { mock<ListEntry> { val mockRep = mock<NotificationEntry> { val mockRep = mock<NotificationEntry> { whenever(key).thenReturn(it) whenever(sbn).thenReturn(mock()) whenever(icons).thenReturn(mock()) Loading @@ -55,6 +62,9 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { } } underTest.setRenderedList(entries) assertThat(notifs).comparingElementsUsing(byKey).containsExactlyElementsIn(keys).inOrder() assertThat(notifs) .comparingElementsUsing(byKey) .containsExactlyElementsIn(keys) .inOrder() } } packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.FlowKt.emptyFlow; import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; Loading Loading @@ -169,7 +170,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { new ActiveNotificationListRepository(); private final ActiveNotificationsInteractor mActiveNotificationsInteractor = new ActiveNotificationsInteractor(mActiveNotificationsRepository); new ActiveNotificationsInteractor(mActiveNotificationsRepository, StandardTestDispatcher(/* scheduler = */ null, /* name = */ null)); private final SeenNotificationsInteractor mSeenNotificationsInteractor = new SeenNotificationsInteractor(mActiveNotificationsRepository); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt +22 −10 Original line number Diff line number Diff line Loading @@ -15,37 +15,48 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map class ActiveNotificationsInteractor @Inject constructor( private val repository: ActiveNotificationListRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) { /** Notifications actively presented to the user in the notification stack, in order. */ val topLevelRepresentativeNotifications: Flow<List<ActiveNotificationModel>> = repository.activeNotifications.map { store -> repository.activeNotifications .map { store -> store.renderList.map { key -> val entry = store[key] ?: error("Could not find notification with key $key in active notif store.") ?: error( "Could not find notification with key $key in active notif store." ) when (entry) { is ActiveNotificationGroupModel -> entry.summary is ActiveNotificationModel -> entry } } } .flowOn(backgroundDispatcher) /** Are any notifications being actively presented in the notification stack? */ val areAnyNotificationsPresent: Flow<Boolean> = repository.activeNotifications.map { it.renderList.isNotEmpty() }.distinctUntilChanged() repository.activeNotifications .map { it.renderList.isNotEmpty() } .distinctUntilChanged() .flowOn(backgroundDispatcher) /** * The same as [areAnyNotificationsPresent], but without flows, for easy access in synchronous Loading @@ -59,6 +70,7 @@ constructor( repository.notifStats .map { it.hasClearableAlertingNotifs || it.hasClearableSilentNotifs } .distinctUntilChanged() .flowOn(backgroundDispatcher) fun setNotifStats(notifStats: NotifStats) { repository.notifStats.value = notifStats Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt +7 −2 Original line number Diff line number Diff line Loading @@ -15,19 +15,24 @@ */ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn /** Domain logic pertaining to notifications on the keyguard. */ class NotificationsKeyguardInteractor @Inject constructor( repository: NotificationsKeyguardViewStateRepository, @Background backgroundDispatcher: CoroutineDispatcher, ) { /** Is a pulse expansion occurring? */ val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding.flowOn(backgroundDispatcher) /** Are notifications fully hidden from view? */ val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden.flowOn(backgroundDispatcher) }
packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +6 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; import android.content.res.Resources; import android.os.Handler; import android.os.Looper; Loading Loading @@ -293,8 +295,10 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { ) ); mActiveNotificationsInteractor = new ActiveNotificationsInteractor(new ActiveNotificationListRepository()); mActiveNotificationsInteractor = new ActiveNotificationsInteractor( new ActiveNotificationListRepository(), StandardTestDispatcher(/* scheduler = */ null, /* name = */ null) ); KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext); keyguardStatusView.setId(R.id.keyguard_status_view); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt +26 −16 Original line number Diff line number Diff line Loading @@ -25,14 +25,19 @@ 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.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @SmallTest class RenderNotificationsListInteractorTest : SysuiTestCase() { private val backgroundDispatcher = StandardTestDispatcher() private val testScope = TestScope(backgroundDispatcher) private val notifsRepository = ActiveNotificationListRepository() private val notifsInteractor = ActiveNotificationsInteractor(notifsRepository) private val notifsInteractor = ActiveNotificationsInteractor(notifsRepository, backgroundDispatcher) private val underTest = RenderNotificationListInteractor( notifsRepository, Loading @@ -40,13 +45,15 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { ) @Test fun setRenderedList_preservesOrdering() = runTest { fun setRenderedList_preservesOrdering() = testScope.runTest { val notifs by collectLastValue(notifsInteractor.topLevelRepresentativeNotifications) val keys = (1..50).shuffled().map { "$it" } val entries = keys.map { mock<ListEntry> { val mockRep = mock<NotificationEntry> { val mockRep = mock<NotificationEntry> { whenever(key).thenReturn(it) whenever(sbn).thenReturn(mock()) whenever(icons).thenReturn(mock()) Loading @@ -55,6 +62,9 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { } } underTest.setRenderedList(entries) assertThat(notifs).comparingElementsUsing(byKey).containsExactlyElementsIn(keys).inOrder() assertThat(notifs) .comparingElementsUsing(byKey) .containsExactlyElementsIn(keys) .inOrder() } }
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.FlowKt.emptyFlow; import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; Loading Loading @@ -169,7 +170,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { new ActiveNotificationListRepository(); private final ActiveNotificationsInteractor mActiveNotificationsInteractor = new ActiveNotificationsInteractor(mActiveNotificationsRepository); new ActiveNotificationsInteractor(mActiveNotificationsRepository, StandardTestDispatcher(/* scheduler = */ null, /* name = */ null)); private final SeenNotificationsInteractor mSeenNotificationsInteractor = new SeenNotificationsInteractor(mActiveNotificationsRepository); Loading