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