1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.systemui.statusbar.notification.collection.coordinator
17 
18 import android.util.ArrayMap
19 import com.android.systemui.statusbar.notification.collection.GroupEntry
20 import com.android.systemui.statusbar.notification.collection.ListEntry
21 import com.android.systemui.statusbar.notification.collection.NotifPipeline
22 import com.android.systemui.statusbar.notification.collection.NotificationEntry
23 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
24 import com.android.systemui.statusbar.notification.collection.render.NotifRowController
25 import javax.inject.Inject
26 import kotlin.math.max
27 
28 /**
29  * A small coordinator which ensures the "alerted" bell shows not just for recently alerted entries,
30  * but also on the summary for every such entry.
31  */
32 @CoordinatorScope
33 class RowAlertTimeCoordinator @Inject constructor() : Coordinator {
34 
35     private val latestAlertTimeBySummary = ArrayMap<NotificationEntry, Long>()
36 
37     override fun attach(pipeline: NotifPipeline) {
38         pipeline.addOnBeforeFinalizeFilterListener(::onBeforeFinalizeFilterListener)
39         pipeline.addOnAfterRenderEntryListener(::onAfterRenderEntry)
40     }
41 
42     private fun onBeforeFinalizeFilterListener(entries: List<ListEntry>) {
43         latestAlertTimeBySummary.clear()
44         entries.asSequence().filterIsInstance<GroupEntry>().forEach { groupEntry ->
45             val summary = checkNotNull(groupEntry.summary)
46             latestAlertTimeBySummary[summary] = groupEntry.calculateLatestAlertTime()
47         }
48     }
49 
50     private fun onAfterRenderEntry(entry: NotificationEntry, controller: NotifRowController) {
51         // Show the "alerted" bell icon based on the latest group member for summaries
52         val lastAudiblyAlerted = latestAlertTimeBySummary[entry] ?: entry.lastAudiblyAlertedMs
53         controller.setLastAudibleMs(lastAudiblyAlerted)
54     }
55 
56     private fun GroupEntry.calculateLatestAlertTime(): Long {
57         val lastChildAlertedTime = children.maxOfOrNull { it.lastAudiblyAlertedMs } ?: 0
58         val summaryAlertedTime = checkNotNull(summary).lastAudiblyAlertedMs
59         return max(lastChildAlertedTime, summaryAlertedTime)
60     }
61 }
62