1 /*
2  * Copyright (C) 2019 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 package com.android.systemui.statusbar.notification.collection.coordinator
17 
18 import com.android.systemui.Dumpable
19 import com.android.systemui.dump.DumpManager
20 import com.android.systemui.flags.FeatureFlags
21 import com.android.systemui.statusbar.notification.collection.NotifPipeline
22 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
23 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
24 import java.io.FileDescriptor
25 import java.io.PrintWriter
26 import java.util.ArrayList
27 import javax.inject.Inject
28 
29 /**
30  * Handles the attachment of [Coordinator]s to the [NotifPipeline] so that the
31  * Coordinators can register their respective callbacks.
32  */
33 interface NotifCoordinators : Coordinator, Dumpable
34 
35 @CoordinatorScope
36 class NotifCoordinatorsImpl @Inject constructor(
37     dumpManager: DumpManager,
38     featureFlags: FeatureFlags,
39     hideLocallyDismissedNotifsCoordinator: HideLocallyDismissedNotifsCoordinator,
40     hideNotifsForOtherUsersCoordinator: HideNotifsForOtherUsersCoordinator,
41     keyguardCoordinator: KeyguardCoordinator,
42     rankingCoordinator: RankingCoordinator,
43     appOpsCoordinator: AppOpsCoordinator,
44     deviceProvisionedCoordinator: DeviceProvisionedCoordinator,
45     bubbleCoordinator: BubbleCoordinator,
46     headsUpCoordinator: HeadsUpCoordinator,
47     gutsCoordinator: GutsCoordinator,
48     conversationCoordinator: ConversationCoordinator,
49     preparationCoordinator: PreparationCoordinator,
50     mediaCoordinator: MediaCoordinator,
51     remoteInputCoordinator: RemoteInputCoordinator,
52     shadeEventCoordinator: ShadeEventCoordinator,
53     smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
54     viewConfigCoordinator: ViewConfigCoordinator,
55     visualStabilityCoordinator: VisualStabilityCoordinator,
56     sensitiveContentCoordinator: SensitiveContentCoordinator
57 ) : NotifCoordinators {
58 
59     private val mCoordinators: MutableList<Coordinator> = ArrayList()
60     private val mOrderedSections: MutableList<NotifSectioner> = ArrayList()
61 
62     /**
63      * Creates all the coordinators.
64      */
65     init {
66         dumpManager.registerDumpable(TAG, this)
67         mCoordinators.add(hideLocallyDismissedNotifsCoordinator)
68         mCoordinators.add(hideNotifsForOtherUsersCoordinator)
69         mCoordinators.add(keyguardCoordinator)
70         mCoordinators.add(rankingCoordinator)
71         mCoordinators.add(appOpsCoordinator)
72         mCoordinators.add(deviceProvisionedCoordinator)
73         mCoordinators.add(bubbleCoordinator)
74         mCoordinators.add(conversationCoordinator)
75         mCoordinators.add(mediaCoordinator)
76         mCoordinators.add(shadeEventCoordinator)
77         mCoordinators.add(viewConfigCoordinator)
78         mCoordinators.add(visualStabilityCoordinator)
79         mCoordinators.add(sensitiveContentCoordinator)
80         if (featureFlags.isSmartspaceDedupingEnabled) {
81             mCoordinators.add(smartspaceDedupingCoordinator)
82         }
83         if (featureFlags.isNewNotifPipelineRenderingEnabled) {
84             mCoordinators.add(headsUpCoordinator)
85             mCoordinators.add(gutsCoordinator)
86             mCoordinators.add(preparationCoordinator)
87             mCoordinators.add(remoteInputCoordinator)
88         }
89 
90         // Manually add Ordered Sections
91         // HeadsUp > FGS > People > Alerting > Silent > Unknown/Default
92         if (featureFlags.isNewNotifPipelineRenderingEnabled) {
93             mOrderedSections.add(headsUpCoordinator.sectioner) // HeadsUp
94         }
95         mOrderedSections.add(appOpsCoordinator.sectioner) // ForegroundService
96         mOrderedSections.add(conversationCoordinator.sectioner) // People
97         mOrderedSections.add(rankingCoordinator.alertingSectioner) // Alerting
98         mOrderedSections.add(rankingCoordinator.silentSectioner) // Silent
99     }
100 
101     /**
102      * Sends the pipeline to each coordinator when the pipeline is ready to accept
103      * [Pluggable]s, [NotifCollectionListener]s and [NotifLifetimeExtender]s.
104      */
105     override fun attach(pipeline: NotifPipeline) {
106         for (c in mCoordinators) {
107             c.attach(pipeline)
108         }
109         pipeline.setSections(mOrderedSections)
110     }
111 
112     override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
113         pw.println()
114         pw.println("$TAG:")
115         for (c in mCoordinators) {
116             pw.println("\t${c.javaClass}")
117         }
118         for (s in mOrderedSections) {
119             pw.println("\t${s.name}")
120         }
121     }
122 
123     companion object {
124         private const val TAG = "NotifCoordinators"
125     }
126 }