1 /*
2  * Copyright (C) 2023 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.pipeline.shared.logging
18 
19 import com.android.systemui.log.LogBuffer
20 import com.android.systemui.log.core.LogLevel
21 import com.android.systemui.qs.pipeline.dagger.QSAutoAddLog
22 import com.android.systemui.qs.pipeline.dagger.QSRestoreLog
23 import com.android.systemui.qs.pipeline.dagger.QSTileListLog
24 import com.android.systemui.qs.pipeline.data.model.RestoreData
25 import com.android.systemui.qs.pipeline.data.repository.UserTileSpecRepository
26 import com.android.systemui.qs.pipeline.shared.TileSpec
27 import javax.inject.Inject
28 
29 /**
30  * Logger for the new pipeline.
31  *
32  * This may log to different buffers depending of the function of the log.
33  */
34 class QSPipelineLogger
35 @Inject
36 constructor(
37     @QSTileListLog private val tileListLogBuffer: LogBuffer,
38     @QSAutoAddLog private val tileAutoAddLogBuffer: LogBuffer,
39     @QSRestoreLog private val restoreLogBuffer: LogBuffer,
40 ) {
41 
42     companion object {
43         const val TILE_LIST_TAG = "QSTileListLog"
44         const val AUTO_ADD_TAG = "QSAutoAddableLog"
45         const val RESTORE_TAG = "QSRestoreLog"
46     }
47 
48     /**
49      * Log the tiles that are parsed in the repo. This is effectively what is surfaces in the flow.
50      *
51      * [usesDefault] indicates if the default tiles were used (due to the setting being empty or
52      * invalid).
53      */
logParsedTilesnull54     fun logParsedTiles(tiles: List<TileSpec>, usesDefault: Boolean, user: Int) {
55         tileListLogBuffer.log(
56             TILE_LIST_TAG,
57             LogLevel.DEBUG,
58             {
59                 str1 = tiles.toString()
60                 bool1 = usesDefault
61                 int1 = user
62             },
63             { "Parsed tiles (default=$bool1, user=$int1): $str1" }
64         )
65     }
66 
logTilesRestoredAndReconcilednull67     fun logTilesRestoredAndReconciled(
68         currentTiles: List<TileSpec>,
69         reconciledTiles: List<TileSpec>,
70         user: Int,
71     ) {
72         tileListLogBuffer.log(
73             TILE_LIST_TAG,
74             LogLevel.DEBUG,
75             {
76                 str1 = currentTiles.toString()
77                 str2 = reconciledTiles.toString()
78                 int1 = user
79             },
80             { "Tiles restored and reconciled for user: $int1\nWas: $str1\nSet to: $str2" }
81         )
82     }
83 
logProcessTileChangenull84     fun logProcessTileChange(
85         action: UserTileSpecRepository.ChangeAction,
86         newList: List<TileSpec>,
87         userId: Int,
88     ) {
89         tileListLogBuffer.log(
90             TILE_LIST_TAG,
91             LogLevel.DEBUG,
92             {
93                 str1 = action.toString()
94                 str2 = newList.toString()
95                 int1 = userId
96             },
97             { "Processing $str1 for user $int1\nNew list: $str2" }
98         )
99     }
100 
101     /** Log when a tile is destroyed and its reason for destroying. */
logTileDestroyednull102     fun logTileDestroyed(spec: TileSpec, reason: TileDestroyedReason) {
103         tileListLogBuffer.log(
104             TILE_LIST_TAG,
105             LogLevel.DEBUG,
106             {
107                 str1 = spec.toString()
108                 str2 = reason.readable
109             },
110             { "Tile $str1 destroyed. Reason: $str2" }
111         )
112     }
113 
114     /** Log when a tile is created. */
logTileCreatednull115     fun logTileCreated(spec: TileSpec) {
116         tileListLogBuffer.log(
117             TILE_LIST_TAG,
118             LogLevel.DEBUG,
119             { str1 = spec.toString() },
120             { "Tile $str1 created" }
121         )
122     }
123 
124     /** Ĺog when trying to create a tile, but it's not found in the factory. */
logTileNotFoundInFactorynull125     fun logTileNotFoundInFactory(spec: TileSpec) {
126         tileListLogBuffer.log(
127             TILE_LIST_TAG,
128             LogLevel.VERBOSE,
129             { str1 = spec.toString() },
130             { "Tile $str1 not found in factory" }
131         )
132     }
133 
134     /** Log when the user is changed for a platform tile. */
logTileUserChangednull135     fun logTileUserChanged(spec: TileSpec, user: Int) {
136         tileListLogBuffer.log(
137             TILE_LIST_TAG,
138             LogLevel.VERBOSE,
139             {
140                 str1 = spec.toString()
141                 int1 = user
142             },
143             { "User changed to $int1 for tile $str1" }
144         )
145     }
146 
logUsingRetailTilesnull147     fun logUsingRetailTiles() {
148         tileListLogBuffer.log(TILE_LIST_TAG, LogLevel.DEBUG, {}, { "Using retail tiles" })
149     }
150 
logTilesNotInstallednull151     fun logTilesNotInstalled(tiles: Collection<TileSpec>, user: Int) {
152         tileListLogBuffer.log(
153             TILE_LIST_TAG,
154             LogLevel.DEBUG,
155             {
156                 str1 = tiles.toString()
157                 int1 = user
158             },
159             { "Tiles kept for not installed packages for user $int1: $str1" }
160         )
161     }
162 
logAutoAddTilesParsednull163     fun logAutoAddTilesParsed(userId: Int, tiles: Set<TileSpec>) {
164         tileAutoAddLogBuffer.log(
165             AUTO_ADD_TAG,
166             LogLevel.DEBUG,
167             {
168                 str1 = tiles.toString()
169                 int1 = userId
170             },
171             { "Auto add tiles parsed for user $int1: $str1" }
172         )
173     }
174 
logAutoAddTilesRestoredReconcilednull175     fun logAutoAddTilesRestoredReconciled(userId: Int, tiles: Set<TileSpec>) {
176         tileAutoAddLogBuffer.log(
177             AUTO_ADD_TAG,
178             LogLevel.DEBUG,
179             {
180                 str1 = tiles.toString()
181                 int1 = userId
182             },
183             { "Auto-add tiles reconciled for user $int1: $str1" }
184         )
185     }
186 
logTileAutoAddednull187     fun logTileAutoAdded(userId: Int, spec: TileSpec, position: Int) {
188         tileAutoAddLogBuffer.log(
189             AUTO_ADD_TAG,
190             LogLevel.DEBUG,
191             {
192                 int1 = userId
193                 int2 = position
194                 str1 = spec.toString()
195             },
196             { "Tile $str1 auto added for user $int1 at position $int2" }
197         )
198     }
199 
logTileAutoRemovednull200     fun logTileAutoRemoved(userId: Int, spec: TileSpec) {
201         tileAutoAddLogBuffer.log(
202             AUTO_ADD_TAG,
203             LogLevel.DEBUG,
204             {
205                 int1 = userId
206                 str1 = spec.toString()
207             },
208             { "Tile $str1 auto removed for user $int1" }
209         )
210     }
211 
logTileUnmarkednull212     fun logTileUnmarked(userId: Int, spec: TileSpec) {
213         tileAutoAddLogBuffer.log(
214             AUTO_ADD_TAG,
215             LogLevel.DEBUG,
216             {
217                 int1 = userId
218                 str1 = spec.toString()
219             },
220             { "Tile $str1 unmarked as auto-added for user $int1" }
221         )
222     }
223 
logSettingsRestoredOnUserSetupCompletenull224     fun logSettingsRestoredOnUserSetupComplete(userId: Int) {
225         restoreLogBuffer.log(
226             RESTORE_TAG,
227             LogLevel.DEBUG,
228             { int1 = userId },
229             { "Restored from single intent after user setup complete for user $int1" }
230         )
231     }
232 
logSettingsRestorednull233     fun logSettingsRestored(restoreData: RestoreData) {
234         restoreLogBuffer.log(
235             RESTORE_TAG,
236             LogLevel.DEBUG,
237             {
238                 int1 = restoreData.userId
239                 str1 = restoreData.restoredTiles.toString()
240                 str2 = restoreData.restoredAutoAddedTiles.toString()
241             },
242             {
243                 "Restored settings data for user $int1\n" +
244                     "\tRestored tiles: $str1\n" +
245                     "\tRestored auto added tiles: $str2"
246             }
247         )
248     }
249 
logRestoreProcessorAppliednull250     fun logRestoreProcessorApplied(
251         restoreProcessorClassName: String?,
252         step: RestorePreprocessorStep,
253     ) {
254         restoreLogBuffer.log(
255             RESTORE_TAG,
256             LogLevel.DEBUG,
257             {
258                 str1 = restoreProcessorClassName
259                 str2 = step.name
260             },
261             { "Restore $str2 processed by $str1" }
262         )
263     }
264 
265     /** Reasons for destroying an existing tile. */
266     enum class TileDestroyedReason(val readable: String) {
267         TILE_REMOVED("Tile removed from  current set"),
268         CUSTOM_TILE_USER_CHANGED("User changed for custom tile"),
269         NEW_TILE_NOT_AVAILABLE("New tile not available"),
270         EXISTING_TILE_NOT_AVAILABLE("Existing tile not available"),
271         TILE_NOT_PRESENT_IN_NEW_USER("Tile not present in new user"),
272     }
273 
274     enum class RestorePreprocessorStep {
275         PREPROCESSING,
276         POSTPROCESSING
277     }
278 }
279