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 package com.android.systemui.statusbar.notification.collection.listbuilder.pluggable
17 
18 import com.android.systemui.statusbar.notification.collection.GroupEntry
19 import com.android.systemui.statusbar.notification.collection.ListEntry
20 import com.android.systemui.statusbar.notification.collection.NotificationEntry
21 
22 /**
23  * Pluggable for participating in notif stabilization. In particular, suppressing group and
24  * section changes.
25  *
26  * The stability manager should be invalidated when previously suppressed a group or
27  * section change is now allowed.
28  */
29 abstract class NotifStabilityManager protected constructor(name: String) :
30     Pluggable<NotifStabilityManager>(name) {
31 
32     /**
33      * Called prior to running the pipeline to suppress any visual changes. Ex: collapse animation
34      * is playing, moving stuff around simultaneously will look janky.
35      *
36      * Note: this is invoked *before* [onBeginRun], so that implementors can reference state
37      * maintained from a previous run.
38      */
isPipelineRunAllowednull39     abstract fun isPipelineRunAllowed(): Boolean
40 
41     /**
42      * Called at the beginning of every pipeline run to perform any necessary cleanup from the
43      * previous run.
44      */
45     abstract fun onBeginRun()
46 
47     /**
48      * Returns whether this notification can currently change groups/parents.
49      * Per iteration of the notification pipeline, locally stores this information until the next
50      * run of the pipeline. When this method returns false, it's expected that a group change for
51      * this entry is being suppressed.
52      */
53     abstract fun isGroupChangeAllowed(entry: NotificationEntry): Boolean
54 
55     /**
56      * Returns whether this notification group can be pruned for not having enough children.
57      * Per iteration of the notification pipeline, locally stores this information until the next
58      * run of the pipeline. When this method returns false, it's expected that a group prune for
59      * this entry is being suppressed.
60      */
61     abstract fun isGroupPruneAllowed(entry: GroupEntry): Boolean
62 
63     /**
64      * Returns whether this notification entry can currently change sections.
65      * Per iteration of the notification pipeline, locally stores this information until the next
66      * run of the pipeline. When this method returns false, it's expected that a section change is
67      * being suppressed.
68      */
69     abstract fun isSectionChangeAllowed(entry: NotificationEntry): Boolean
70 
71     /**
72      * Returns whether this list entry is allowed to be reordered within its section.
73      * Unlike [isGroupChangeAllowed] or [isSectionChangeAllowed], this method is called on every
74      * entry, so an implementation may not assume that returning false means an order change is
75      * being suppressed. However, if an order change is suppressed, that will be reported to ths
76      * implementation by calling [onEntryReorderSuppressed] after ordering is complete.
77      */
78     abstract fun isEntryReorderingAllowed(entry: ListEntry): Boolean
79 
80     /**
81      * Called by the pipeline to determine if every call to the other stability methods would
82      * return true, regardless of parameters.  This allows the pipeline to skip any pieces of
83      * work related to stability.
84      *
85      * @return true if all other methods will return true for any parameters.
86      */
87     abstract fun isEveryChangeAllowed(): Boolean
88 
89     /**
90      * Called by the pipeline to inform the stability manager that an entry reordering was indeed
91      * suppressed as the result of a previous call to [.isEntryReorderingAllowed].
92      */
93     abstract fun onEntryReorderSuppressed()
94 }
95 
96 /** The default, no-op instance of the stability manager which always allows all changes */
97 object DefaultNotifStabilityManager : NotifStabilityManager("DefaultNotifStabilityManager") {
98     override fun isPipelineRunAllowed(): Boolean = true
99     override fun onBeginRun() {}
100     override fun isGroupChangeAllowed(entry: NotificationEntry): Boolean = true
101     override fun isGroupPruneAllowed(entry: GroupEntry): Boolean = true
102     override fun isSectionChangeAllowed(entry: NotificationEntry): Boolean = true
103     override fun isEntryReorderingAllowed(entry: ListEntry): Boolean = true
104     override fun isEveryChangeAllowed(): Boolean = true
105     override fun onEntryReorderSuppressed() {}
106 }
107