1 /* 2 * Copyright (C) 2025 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.collection 18 19 import android.content.Context 20 import android.os.SystemClock 21 import android.service.notification.NotificationListenerService 22 import android.service.notification.StatusBarNotification 23 import com.android.internal.logging.MetricsLogger 24 import com.android.systemui.statusbar.notification.NotificationActivityStarter 25 import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator 26 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender 27 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider 28 import com.android.systemui.statusbar.notification.headsup.HeadsUpManager 29 import com.android.systemui.statusbar.notification.icon.IconPack 30 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier 31 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow 32 import com.android.systemui.statusbar.notification.row.NotificationActionClickManager 33 import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider 34 import kotlinx.coroutines.flow.StateFlow 35 36 class NotificationEntryAdapter( 37 private val notificationActivityStarter: NotificationActivityStarter, 38 private val metricsLogger: MetricsLogger, 39 private val peopleNotificationIdentifier: PeopleNotificationIdentifier, 40 private val iconStyleProvider: NotificationIconStyleProvider, 41 private val visualStabilityCoordinator: VisualStabilityCoordinator, 42 private val notificationActionClickManager: NotificationActionClickManager, 43 private val highPriorityProvider: HighPriorityProvider, 44 private val headsUpManager: HeadsUpManager, 45 private val entry: NotificationEntry, 46 ) : EntryAdapter { getBackingHashCodenull47 override fun getBackingHashCode(): Int { 48 return entry.hashCode() 49 } 50 getParentnull51 override fun getParent(): PipelineEntry? { 52 return entry.parent 53 } 54 isTopLevelEntrynull55 override fun isTopLevelEntry(): Boolean { 56 return parent != null && 57 (parent === GroupEntry.ROOT_ENTRY || BundleEntry.ROOT_BUNDLES.contains(parent)) 58 } 59 getKeynull60 override fun getKey(): String { 61 return entry.key 62 } 63 getRownull64 override fun getRow(): ExpandableNotificationRow { 65 return entry.row 66 } 67 isGroupRootnull68 override fun isGroupRoot(): Boolean { 69 if (isTopLevelEntry || parent == null) { 70 return false 71 } 72 return (entry.parent as? GroupEntry)?.summary == entry 73 } 74 isSensitivenull75 override fun isSensitive(): StateFlow<Boolean> { 76 return entry.isSensitive 77 } 78 isClearablenull79 override fun isClearable(): Boolean { 80 return entry.isClearable 81 } 82 getTargetSdknull83 override fun getTargetSdk(): Int { 84 return entry.targetSdk 85 } 86 getSummarizationnull87 override fun getSummarization(): String? { 88 return entry.ranking?.summarization 89 } 90 prepareForInflationnull91 override fun prepareForInflation() { 92 entry.sbn.clearPackageContext() 93 } 94 getContrastedColornull95 override fun getContrastedColor( 96 context: Context?, 97 isLowPriority: Boolean, 98 backgroundColor: Int, 99 ): Int { 100 return entry.getContrastedColor(context, isLowPriority, backgroundColor) 101 } 102 canPeeknull103 override fun canPeek(): Boolean { 104 return entry.isStickyAndNotDemoted 105 } 106 getWhennull107 override fun getWhen(): Long { 108 return entry.sbn.notification.getWhen() 109 } 110 getIconsnull111 override fun getIcons(): IconPack { 112 return entry.icons 113 } 114 isColorizednull115 override fun isColorized(): Boolean { 116 return entry.sbn.notification.isColorized 117 } 118 getSbnnull119 override fun getSbn(): StatusBarNotification { 120 return entry.sbn 121 } 122 getRankingnull123 override fun getRanking(): NotificationListenerService.Ranking? { 124 return entry.ranking 125 } 126 endLifetimeExtensionnull127 override fun endLifetimeExtension( 128 callback: NotifLifetimeExtender.OnEndLifetimeExtensionCallback?, 129 extender: NotifLifetimeExtender, 130 ) { 131 callback?.onEndLifetimeExtension(extender, entry) 132 } 133 onImportanceChangednull134 override fun onImportanceChanged() { 135 visualStabilityCoordinator.temporarilyAllowSectionChanges(entry, SystemClock.uptimeMillis()) 136 } 137 markForUserTriggeredMovementnull138 override fun markForUserTriggeredMovement() { 139 entry.markForUserTriggeredMovement(true) 140 } 141 isMarkedForUserTriggeredMovementnull142 override fun isMarkedForUserTriggeredMovement(): Boolean { 143 return entry.isMarkedForUserTriggeredMovement 144 } 145 isHighPrioritynull146 override fun isHighPriority(): Boolean { 147 return highPriorityProvider.isHighPriority(entry) 148 } 149 setInlineControlsShownnull150 override fun setInlineControlsShown(currentlyVisible: Boolean) { 151 headsUpManager.setGutsShown(entry, currentlyVisible) 152 } 153 isBlockablenull154 override fun isBlockable(): Boolean { 155 return entry.isBlockable 156 } 157 canDragAndDropnull158 override fun canDragAndDrop(): Boolean { 159 val canBubble: Boolean = entry.canBubble() 160 val notif = entry.sbn.notification 161 val dragIntent = 162 if (notif.contentIntent != null) notif.contentIntent else notif.fullScreenIntent 163 if (dragIntent != null && dragIntent.isActivity && !canBubble) { 164 return true 165 } 166 return false 167 } 168 isBubblenull169 override fun isBubble(): Boolean { 170 return entry.isBubble 171 } 172 getStylenull173 override fun getStyle(): String? { 174 return entry.notificationStyle 175 } 176 getSectionBucketnull177 override fun getSectionBucket(): Int { 178 return entry.bucket 179 } 180 isAmbientnull181 override fun isAmbient(): Boolean { 182 return entry.ranking.isAmbient 183 } 184 getPeopleNotificationTypenull185 override fun getPeopleNotificationType(): Int { 186 return peopleNotificationIdentifier.getPeopleNotificationType(entry) 187 } 188 isPromotedOngoingnull189 override fun isPromotedOngoing(): Boolean { 190 return entry.isPromotedOngoing 191 } 192 isFullScreenCapablenull193 override fun isFullScreenCapable(): Boolean { 194 return entry.sbn.notification.fullScreenIntent != null 195 } 196 onDragSuccessnull197 override fun onDragSuccess() { 198 notificationActivityStarter.onDragSuccess(entry) 199 } 200 onNotificationBubbleIconClickednull201 override fun onNotificationBubbleIconClicked() { 202 notificationActivityStarter.onNotificationBubbleIconClicked(entry) 203 } 204 onNotificationActionClickednull205 override fun onNotificationActionClicked() { 206 notificationActionClickManager.onNotificationActionClicked(entry) 207 } 208 getDismissStatenull209 override fun getDismissState(): NotificationEntry.DismissState { 210 return entry.dismissState 211 } 212 onEntryClickednull213 override fun onEntryClicked(row: ExpandableNotificationRow) { 214 notificationActivityStarter.onNotificationClicked(entry, row) 215 } 216 } 217