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.dagger.SysUISingleton 21 import com.android.systemui.people.widget.PeopleSpaceWidgetManager 22 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption 23 import com.android.systemui.flags.FeatureFlags 24 import com.android.systemui.statusbar.NotificationListener 25 import com.android.systemui.statusbar.NotificationPresenter 26 import com.android.systemui.statusbar.notification.AnimatedImageNotificationManager 27 import com.android.systemui.statusbar.notification.NotificationActivityStarter 28 import com.android.systemui.statusbar.notification.NotificationClicker 29 import com.android.systemui.statusbar.notification.NotificationEntryManager 30 import com.android.systemui.statusbar.notification.NotificationListController 31 import com.android.systemui.statusbar.notification.collection.NotifPipeline 32 import com.android.systemui.statusbar.notification.collection.NotificationRankingManager 33 import com.android.systemui.statusbar.notification.collection.TargetSdkResolver 34 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl 35 import com.android.systemui.statusbar.notification.collection.init.NotifPipelineInitializer 36 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy 37 import com.android.systemui.statusbar.notification.interruption.HeadsUpController 38 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder 39 import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer 40 import com.android.systemui.statusbar.notification.stack.NotificationListContainer 41 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper 42 import com.android.systemui.statusbar.phone.StatusBar 43 import com.android.systemui.statusbar.policy.DeviceProvisionedController 44 import com.android.systemui.statusbar.policy.HeadsUpManager 45 import com.android.systemui.statusbar.policy.RemoteInputUriController 46 import com.android.wm.shell.bubbles.Bubbles 47 import dagger.Lazy 48 import java.io.FileDescriptor 49 import java.io.PrintWriter 50 import java.util.Optional 51 import javax.inject.Inject 52 53 /** 54 * Master controller for all notifications-related work 55 * 56 * At the moment exposes a number of event-handler-esque methods; these are for historical reasons. 57 * Once we migrate away from the need for such things, this class becomes primarily a place to do 58 * any initialization work that notifications require. 59 */ 60 @SysUISingleton 61 class NotificationsControllerImpl @Inject constructor( 62 private val featureFlags: FeatureFlags, 63 private val notificationListener: NotificationListener, 64 private val entryManager: NotificationEntryManager, 65 private val legacyRanker: NotificationRankingManager, 66 private val notifPipeline: Lazy<NotifPipeline>, 67 private val targetSdkResolver: TargetSdkResolver, 68 private val newNotifPipeline: Lazy<NotifPipelineInitializer>, 69 private val notifBindPipelineInitializer: NotifBindPipelineInitializer, 70 private val deviceProvisionedController: DeviceProvisionedController, 71 private val notificationRowBinder: NotificationRowBinderImpl, 72 private val remoteInputUriController: RemoteInputUriController, 73 private val groupManagerLegacy: Lazy<NotificationGroupManagerLegacy>, 74 private val groupAlertTransferHelper: NotificationGroupAlertTransferHelper, 75 private val headsUpManager: HeadsUpManager, 76 private val headsUpController: HeadsUpController, 77 private val headsUpViewBinder: HeadsUpViewBinder, 78 private val clickerBuilder: NotificationClicker.Builder, 79 private val animatedImageNotificationManager: AnimatedImageNotificationManager, 80 private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager 81 ) : NotificationsController { 82 83 override fun initialize( 84 statusBar: StatusBar, 85 bubblesOptional: Optional<Bubbles>, 86 presenter: NotificationPresenter, 87 listContainer: NotificationListContainer, 88 notificationActivityStarter: NotificationActivityStarter, 89 bindRowCallback: NotificationRowBinderImpl.BindRowCallback 90 ) { 91 notificationListener.registerAsSystemService() 92 93 val listController = 94 NotificationListController( 95 entryManager, 96 listContainer, 97 deviceProvisionedController) 98 listController.bind() 99 100 notificationRowBinder.setNotificationClicker( 101 clickerBuilder.build( 102 Optional.of(statusBar), bubblesOptional, notificationActivityStarter)) 103 notificationRowBinder.setUpWithPresenter( 104 presenter, 105 listContainer, 106 bindRowCallback) 107 headsUpViewBinder.setPresenter(presenter) 108 notifBindPipelineInitializer.initialize() 109 animatedImageNotificationManager.bind() 110 111 if (featureFlags.isNewNotifPipelineEnabled) { 112 newNotifPipeline.get().initialize( 113 notificationListener, 114 notificationRowBinder, 115 listContainer) 116 } 117 118 if (featureFlags.isNewNotifPipelineRenderingEnabled) { 119 targetSdkResolver.initialize(notifPipeline.get()) 120 // TODO 121 } else { 122 targetSdkResolver.initialize(entryManager) 123 remoteInputUriController.attach(entryManager) 124 groupAlertTransferHelper.bind(entryManager, groupManagerLegacy.get()) 125 headsUpManager.addListener(groupManagerLegacy.get()) 126 headsUpManager.addListener(groupAlertTransferHelper) 127 headsUpController.attach(entryManager, headsUpManager) 128 groupManagerLegacy.get().setHeadsUpManager(headsUpManager) 129 groupAlertTransferHelper.setHeadsUpManager(headsUpManager) 130 131 entryManager.initialize(notificationListener, legacyRanker) 132 } 133 134 peopleSpaceWidgetManager.attach(notificationListener) 135 } 136 137 override fun dump( 138 fd: FileDescriptor, 139 pw: PrintWriter, 140 args: Array<String>, 141 dumpTruck: Boolean 142 ) { 143 if (dumpTruck) { 144 entryManager.dump(pw, " ") 145 } 146 } 147 148 // TODO: Convert all functions below this line into listeners instead of public methods 149 150 override fun requestNotificationUpdate(reason: String) { 151 entryManager.updateNotifications(reason) 152 } 153 154 override fun resetUserExpandedStates() { 155 for (entry in entryManager.visibleNotifications) { 156 entry.resetUserExpansion() 157 } 158 } 159 160 override fun setNotificationSnoozed(sbn: StatusBarNotification, snoozeOption: SnoozeOption) { 161 if (snoozeOption.snoozeCriterion != null) { 162 notificationListener.snoozeNotification(sbn.key, snoozeOption.snoozeCriterion.id) 163 } else { 164 notificationListener.snoozeNotification( 165 sbn.key, 166 snoozeOption.minutesToSnoozeFor * 60 * 1000.toLong()) 167 } 168 } 169 170 override fun getActiveNotificationsCount(): Int { 171 return entryManager.activeNotificationsCount 172 } 173 } 174