1 /*
2  * Copyright (C) 2022 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.shade
18 
19 import com.android.systemui.common.buffer.RingBuffer
20 import com.android.systemui.dump.DumpsysTableLogger
21 import com.android.systemui.dump.Row
22 import com.android.systemui.shade.NotificationShadeWindowState.Buffer
23 import com.android.systemui.statusbar.StatusBarState
24 
25 /**
26  * Represents state of shade window, used by [NotificationShadeWindowControllerImpl]. Contains
27  * nested class [Buffer] for pretty table logging in bug reports.
28  */
29 class NotificationShadeWindowState(
30     @JvmField var keyguardShowing: Boolean = false,
31     @JvmField var keyguardOccluded: Boolean = false,
32     @JvmField var keyguardNeedsInput: Boolean = false,
33     @JvmField var panelVisible: Boolean = false,
34     /** shade panel is expanded (expansion fraction > 0) */
35     @JvmField var panelExpanded: Boolean = false,
36     @JvmField var notificationShadeFocusable: Boolean = false,
37     @JvmField var bouncerShowing: Boolean = false,
38     @JvmField var keyguardFadingAway: Boolean = false,
39     @JvmField var keyguardGoingAway: Boolean = false,
40     @JvmField var qsExpanded: Boolean = false,
41     @JvmField var headsUpNotificationShowing: Boolean = false,
42     @JvmField var lightRevealScrimOpaque: Boolean = false,
43     @JvmField var forceWindowCollapsed: Boolean = false,
44     @JvmField var forceDozeBrightness: Boolean = false,
45     // TODO: forceUserActivity seems to be unused, delete?
46     @JvmField var forceUserActivity: Boolean = false,
47     @JvmField var launchingActivityFromNotification: Boolean = false,
48     @JvmField var mediaBackdropShowing: Boolean = false,
49     @JvmField var windowNotTouchable: Boolean = false,
50     @JvmField var componentsForcingTopUi: MutableSet<String> = mutableSetOf(),
51     @JvmField var forceOpenTokens: MutableSet<Any> = mutableSetOf(),
52     /** one of [StatusBarState] */
53     @JvmField var statusBarState: Int = 0,
54     @JvmField var remoteInputActive: Boolean = false,
55     @JvmField var forcePluginOpen: Boolean = false,
56     @JvmField var dozing: Boolean = false,
57     @JvmField var dreaming: Boolean = false,
58     @JvmField var scrimsVisibility: Int = 0,
59     @JvmField var backgroundBlurRadius: Int = 0,
60 ) {
61 
62     fun isKeyguardShowingAndNotOccluded(): Boolean {
63         return keyguardShowing && !keyguardOccluded
64     }
65 
66     /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
67     val asStringList: List<String> by lazy {
68         listOf(
69             keyguardShowing.toString(),
70             keyguardOccluded.toString(),
71             keyguardNeedsInput.toString(),
72             panelVisible.toString(),
73             panelExpanded.toString(),
74             notificationShadeFocusable.toString(),
75             bouncerShowing.toString(),
76             keyguardFadingAway.toString(),
77             keyguardGoingAway.toString(),
78             qsExpanded.toString(),
79             headsUpNotificationShowing.toString(),
80             lightRevealScrimOpaque.toString(),
81             forceWindowCollapsed.toString(),
82             forceDozeBrightness.toString(),
83             forceUserActivity.toString(),
84             launchingActivityFromNotification.toString(),
85             mediaBackdropShowing.toString(),
86             windowNotTouchable.toString(),
87             componentsForcingTopUi.toString(),
88             forceOpenTokens.toString(),
89             StatusBarState.toString(statusBarState),
90             remoteInputActive.toString(),
91             forcePluginOpen.toString(),
92             dozing.toString(),
93             scrimsVisibility.toString(),
94             backgroundBlurRadius.toString()
95         )
96     }
97 
98     /**
99      * [RingBuffer] to store [NotificationShadeWindowState]. After the buffer is full, it will
100      * recycle old events.
101      */
102     class Buffer(capacity: Int) {
103 
104         private val buffer = RingBuffer(capacity) { NotificationShadeWindowState() }
105 
106         /** Insert a new element in the buffer. */
107         fun insert(
108             keyguardShowing: Boolean,
109             keyguardOccluded: Boolean,
110             keyguardNeedsInput: Boolean,
111             panelVisible: Boolean,
112             panelExpanded: Boolean,
113             notificationShadeFocusable: Boolean,
114             bouncerShowing: Boolean,
115             keyguardFadingAway: Boolean,
116             keyguardGoingAway: Boolean,
117             qsExpanded: Boolean,
118             headsUpShowing: Boolean,
119             lightRevealScrimOpaque: Boolean,
120             forceCollapsed: Boolean,
121             forceDozeBrightness: Boolean,
122             forceUserActivity: Boolean,
123             launchingActivity: Boolean,
124             backdropShowing: Boolean,
125             notTouchable: Boolean,
126             componentsForcingTopUi: MutableSet<String>,
127             forceOpenTokens: MutableSet<Any>,
128             statusBarState: Int,
129             remoteInputActive: Boolean,
130             forcePluginOpen: Boolean,
131             dozing: Boolean,
132             scrimsVisibility: Int,
133             backgroundBlurRadius: Int,
134         ) {
135             buffer.advance().apply {
136                 this.keyguardShowing = keyguardShowing
137                 this.keyguardOccluded = keyguardOccluded
138                 this.keyguardNeedsInput = keyguardNeedsInput
139                 this.panelVisible = panelVisible
140                 this.panelExpanded = panelExpanded
141                 this.notificationShadeFocusable = notificationShadeFocusable
142                 this.bouncerShowing = bouncerShowing
143                 this.keyguardFadingAway = keyguardFadingAway
144                 this.keyguardGoingAway = keyguardGoingAway
145                 this.qsExpanded = qsExpanded
146                 this.headsUpNotificationShowing = headsUpShowing
147                 this.lightRevealScrimOpaque = lightRevealScrimOpaque
148                 this.forceWindowCollapsed = forceCollapsed
149                 this.forceDozeBrightness = forceDozeBrightness
150                 this.forceUserActivity = forceUserActivity
151                 this.launchingActivityFromNotification = launchingActivity
152                 this.mediaBackdropShowing = backdropShowing
153                 this.windowNotTouchable = notTouchable
154                 this.componentsForcingTopUi.clear()
155                 this.componentsForcingTopUi.addAll(componentsForcingTopUi)
156                 this.forceOpenTokens.clear()
157                 this.forceOpenTokens.addAll(forceOpenTokens)
158                 this.statusBarState = statusBarState
159                 this.remoteInputActive = remoteInputActive
160                 this.forcePluginOpen = forcePluginOpen
161                 this.dozing = dozing
162                 this.scrimsVisibility = scrimsVisibility
163                 this.backgroundBlurRadius = backgroundBlurRadius
164             }
165         }
166 
167         /**
168          * Returns the content of the buffer (sorted from latest to newest).
169          *
170          * @see [NotificationShadeWindowState.asStringList]
171          */
172         fun toList(): List<Row> {
173             return buffer.map { it.asStringList }
174         }
175     }
176 
177     companion object {
178         /** Headers for dumping a table using [DumpsysTableLogger]. */
179         @JvmField
180         val TABLE_HEADERS =
181             listOf(
182                 "keyguardShowing",
183                 "keyguardOccluded",
184                 "keyguardNeedsInput",
185                 "panelVisible",
186                 "panelExpanded",
187                 "notificationShadeFocusable",
188                 "bouncerShowing",
189                 "keyguardFadingAway",
190                 "keyguardGoingAway",
191                 "qsExpanded",
192                 "headsUpShowing",
193                 "lightRevealScrimOpaque",
194                 "forceCollapsed",
195                 "forceDozeBrightness",
196                 "forceUserActivity",
197                 "launchingActivity",
198                 "backdropShowing",
199                 "notTouchable",
200                 "componentsForcingTopUi",
201                 "forceOpenTokens",
202                 "statusBarState",
203                 "remoteInputActive",
204                 "forcePluginOpen",
205                 "dozing",
206                 "scrimsVisibility",
207                 "backgroundBlurRadius"
208             )
209     }
210 }
211