1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 * 14 */ 15 16 package com.android.systemui.statusbar.notification.domain.interactor 17 18 import com.android.systemui.dagger.qualifiers.Background 19 import com.android.systemui.statusbar.notification.collection.render.NotifStats 20 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository 21 import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel 22 import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel 23 import javax.inject.Inject 24 import kotlinx.coroutines.CoroutineDispatcher 25 import kotlinx.coroutines.flow.Flow 26 import kotlinx.coroutines.flow.distinctUntilChanged 27 import kotlinx.coroutines.flow.flowOn 28 import kotlinx.coroutines.flow.map 29 30 class ActiveNotificationsInteractor 31 @Inject 32 constructor( 33 private val repository: ActiveNotificationListRepository, 34 @Background private val backgroundDispatcher: CoroutineDispatcher, 35 ) { 36 /** 37 * Top level list of Notifications actively presented to the user in the notification stack, in 38 * order. 39 */ 40 val topLevelRepresentativeNotifications: Flow<List<ActiveNotificationModel>> = 41 repository.activeNotifications 42 .map { store -> 43 store.renderList.map { key -> 44 val entry = 45 store[key] 46 ?: error( 47 "Could not find notification with key $key in active notif store." 48 ) 49 when (entry) { 50 is ActiveNotificationGroupModel -> entry.summary 51 is ActiveNotificationModel -> entry 52 } 53 } 54 } 55 .flowOn(backgroundDispatcher) 56 57 /** 58 * Flattened list of Notifications actively presented to the user in the notification stack, in 59 * order. 60 */ 61 val allRepresentativeNotifications: Flow<Map<String, ActiveNotificationModel>> = 62 repository.activeNotifications.map { store -> store.individuals } 63 64 /** Size of the flattened list of Notifications actively presented in the stack. */ 65 val allNotificationsCount: Flow<Int> = 66 repository.activeNotifications.map { store -> store.individuals.size } 67 68 /** 69 * The same as [allNotificationsCount], but without flows, for easy access in synchronous code. 70 */ 71 val allNotificationsCountValue: Int 72 get() = repository.activeNotifications.value.individuals.size 73 74 /** Are any notifications being actively presented in the notification stack? */ 75 val areAnyNotificationsPresent: Flow<Boolean> = 76 repository.activeNotifications 77 .map { it.renderList.isNotEmpty() } 78 .distinctUntilChanged() 79 .flowOn(backgroundDispatcher) 80 81 /** 82 * The same as [areAnyNotificationsPresent], but without flows, for easy access in synchronous 83 * code. 84 */ 85 val areAnyNotificationsPresentValue: Boolean 86 get() = repository.activeNotifications.value.renderList.isNotEmpty() 87 88 /** 89 * Map of notification key to rank, where rank is the 0-based index of the notification in the 90 * system server, meaning that in the unfiltered flattened list of notification entries. Used 91 * for logging purposes. 92 * 93 * @see [com.android.systemui.statusbar.notification.stack.ui.view.NotificationStatsLogger]. 94 */ 95 val activeNotificationRanks: Flow<Map<String, Int>> = 96 repository.activeNotifications.map { store -> store.rankingsMap } 97 98 /** Are there are any notifications that can be cleared by the "Clear all" button? */ 99 val hasClearableNotifications: Flow<Boolean> = 100 repository.notifStats 101 .map { it.hasClearableAlertingNotifs || it.hasClearableSilentNotifs } 102 .distinctUntilChanged() 103 .flowOn(backgroundDispatcher) 104 105 val hasClearableAlertingNotifications: Flow<Boolean> = 106 repository.notifStats 107 .map { it.hasClearableAlertingNotifs } 108 .distinctUntilChanged() 109 .flowOn(backgroundDispatcher) 110 111 val hasNonClearableSilentNotifications: Flow<Boolean> = 112 repository.notifStats 113 .map { it.hasNonClearableSilentNotifs } 114 .distinctUntilChanged() 115 .flowOn(backgroundDispatcher) 116 117 fun setNotifStats(notifStats: NotifStats) { 118 repository.notifStats.value = notifStats 119 } 120 } 121