1 /* 2 * Copyright (C) 2020 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.init 18 19 import android.service.notification.StatusBarNotification 20 import com.android.systemui.ForegroundServiceNotificationListener 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.flags.FeatureFlags 23 import com.android.systemui.flags.Flags 24 import com.android.systemui.people.widget.PeopleSpaceWidgetManager 25 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption 26 import com.android.systemui.statusbar.NotificationListener 27 import com.android.systemui.statusbar.NotificationMediaManager 28 import com.android.systemui.statusbar.NotificationPresenter 29 import com.android.systemui.statusbar.notification.AnimatedImageNotificationManager 30 import com.android.systemui.statusbar.notification.NotificationActivityStarter 31 import com.android.systemui.statusbar.notification.NotificationClicker 32 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore 33 import com.android.systemui.statusbar.notification.collection.NotifPipeline 34 import com.android.systemui.statusbar.notification.collection.NotificationEntry 35 import com.android.systemui.statusbar.notification.collection.TargetSdkResolver 36 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl 37 import com.android.systemui.statusbar.notification.collection.init.NotifPipelineInitializer 38 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection 39 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener 40 import com.android.systemui.statusbar.notification.collection.render.NotifStackController 41 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder 42 import com.android.systemui.statusbar.notification.logging.NotificationLogger 43 import com.android.systemui.statusbar.notification.logging.NotificationMemoryMonitor 44 import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer 45 import com.android.systemui.statusbar.notification.stack.NotificationListContainer 46 import com.android.systemui.statusbar.phone.CentralSurfaces 47 import com.android.wm.shell.bubbles.Bubbles 48 import dagger.Lazy 49 import java.util.Optional 50 import javax.inject.Inject 51 52 /** 53 * Master controller for all notifications-related work 54 * 55 * At the moment exposes a number of event-handler-esque methods; these are for historical reasons. 56 * Once we migrate away from the need for such things, this class becomes primarily a place to do 57 * any initialization work that notifications require. 58 */ 59 @SysUISingleton 60 class NotificationsControllerImpl @Inject constructor( 61 private val notificationListener: NotificationListener, 62 private val commonNotifCollection: Lazy<CommonNotifCollection>, 63 private val notifPipeline: Lazy<NotifPipeline>, 64 private val notifLiveDataStore: NotifLiveDataStore, 65 private val targetSdkResolver: TargetSdkResolver, 66 private val notifPipelineInitializer: Lazy<NotifPipelineInitializer>, 67 private val notifBindPipelineInitializer: NotifBindPipelineInitializer, 68 private val notificationLogger: NotificationLogger, 69 private val notificationRowBinder: NotificationRowBinderImpl, 70 private val notificationsMediaManager: NotificationMediaManager, 71 private val headsUpViewBinder: HeadsUpViewBinder, 72 private val clickerBuilder: NotificationClicker.Builder, 73 private val animatedImageNotificationManager: AnimatedImageNotificationManager, 74 private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager, 75 private val bubblesOptional: Optional<Bubbles>, 76 private val fgsNotifListener: ForegroundServiceNotificationListener, 77 private val memoryMonitor: Lazy<NotificationMemoryMonitor>, 78 private val featureFlags: FeatureFlags 79 ) : NotificationsController { 80 initializenull81 override fun initialize( 82 centralSurfaces: CentralSurfaces, 83 presenter: NotificationPresenter, 84 listContainer: NotificationListContainer, 85 stackController: NotifStackController, 86 notificationActivityStarter: NotificationActivityStarter, 87 bindRowCallback: NotificationRowBinderImpl.BindRowCallback 88 ) { 89 notificationListener.registerAsSystemService() 90 91 notifPipeline.get().addCollectionListener(object : NotifCollectionListener { 92 override fun onEntryRemoved(entry: NotificationEntry, reason: Int) { 93 listContainer.cleanUpViewStateForEntry(entry) 94 } 95 }) 96 97 notificationRowBinder.setNotificationClicker( 98 clickerBuilder.build( 99 Optional.ofNullable(centralSurfaces), bubblesOptional, 100 notificationActivityStarter)) 101 notificationRowBinder.setUpWithPresenter( 102 presenter, 103 listContainer, 104 bindRowCallback) 105 headsUpViewBinder.setPresenter(presenter) 106 notifBindPipelineInitializer.initialize() 107 animatedImageNotificationManager.bind() 108 109 notifPipelineInitializer.get().initialize( 110 notificationListener, 111 notificationRowBinder, 112 listContainer, 113 stackController) 114 115 targetSdkResolver.initialize(notifPipeline.get()) 116 notificationsMediaManager.setUpWithPresenter(presenter) 117 notificationLogger.setUpWithContainer(listContainer) 118 peopleSpaceWidgetManager.attach(notificationListener) 119 fgsNotifListener.init() 120 if (featureFlags.isEnabled(Flags.NOTIFICATION_MEMORY_MONITOR_ENABLED)) { 121 memoryMonitor.get().init() 122 } 123 } 124 125 // TODO: Convert all functions below this line into listeners instead of public methods 126 resetUserExpandedStatesnull127 override fun resetUserExpandedStates() { 128 // TODO: this is a view thing that should be done through the views, but that means doing it 129 // both when this event is fired and any time a row is attached. 130 for (entry in commonNotifCollection.get().allNotifs) { 131 entry.resetUserExpansion() 132 } 133 } 134 setNotificationSnoozednull135 override fun setNotificationSnoozed(sbn: StatusBarNotification, snoozeOption: SnoozeOption) { 136 if (snoozeOption.snoozeCriterion != null) { 137 notificationListener.snoozeNotification(sbn.key, snoozeOption.snoozeCriterion.id) 138 } else { 139 notificationListener.snoozeNotification( 140 sbn.key, 141 snoozeOption.minutesToSnoozeFor * 60 * 1000.toLong()) 142 } 143 } 144 getActiveNotificationsCountnull145 override fun getActiveNotificationsCount(): Int = 146 notifLiveDataStore.activeNotifCount.value 147 } 148