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.view.View
20 import java.lang.RuntimeException
21 import java.lang.StringBuilder
22
23 /**
24 * A controller that represents a single unit of addable/removable view(s) in the notification
25 * shade. Some nodes are just a single view (such as a header), while some might involve many views
26 * (such as a notification row).
27 *
28 * It's possible for nodes to support having child nodes (for example, some notification rows
29 * contain other notification rows). If so, they must implement all of the child-related methods
30 * below.
31 */
32 interface NodeController {
33
34 /** A string that uniquely(ish) represents the node in the tree. Used for debugging. */
35 val nodeLabel: String
36
37 val view: View
38
getChildAtnull39 fun getChildAt(index: Int): View? {
40 throw RuntimeException("Not supported")
41 }
42
getChildCountnull43 fun getChildCount(): Int = 0
44
45 /** Called to add a child to this view */
46 fun addChildAt(child: NodeController, index: Int) {
47 throw RuntimeException("Not supported")
48 }
49
50 /** Called to move one of this view's current children to a new position */
moveChildTonull51 fun moveChildTo(child: NodeController, index: Int) {
52 throw RuntimeException("Not supported")
53 }
54
55 /** Called to remove one of this view's current children */
removeChildnull56 fun removeChild(child: NodeController, isTransfer: Boolean) {
57 throw RuntimeException("Not supported")
58 }
59
60 /** Called when this view has been added */
onViewAddednull61 fun onViewAdded() {}
62
63 /** Called when this view has been moved */
onViewMovednull64 fun onViewMoved() {}
65
66 /** Called when this view has been removed */
onViewRemovednull67 fun onViewRemoved() {}
68
69 /**
70 * Called before removing a node from its parent
71 *
72 * If returned true, the ShadeViewDiffer won't detach this row and the view system is
73 * responsible for ensuring the row is in eventually removed from the parent.
74 *
75 * @return false to opt out from this feature
76 */
offerToKeepInParentForAnimationnull77 fun offerToKeepInParentForAnimation(): Boolean
78
79 /**
80 * Called before a node is reattached. Removes the view from its parent
81 * if it was flagged to be kept before.
82 *
83 * @return whether it did a removal
84 */
85 fun removeFromParentIfKeptForAnimation(): Boolean
86
87 /** Called when a node is being reattached */
88 fun resetKeepInParentForAnimation()
89 }
90
91 /**
92 * Used to specify the tree of [NodeController]s that currently make up the shade.
93 */
94 interface NodeSpec {
95 val parent: NodeSpec?
96 val controller: NodeController
97 val children: List<NodeSpec>
98 }
99
100 class NodeSpecImpl(
101 override val parent: NodeSpec?,
102 override val controller: NodeController
103 ) : NodeSpec {
104 override val children = mutableListOf<NodeSpec>()
105 }
106
107 /**
108 * Converts a tree spec to human-readable string, for dumping purposes.
109 */
treeSpecToStrnull110 fun treeSpecToStr(tree: NodeSpec): String {
111 return StringBuilder().also { treeSpecToStrHelper(tree, it, "") }.toString()
112 }
113
treeSpecToStrHelpernull114 private fun treeSpecToStrHelper(tree: NodeSpec, sb: StringBuilder, indent: String) {
115 sb.append("$indent{${tree.controller.nodeLabel}}\n")
116 if (tree.children.isNotEmpty()) {
117 val childIndent = "$indent "
118 for (child in tree.children) {
119 treeSpecToStrHelper(child, sb, childIndent)
120 }
121 }
122 }
123