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