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.keyguard.logging
18 
19 import androidx.annotation.IntDef
20 import com.android.keyguard.CarrierTextManager.CarrierTextCallbackInfo
21 import com.android.systemui.log.LogBuffer
22 import com.android.systemui.log.core.LogLevel
23 import com.android.systemui.log.dagger.CarrierTextManagerLog
24 import javax.inject.Inject
25 
26 /** Logger adapter for [CarrierTextManager] to add detailed messages in a [LogBuffer] */
27 class CarrierTextManagerLogger @Inject constructor(@CarrierTextManagerLog val buffer: LogBuffer) {
28     /**
29      * To help disambiguate carrier text manager instances, set a location string here which will
30      * propagate to [logUpdate] and [logUpdateCarrierTextForReason]
31      */
32     var location: String? = null
33 
34     /**
35      * This method and the methods below trace the execution of CarrierTextManager.updateCarrierText
36      */
logUpdatenull37     fun logUpdate(numSubs: Int) {
38         buffer.log(
39             TAG,
40             LogLevel.VERBOSE,
41             {
42                 int1 = numSubs
43                 str1 = location
44             },
45             { "updateCarrierText: location=${str1 ?: "(unknown)"} numSubs=$int1" },
46         )
47     }
48 
logUpdateLoopStartnull49     fun logUpdateLoopStart(sub: Int, simState: Int, carrierName: String) {
50         buffer.log(
51             TAG,
52             LogLevel.VERBOSE,
53             {
54                 int1 = sub
55                 int2 = simState
56                 str1 = carrierName
57             },
58             { "┣ updateCarrierText: updating sub=$int1 simState=$int2 carrierName=$str1" },
59         )
60     }
61 
logUpdateWfcChecknull62     fun logUpdateWfcCheck() {
63         buffer.log(
64             TAG,
65             LogLevel.VERBOSE,
66             {},
67             { "┣ updateCarrierText: found WFC state" },
68         )
69     }
70 
logUpdateFromStickyBroadcastnull71     fun logUpdateFromStickyBroadcast(plmn: String?, spn: String?) {
72         buffer.log(
73             TAG,
74             LogLevel.VERBOSE,
75             {
76                 str1 = plmn
77                 str2 = spn
78             },
79             { "┣ updateCarrierText: getting PLMN/SPN sticky brdcst. plmn=$str1, spn=$str1" },
80         )
81     }
82 
logNewSatelliteCarrierTextnull83     fun logNewSatelliteCarrierText(newSatelliteText: String?) {
84         buffer.log(
85             TAG,
86             LogLevel.VERBOSE,
87             { str1 = newSatelliteText },
88             { "New satellite text = $str1" },
89         )
90     }
91 
logUsingSatelliteTextnull92     fun logUsingSatelliteText(satelliteText: String) {
93         buffer.log(
94             TAG,
95             LogLevel.VERBOSE,
96             { str1 = satelliteText },
97             { "┣ updateCarrierText: using satellite text. text=$str1" },
98         )
99     }
100 
101     /** De-structures the info object so that we don't have to generate new strings */
logCallbackSentFromUpdatenull102     fun logCallbackSentFromUpdate(info: CarrierTextCallbackInfo) {
103         buffer.log(
104             TAG,
105             LogLevel.VERBOSE,
106             {
107                 str1 = "${info.carrierText}"
108                 bool1 = info.anySimReady
109                 bool2 = info.airplaneMode
110             },
111             {
112                 "┗ updateCarrierText: " +
113                     "result=(carrierText=$str1, anySimReady=$bool1, airplaneMode=$bool2)"
114             },
115         )
116     }
117 
logSimStateChangedCallbacknull118     fun logSimStateChangedCallback(subId: Int, slotId: Int, simState: Int) {
119         buffer.log(
120             TAG,
121             LogLevel.VERBOSE,
122             {
123                 // subId is always a very small int, and we've run out of integers for log buffer
124                 long1 = subId.toLong()
125                 int1 = slotId
126                 int2 = simState
127             },
128             { "onSimStateChangedCallback: subId=$long1 slotId=$int1 simState=$int2" }
129         )
130     }
131 
132     /**
133      * Used to log the starting point for _why_ the carrier text is updating. In order to keep us
134      * from holding on to too many objects, we'll just use simple ints for reasons here
135      */
logUpdateCarrierTextForReasonnull136     fun logUpdateCarrierTextForReason(@CarrierTextRefreshReason reason: Int) {
137         buffer.log(
138             TAG,
139             LogLevel.DEBUG,
140             {
141                 int1 = reason
142                 str1 = location
143             },
144             {
145                 "refreshing carrier info for reason: ${reason.reasonMessage()}" +
146                     " location=${str1 ?: "(unknown)"}"
147             }
148         )
149     }
150 
logStartListeningForSatelliteCarrierTextnull151     fun logStartListeningForSatelliteCarrierText() {
152         buffer.log(
153             TAG,
154             LogLevel.DEBUG,
155             { str1 = location },
156             { "Start listening for satellite carrier text. Location=${str1 ?: "(unknown)"}" }
157         )
158     }
159 
logStopListeningForSatelliteCarrierTextnull160     fun logStopListeningForSatelliteCarrierText(reason: String) {
161         buffer.log(
162             TAG,
163             LogLevel.DEBUG,
164             {
165                 str1 = location
166                 str2 = reason
167             },
168             {
169                 "Stop listening for satellite carrier text. " +
170                     "Location=${str1 ?: "(unknown)"} Reason=$str2"
171             }
172         )
173     }
174 
175     companion object {
176         const val REASON_REFRESH_CARRIER_INFO = 1
177         const val REASON_ON_TELEPHONY_CAPABLE = 2
178         const val REASON_SIM_ERROR_STATE_CHANGED = 3
179         const val REASON_ACTIVE_DATA_SUB_CHANGED = 4
180         const val REASON_SATELLITE_CHANGED = 5
181 
182         @Retention(AnnotationRetention.SOURCE)
183         @IntDef(
184             value =
185                 [
186                     REASON_REFRESH_CARRIER_INFO,
187                     REASON_ON_TELEPHONY_CAPABLE,
188                     REASON_SIM_ERROR_STATE_CHANGED,
189                     REASON_ACTIVE_DATA_SUB_CHANGED,
190                     REASON_SATELLITE_CHANGED,
191                 ]
192         )
193         annotation class CarrierTextRefreshReason
194 
reasonMessagenull195         private fun @receiver:CarrierTextRefreshReason Int.reasonMessage() =
196             when (this) {
197                 REASON_REFRESH_CARRIER_INFO -> "REFRESH_CARRIER_INFO"
198                 REASON_ON_TELEPHONY_CAPABLE -> "ON_TELEPHONY_CAPABLE"
199                 REASON_SIM_ERROR_STATE_CHANGED -> "SIM_ERROR_STATE_CHANGED"
200                 REASON_ACTIVE_DATA_SUB_CHANGED -> "ACTIVE_DATA_SUB_CHANGED"
201                 REASON_SATELLITE_CHANGED -> "SATELLITE_CHANGED"
202                 else -> "unknown"
203             }
204     }
205 }
206 
207 private const val TAG = "CarrierTextManagerLog"
208