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