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 android.annotation.UserIdInt
20 import com.android.systemui.log.LogBuffer
21 import com.android.systemui.log.core.LogLevel
22 import com.android.systemui.qs.pipeline.dagger.QSAutoAddLog
23 import com.android.systemui.qs.pipeline.dagger.QSTileListLog
24 import com.android.systemui.qs.pipeline.shared.TileSpec
25 import javax.inject.Inject
26 
27 /**
28  * Logger for the new pipeline.
29  *
30  * This may log to different buffers depending of the function of the log.
31  */
32 class QSPipelineLogger
33 @Inject
34 constructor(
35     @QSTileListLog private val tileListLogBuffer: LogBuffer,
36     @QSAutoAddLog private val tileAutoAddLogBuffer: LogBuffer,
37 ) {
38 
39     companion object {
40         const val TILE_LIST_TAG = "QSTileListLog"
41         const val AUTO_ADD_TAG = "QSAutoAddableLog"
42     }
43 
44     /**
45      * Log the tiles that are parsed in the repo. This is effectively what is surfaces in the flow.
46      *
47      * [usesDefault] indicates if the default tiles were used (due to the setting being empty or
48      * invalid).
49      */
50     fun logParsedTiles(tiles: List<TileSpec>, usesDefault: Boolean, user: Int) {
51         tileListLogBuffer.log(
52             TILE_LIST_TAG,
53             LogLevel.DEBUG,
54             {
55                 str1 = tiles.toString()
56                 bool1 = usesDefault
57                 int1 = user
58             },
59             { "Parsed tiles (default=$bool1, user=$int1): $str1" }
60         )
61     }
62 
63     /**
64      * Logs when the tiles change in Settings.
65      *
66      * This could be caused by SystemUI, or restore.
67      */
68     fun logTilesChangedInSettings(newTiles: String, @UserIdInt user: Int) {
69         tileListLogBuffer.log(
70             TILE_LIST_TAG,
71             LogLevel.VERBOSE,
72             {
73                 str1 = newTiles
74                 int1 = user
75             },
76             { "Tiles changed in settings for user $int1: $str1" }
77         )
78     }
79 
80     /** Log when a tile is destroyed and its reason for destroying. */
81     fun logTileDestroyed(spec: TileSpec, reason: TileDestroyedReason) {
82         tileListLogBuffer.log(
83             TILE_LIST_TAG,
84             LogLevel.DEBUG,
85             {
86                 str1 = spec.toString()
87                 str2 = reason.readable
88             },
89             { "Tile $str1 destroyed. Reason: $str2" }
90         )
91     }
92 
93     /** Log when a tile is created. */
94     fun logTileCreated(spec: TileSpec) {
95         tileListLogBuffer.log(
96             TILE_LIST_TAG,
97             LogLevel.DEBUG,
98             { str1 = spec.toString() },
99             { "Tile $str1 created" }
100         )
101     }
102 
103     /** Ĺog when trying to create a tile, but it's not found in the factory. */
104     fun logTileNotFoundInFactory(spec: TileSpec) {
105         tileListLogBuffer.log(
106             TILE_LIST_TAG,
107             LogLevel.VERBOSE,
108             { str1 = spec.toString() },
109             { "Tile $str1 not found in factory" }
110         )
111     }
112 
113     /** Log when the user is changed for a platform tile. */
114     fun logTileUserChanged(spec: TileSpec, user: Int) {
115         tileListLogBuffer.log(
116             TILE_LIST_TAG,
117             LogLevel.VERBOSE,
118             {
119                 str1 = spec.toString()
120                 int1 = user
121             },
122             { "User changed to $int1 for tile $str1" }
123         )
124     }
125 
126     fun logUsingRetailTiles() {
127         tileListLogBuffer.log(TILE_LIST_TAG, LogLevel.DEBUG, {}, { "Using retail tiles" })
128     }
129 
130     fun logTilesNotInstalled(tiles: Collection<TileSpec>, user: Int) {
131         tileListLogBuffer.log(
132             TILE_LIST_TAG,
133             LogLevel.DEBUG,
134             {
135                 str1 = tiles.toString()
136                 int1 = user
137             },
138             { "Tiles kept for not installed packages for user $int1: $str1" }
139         )
140     }
141 
142     fun logTileAutoAdded(userId: Int, spec: TileSpec, position: Int) {
143         tileAutoAddLogBuffer.log(
144             AUTO_ADD_TAG,
145             LogLevel.DEBUG,
146             {
147                 int1 = userId
148                 int2 = position
149                 str1 = spec.toString()
150             },
151             { "Tile $str1 auto added for user $int1 at position $int2" }
152         )
153     }
154 
155     fun logTileAutoRemoved(userId: Int, spec: TileSpec) {
156         tileAutoAddLogBuffer.log(
157             AUTO_ADD_TAG,
158             LogLevel.DEBUG,
159             {
160                 int1 = userId
161                 str1 = spec.toString()
162             },
163             { "Tile $str1 auto removed for user $int1" }
164         )
165     }
166 
167     /** Reasons for destroying an existing tile. */
168     enum class TileDestroyedReason(val readable: String) {
169         TILE_REMOVED("Tile removed from  current set"),
170         CUSTOM_TILE_USER_CHANGED("User changed for custom tile"),
171         NEW_TILE_NOT_AVAILABLE("New tile not available"),
172         EXISTING_TILE_NOT_AVAILABLE("Existing tile not available"),
173         TILE_NOT_PRESENT_IN_NEW_USER("Tile not present in new user"),
174     }
175 }
176