Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 405bed58 authored by Steve Elliott's avatar Steve Elliott
Browse files

Introduce ActiveNotificationModel data model

This class serves as an immutable snapshot of ListEntry, so that the
recommended architecture stack doesn't have to worry about the
notification pipeline mutating data out from under it.

This CL also renames and unifies some of the various
Notification-related repositories and interactors; "Active" is used to
identify the outputs of the notification pipeline, which internally
tracks "inactive" notifications (ones that are filtered from view).

Flag: NOTIFICATION_ICON_CONTAINER_REFACTOR
Bug: 290787599
Bug: 278765923
Test: atest SystemUITests
Change-Id: I246b5a5e3a744caad4dcc252c96166e91fe2cc48
parent 319259ca
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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 {
+1 −8
Original line number Diff line number Diff line
@@ -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
+7 −21
Original line number Diff line number Diff line
@@ -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)
}
+32 −0
Original line number Diff line number Diff line
/*
 * 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 }
}
+2 −9
Original line number Diff line number Diff line
@@ -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
}
Loading