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.collection.render
18 
19 import android.content.Context
20 import android.view.View
21 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
22 import com.android.systemui.statusbar.notification.collection.GroupEntry
23 import com.android.systemui.statusbar.notification.collection.ListEntry
24 import com.android.systemui.statusbar.notification.collection.NotificationEntry
25 import com.android.systemui.statusbar.notification.collection.PipelineDumpable
26 import com.android.systemui.statusbar.notification.collection.PipelineDumper
27 import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
28 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
29 import com.android.systemui.util.traceSection
30 import dagger.assisted.Assisted
31 import dagger.assisted.AssistedFactory
32 import dagger.assisted.AssistedInject
33 
34 /**
35  * Responsible for building and applying the "shade node spec": the list (tree) of things that
36  * currently populate the notification shade.
37  */
38 class ShadeViewManager @AssistedInject constructor(
39     context: Context,
40     @Assisted listContainer: NotificationListContainer,
41     @Assisted private val stackController: NotifStackController,
42     mediaContainerController: MediaContainerController,
43     featureManager: NotificationSectionsFeatureManager,
44     sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
45     nodeSpecBuilderLogger: NodeSpecBuilderLogger,
46     shadeViewDifferLogger: ShadeViewDifferLogger,
47     private val viewBarn: NotifViewBarn
48 ) : PipelineDumpable {
49     // We pass a shim view here because the listContainer may not actually have a view associated
50     // with it and the differ never actually cares about the root node's view.
51     private val rootController = RootNodeController(listContainer, View(context))
52     private val specBuilder = NodeSpecBuilder(mediaContainerController, featureManager,
53         sectionHeaderVisibilityProvider, viewBarn, nodeSpecBuilderLogger)
54     private val viewDiffer = ShadeViewDiffer(rootController, shadeViewDifferLogger)
55 
56     /** Method for attaching this manager to the pipeline. */
57     fun attach(renderStageManager: RenderStageManager) {
58         renderStageManager.setViewRenderer(viewRenderer)
59     }
60 
61     override fun dumpPipeline(d: PipelineDumper) = with(d) {
62         dump("rootController", rootController)
63         dump("specBuilder", specBuilder)
64         dump("viewDiffer", viewDiffer)
65     }
66 
67     private val viewRenderer = object : NotifViewRenderer {
68 
69         override fun onRenderList(notifList: List<ListEntry>) {
70             traceSection("ShadeViewManager.onRenderList") {
71                 viewDiffer.applySpec(specBuilder.buildNodeSpec(rootController, notifList))
72             }
73         }
74 
75         override fun getStackController(): NotifStackController = stackController
76 
77         override fun getGroupController(group: GroupEntry): NotifGroupController =
78             viewBarn.requireGroupController(group.requireSummary)
79 
80         override fun getRowController(entry: NotificationEntry): NotifRowController =
81             viewBarn.requireRowController(entry)
82     }
83 }
84 
85 @AssistedFactory
86 interface ShadeViewManagerFactory {
87     fun create(
88         listContainer: NotificationListContainer,
89         stackController: NotifStackController
90     ): ShadeViewManager
91 }
92