1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar
import android.app.StatusBarManager.DISABLE_BACK
import android.app.StatusBarManager.DISABLE_CLOCK
import android.app.StatusBarManager.DISABLE_EXPAND
import android.app.StatusBarManager.DISABLE_HOME
import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS
import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS
import android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP
import android.app.StatusBarManager.DISABLE_RECENT
import android.app.StatusBarManager.DISABLE_SEARCH
import android.app.StatusBarManager.DISABLE_SYSTEM_INFO
import android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS
import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
import android.app.StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS
import android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS
import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject
/**
* A singleton that creates concise but readable strings representing the values of the disable
* flags for debugging.
*
* See [CommandQueue.disable] for information about disable flags.
*
* Note that, for both lists passed in, each flag must have a distinct [DisableFlag.flagIsSetSymbol]
* and distinct [DisableFlag.flagNotSetSymbol] within the list. If this isn't true, the logs could
* be ambiguous so an [IllegalArgumentException] is thrown.
*/
@SysUISingleton
class DisableFlagsLogger constructor(
private val disable1FlagsList: List<DisableFlag>,
private val disable2FlagsList: List<DisableFlag>
) {
@Inject
constructor() : this(defaultDisable1FlagsList, defaultDisable2FlagsList)
init {
if (flagsListHasDuplicateSymbols(disable1FlagsList)) {
throw IllegalArgumentException("disable1 flags must have unique symbols")
}
if (flagsListHasDuplicateSymbols(disable2FlagsList)) {
throw IllegalArgumentException("disable2 flags must have unique symbols")
}
}
private fun flagsListHasDuplicateSymbols(list: List<DisableFlag>): Boolean {
val numDistinctFlagOffStatus = list.map { it.getFlagStatus(0) }.distinct().count()
val numDistinctFlagOnStatus = list
.map { it.getFlagStatus(Int.MAX_VALUE) }
.distinct()
.count()
return numDistinctFlagOffStatus < list.count() || numDistinctFlagOnStatus < list.count()
}
/**
* Returns a string representing the, old, new, and new-after-modification disable flag states,
* as well as the differences between each of the states.
*
* Example:
* Old: EnaiHbcRso.qINgr | New: EnaihBcRso.qiNGR (hB.iGR) | New after local modification:
* EnaihBcRso.qInGR (.n)
*
* A capital character signifies the flag is set and a lowercase character signifies that the
* flag isn't set. The flag states will be logged in the same order as the passed-in lists.
*
* The difference between states is written between parentheses, and won't be included if there
* is no difference. the new-after-modification state also won't be included if there's no
* difference from the new state.
*
* @param old the disable state that had been previously sent. Null if we don't need to log the
* previously sent state.
* @param new the new disable state that has just been sent.
* @param newAfterLocalModification the new disable states after a class has locally modified
* them. Null if the class does not locally modify.
*/
fun getDisableFlagsString(
old: DisableState? = null,
new: DisableState,
newAfterLocalModification: DisableState? = null
): String {
val builder = StringBuilder("Received new disable state. ")
old?.let {
builder.append("Old: ")
builder.append(getFlagsString(old))
builder.append(" | ")
}
builder.append("New: ")
if (old != null && old != new) {
builder.append(getFlagsStringWithDiff(old, new))
} else {
builder.append(getFlagsString(new))
}
if (newAfterLocalModification != null && new != newAfterLocalModification) {
builder.append(" | New after local modification: ")
builder.append(getFlagsStringWithDiff(new, newAfterLocalModification))
}
return builder.toString()
}
/**
* Returns a string representing [new] state, as well as the difference from [old] to [new]
* (if there is one).
*/
private fun getFlagsStringWithDiff(old: DisableState, new: DisableState): String {
val builder = StringBuilder()
builder.append(getFlagsString(new))
builder.append(" ")
builder.append(getDiffString(old, new))
return builder.toString()
}
/**
* Returns a string representing the difference between [old] and [new], or an empty string if
* there is no difference.
*
* For example, if old was "abc.DE" and new was "aBC.De", the difference returned would be
* "(BC.e)".
*/
private fun getDiffString(old: DisableState, new: DisableState): String {
if (old == new) {
return ""
}
val builder = StringBuilder("(")
disable1FlagsList.forEach {
val newSymbol = it.getFlagStatus(new.disable1)
if (it.getFlagStatus(old.disable1) != newSymbol) {
builder.append(newSymbol)
}
}
builder.append(".")
disable2FlagsList.forEach {
val newSymbol = it.getFlagStatus(new.disable2)
if (it.getFlagStatus(old.disable2) != newSymbol) {
builder.append(newSymbol)
}
}
builder.append(")")
return builder.toString()
}
/** Returns a string representing the disable flag states, e.g. "EnaihBcRso.qiNGR". */
private fun getFlagsString(state: DisableState): String {
val builder = StringBuilder("")
disable1FlagsList.forEach { builder.append(it.getFlagStatus(state.disable1)) }
builder.append(".")
disable2FlagsList.forEach { builder.append(it.getFlagStatus(state.disable2)) }
return builder.toString()
}
/** A POJO representing each disable flag. */
class DisableFlag(
private val bitMask: Int,
private val flagIsSetSymbol: Char,
private val flagNotSetSymbol: Char
) {
/**
* Returns a character representing whether or not this flag is set in [state].
*
* A capital character signifies the flag is set and a lowercase character signifies that
* the flag isn't set.
*/
internal fun getFlagStatus(state: Int): Char =
if (0 != state and this.bitMask) this.flagIsSetSymbol
else this.flagNotSetSymbol
}
/** POJO to hold [disable1] and [disable2]. */
data class DisableState(val disable1: Int, val disable2: Int)
}
// LINT.IfChange
private val defaultDisable1FlagsList: List<DisableFlagsLogger.DisableFlag> = listOf(
DisableFlagsLogger.DisableFlag(DISABLE_EXPAND, 'E', 'e'),
DisableFlagsLogger.DisableFlag(DISABLE_NOTIFICATION_ICONS, 'N', 'n'),
DisableFlagsLogger.DisableFlag(DISABLE_NOTIFICATION_ALERTS, 'A', 'a'),
DisableFlagsLogger.DisableFlag(DISABLE_SYSTEM_INFO, 'I', 'i'),
DisableFlagsLogger.DisableFlag(DISABLE_HOME, 'H', 'h'),
DisableFlagsLogger.DisableFlag(DISABLE_BACK, 'B', 'b'),
DisableFlagsLogger.DisableFlag(DISABLE_CLOCK, 'C', 'c'),
DisableFlagsLogger.DisableFlag(DISABLE_RECENT, 'R', 'r'),
DisableFlagsLogger.DisableFlag(DISABLE_SEARCH, 'S', 's'),
DisableFlagsLogger.DisableFlag(DISABLE_ONGOING_CALL_CHIP, 'O', 'o')
)
private val defaultDisable2FlagsList: List<DisableFlagsLogger.DisableFlag> = listOf(
DisableFlagsLogger.DisableFlag(DISABLE2_QUICK_SETTINGS, 'Q', 'q'),
DisableFlagsLogger.DisableFlag(DISABLE2_SYSTEM_ICONS, 'I', 'i'),
DisableFlagsLogger.DisableFlag(DISABLE2_NOTIFICATION_SHADE, 'N', 'n'),
DisableFlagsLogger.DisableFlag(DISABLE2_GLOBAL_ACTIONS, 'G', 'g'),
DisableFlagsLogger.DisableFlag(DISABLE2_ROTATE_SUGGESTIONS, 'R', 'r')
)
// LINT.ThenChange(frameworks/base/core/java/android/app/StatusBarManager.java)
|