1 /*
2 * Copyright (C) 2019 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.qs.logging
18
19 import android.content.res.Configuration.ORIENTATION_LANDSCAPE
20 import android.content.res.Configuration.ORIENTATION_PORTRAIT
21 import android.content.res.Configuration.Orientation
22 import android.service.quicksettings.Tile
23 import android.view.View
24 import com.android.systemui.log.ConstantStringsLogger
25 import com.android.systemui.log.ConstantStringsLoggerImpl
26 import com.android.systemui.log.LogBuffer
27 import com.android.systemui.log.core.LogLevel.DEBUG
28 import com.android.systemui.log.core.LogLevel.ERROR
29 import com.android.systemui.log.core.LogLevel.VERBOSE
30 import com.android.systemui.log.dagger.QSConfigLog
31 import com.android.systemui.log.dagger.QSLog
32 import com.android.systemui.plugins.qs.QSTile
33 import com.android.systemui.statusbar.StatusBarState
34 import com.google.errorprone.annotations.CompileTimeConstant
35 import javax.inject.Inject
36
37 private const val TAG = "QSLog"
38
39 class QSLogger
40 @Inject
41 constructor(
42 @QSLog private val buffer: LogBuffer,
43 @QSConfigLog private val configChangedBuffer: LogBuffer,
<lambda>null44 ) : ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
45
46 fun logException(@CompileTimeConstant logMsg: String, ex: Exception) {
47 buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
48 }
49
50 fun v(@CompileTimeConstant msg: String, arg: Any) {
51 buffer.log(TAG, VERBOSE, { str1 = arg.toString() }, { "$msg: $str1" })
52 }
53
54 fun d(@CompileTimeConstant msg: String, arg: Any) {
55 buffer.log(TAG, DEBUG, { str1 = arg.toString() }, { "$msg: $str1" })
56 }
57
58 fun logTileAdded(tileSpec: String) {
59 buffer.log(TAG, DEBUG, { str1 = tileSpec }, { "[$str1] Tile added" })
60 }
61
62 fun logTileDestroyed(tileSpec: String, reason: String) {
63 buffer.log(
64 TAG,
65 DEBUG,
66 {
67 str1 = tileSpec
68 str2 = reason
69 },
70 { "[$str1] Tile destroyed. Reason: $str2" }
71 )
72 }
73
74 fun logTileChangeListening(tileSpec: String, listening: Boolean) {
75 buffer.log(
76 TAG,
77 VERBOSE,
78 {
79 bool1 = listening
80 str1 = tileSpec
81 },
82 { "[$str1] Tile listening=$bool1" }
83 )
84 }
85
86 fun logAllTilesChangeListening(listening: Boolean, containerName: String, allSpecs: String) {
87 buffer.log(
88 TAG,
89 DEBUG,
90 {
91 bool1 = listening
92 str1 = containerName
93 str2 = allSpecs
94 },
95 { "Tiles listening=$bool1 in $str1. $str2" }
96 )
97 }
98
99 fun logTileClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
100 buffer.log(
101 TAG,
102 DEBUG,
103 {
104 str1 = tileSpec
105 int1 = eventId
106 str2 = StatusBarState.toString(statusBarState)
107 str3 = toStateString(state)
108 },
109 { "[$str1][$int1] Tile clicked. StatusBarState=$str2. TileState=$str3" }
110 )
111 }
112
113 fun logHandleClick(tileSpec: String, eventId: Int) {
114 buffer.log(
115 TAG,
116 DEBUG,
117 {
118 str1 = tileSpec
119 int1 = eventId
120 },
121 { "[$str1][$int1] Tile handling click." }
122 )
123 }
124
125 fun logTileSecondaryClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
126 buffer.log(
127 TAG,
128 DEBUG,
129 {
130 str1 = tileSpec
131 int1 = eventId
132 str2 = StatusBarState.toString(statusBarState)
133 str3 = toStateString(state)
134 },
135 { "[$str1][$int1] Tile secondary clicked. StatusBarState=$str2. TileState=$str3" }
136 )
137 }
138
139 fun logHandleSecondaryClick(tileSpec: String, eventId: Int) {
140 buffer.log(
141 TAG,
142 DEBUG,
143 {
144 str1 = tileSpec
145 int1 = eventId
146 },
147 { "[$str1][$int1] Tile handling secondary click." }
148 )
149 }
150
151 fun logTileLongClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
152 buffer.log(
153 TAG,
154 DEBUG,
155 {
156 str1 = tileSpec
157 int1 = eventId
158 str2 = StatusBarState.toString(statusBarState)
159 str3 = toStateString(state)
160 },
161 { "[$str1][$int1] Tile long clicked. StatusBarState=$str2. TileState=$str3" }
162 )
163 }
164
165 fun logHandleLongClick(tileSpec: String, eventId: Int) {
166 buffer.log(
167 TAG,
168 DEBUG,
169 {
170 str1 = tileSpec
171 int1 = eventId
172 },
173 { "[$str1][$int1] Tile handling long click." }
174 )
175 }
176
177 fun logInternetTileUpdate(tileSpec: String, lastType: Int, callback: String) {
178 buffer.log(
179 TAG,
180 VERBOSE,
181 {
182 str1 = tileSpec
183 int1 = lastType
184 str2 = callback
185 },
186 { "[$str1] mLastTileState=$int1, Callback=$str2." }
187 )
188 }
189
190 // TODO(b/250618218): Remove this method once we know the root cause of b/250618218.
191 fun logTileBackgroundColorUpdateIfInternetTile(
192 tileSpec: String,
193 state: Int,
194 disabledByPolicy: Boolean,
195 color: Int
196 ) {
197 // This method is added to further debug b/250618218 which has only been observed from the
198 // InternetTile, so we are only logging the background color change for the InternetTile
199 // to avoid spamming the QSLogger.
200 if (tileSpec != "internet") {
201 return
202 }
203 buffer.log(
204 TAG,
205 VERBOSE,
206 {
207 str1 = tileSpec
208 int1 = state
209 bool1 = disabledByPolicy
210 int2 = color
211 },
212 { "[$str1] state=$int1, disabledByPolicy=$bool1, color=$int2." }
213 )
214 }
215
216 fun logTileUpdated(tileSpec: String, state: QSTile.State) {
217 buffer.log(
218 TAG,
219 VERBOSE,
220 {
221 str1 = tileSpec
222 str2 = state.label?.toString()
223 str3 = state.icon?.toString()
224 int1 = state.state
225 if (state is QSTile.SignalState) {
226 bool1 = true
227 bool2 = state.activityIn
228 bool3 = state.activityOut
229 }
230 },
231 {
232 "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." +
233 if (bool1) " Activity in/out=$bool2/$bool3" else ""
234 }
235 )
236 }
237
238 fun logPanelExpanded(expanded: Boolean, containerName: String) {
239 buffer.log(
240 TAG,
241 DEBUG,
242 {
243 str1 = containerName
244 bool1 = expanded
245 },
246 { "$str1 expanded=$bool1" }
247 )
248 }
249
250 fun logOnViewAttached(orientation: Int, containerName: String) {
251 buffer.log(
252 TAG,
253 DEBUG,
254 {
255 str1 = containerName
256 int1 = orientation
257 },
258 { "onViewAttached: $str1 orientation $int1" }
259 )
260 }
261
262 fun logOnViewDetached(orientation: Int, containerName: String) {
263 buffer.log(
264 TAG,
265 DEBUG,
266 {
267 str1 = containerName
268 int1 = orientation
269 },
270 { "onViewDetached: $str1 orientation $int1" }
271 )
272 }
273
274 fun logOnConfigurationChanged(
275 @Orientation oldOrientation: Int,
276 @Orientation newOrientation: Int,
277 newShouldUseSplitShade: Boolean,
278 oldShouldUseSplitShade: Boolean,
279 containerName: String
280 ) {
281 configChangedBuffer.log(
282 TAG,
283 DEBUG,
284 {
285 str1 = containerName
286 int1 = oldOrientation
287 int2 = newOrientation
288 bool1 = oldShouldUseSplitShade
289 bool2 = newShouldUseSplitShade
290 },
291 {
292 "config change: " +
293 "$str1 orientation=${toOrientationString(int2)} " +
294 "(was ${toOrientationString(int1)}), " +
295 "splitShade=$bool2 (was $bool1)"
296 }
297 )
298 }
299
300 fun logSwitchTileLayout(
301 after: Boolean,
302 before: Boolean,
303 force: Boolean,
304 containerName: String
305 ) {
306 buffer.log(
307 TAG,
308 DEBUG,
309 {
310 str1 = containerName
311 bool1 = after
312 bool2 = before
313 bool3 = force
314 },
315 { "change tile layout: $str1 horizontal=$bool1 (was $bool2), force? $bool3" }
316 )
317 }
318
319 fun logTileDistributionInProgress(tilesPerPageCount: Int, totalTilesCount: Int) {
320 buffer.log(
321 TAG,
322 DEBUG,
323 {
324 int1 = tilesPerPageCount
325 int2 = totalTilesCount
326 },
327 { "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]" }
328 )
329 }
330
331 fun logTileDistributed(tileName: String, pageIndex: Int) {
332 buffer.log(
333 TAG,
334 DEBUG,
335 {
336 str1 = tileName
337 int1 = pageIndex
338 },
339 { "Adding $str1 to page number $int1" }
340 )
341 }
342
343 private fun toStateString(state: Int): String {
344 return when (state) {
345 Tile.STATE_ACTIVE -> "active"
346 Tile.STATE_INACTIVE -> "inactive"
347 Tile.STATE_UNAVAILABLE -> "unavailable"
348 else -> "wrong state"
349 }
350 }
351
352 fun logVisibility(viewName: String, @View.Visibility visibility: Int) {
353 buffer.log(
354 TAG,
355 DEBUG,
356 {
357 str1 = viewName
358 str2 = toVisibilityString(visibility)
359 },
360 { "$str1 visibility: $str2" }
361 )
362 }
363
364 private fun toVisibilityString(visibility: Int): String {
365 return when (visibility) {
366 View.VISIBLE -> "VISIBLE"
367 View.INVISIBLE -> "INVISIBLE"
368 View.GONE -> "GONE"
369 else -> "undefined"
370 }
371 }
372 }
373
toOrientationStringnull374 private inline fun toOrientationString(@Orientation orientation: Int): String {
375 return when (orientation) {
376 ORIENTATION_LANDSCAPE -> "land"
377 ORIENTATION_PORTRAIT -> "port"
378 else -> "undefined"
379 }
380 }
381