• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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 
17 package com.android.systemui.statusbar.notification.icon.ui.viewbinder
18 
19 import android.util.Log
20 import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractor
21 import com.android.systemui.lifecycle.Activatable
22 import com.android.systemui.statusbar.StatusBarIconView
23 import com.android.systemui.statusbar.notification.collection.NotifCollection
24 import com.android.systemui.statusbar.notification.collection.NotifPipeline
25 import com.android.systemui.statusbar.notification.collection.NotificationEntry
26 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
27 import com.android.systemui.statusbar.notification.icon.IconManager
28 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
29 import dagger.assisted.Assisted
30 import dagger.assisted.AssistedFactory
31 import dagger.assisted.AssistedInject
32 import java.util.concurrent.ConcurrentHashMap
33 import kotlinx.coroutines.awaitCancellation
34 import kotlinx.coroutines.coroutineScope
35 
36 /** [IconViewStore] for the status bar on multiple displays. */
37 class ConnectedDisplaysStatusBarNotificationIconViewStore
38 @AssistedInject
39 constructor(
40     @Assisted private val displayId: Int,
41     private val notifCollection: NotifCollection,
42     private val iconManager: IconManager,
43     private val displayWindowPropertiesInteractor: DisplayWindowPropertiesInteractor,
44     private val notifPipeline: NotifPipeline,
45 ) : IconViewStore, Activatable {
46 
47     private val cachedIcons = ConcurrentHashMap<String, StatusBarIconView>()
48 
49     private val iconUpdateRequiredListener =
50         object : IconManager.OnIconUpdateRequiredListener {
onIconUpdateRequirednull51             override fun onIconUpdateRequired(entry: NotificationEntry) {
52                 val iconView = iconView(entry.key) ?: return
53                 iconManager.updateSbIcon(entry, iconView)
54             }
55         }
56 
57     private val notifCollectionListener =
58         object : NotifCollectionListener {
onEntryRemovednull59             override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
60                 cachedIcons.remove(entry.key)
61             }
62         }
63 
iconViewnull64     override fun iconView(key: String): StatusBarIconView? {
65         val entry = notifCollection.getEntry(key)
66         if (entry == null) {
67             Log.w(TAG, "No notification entry found for key: $key")
68             return null
69         }
70         val displayWindowProperties = displayWindowPropertiesInteractor.getForStatusBar(displayId)
71         if (displayWindowProperties == null) {
72             Log.w(TAG, "No display properties found for display id: $displayId")
73             return null
74         }
75         return cachedIcons.computeIfAbsent(key) {
76             val context = displayWindowProperties.context
77             iconManager.createSbIconView(context, entry)
78         }
79     }
80 
<lambda>null81     override suspend fun activate() = coroutineScope {
82         start()
83         try {
84             awaitCancellation()
85         } finally {
86             stop()
87         }
88     }
89 
startnull90     private fun start() {
91         notifPipeline.addCollectionListener(notifCollectionListener)
92         iconManager.addIconsUpdateListener(iconUpdateRequiredListener)
93     }
94 
stopnull95     private fun stop() {
96         notifPipeline.removeCollectionListener(notifCollectionListener)
97         iconManager.removeIconsUpdateListener(iconUpdateRequiredListener)
98     }
99 
100     @AssistedFactory
101     interface Factory {
createnull102         fun create(displayId: Int): ConnectedDisplaysStatusBarNotificationIconViewStore
103     }
104 
105     companion object {
106         private const val TAG = "ConnectedDisplaysNotifIconViewStore"
107     }
108 }
109