1 /*
2  * Copyright (C) 2020 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.broadcast.logging
18 
19 import android.content.BroadcastReceiver
20 import android.content.Context
21 import android.content.Intent
22 import android.content.IntentFilter
23 import com.android.systemui.log.LogBuffer
24 import com.android.systemui.log.core.LogLevel
25 import com.android.systemui.log.core.LogLevel.DEBUG
26 import com.android.systemui.log.core.LogLevel.INFO
27 import com.android.systemui.log.core.LogMessage
28 import com.android.systemui.log.dagger.BroadcastDispatcherLog
29 import javax.inject.Inject
30 
31 private const val TAG = "BroadcastDispatcherLog"
32 
33 class BroadcastDispatcherLogger @Inject constructor(
34     @BroadcastDispatcherLog private val buffer: LogBuffer
35 ) {
36 
37     companion object {
flagToStringnull38         fun flagToString(@Context.RegisterReceiverFlags flag: Int): String {
39             val b = StringBuilder("")
40             if (flag and Context.RECEIVER_VISIBLE_TO_INSTANT_APPS != 0) {
41                 b.append("instant_apps,")
42             }
43             if (flag and Context.RECEIVER_NOT_EXPORTED != 0) {
44                 b.append("not_exported,")
45             }
46             if (flag and Context.RECEIVER_EXPORTED != 0) {
47                 b.append("exported")
48             }
49             if (b.isEmpty()) {
50                 b.append(flag)
51             }
52             return b.toString()
53         }
54     }
55 
logBroadcastReceivednull56     fun logBroadcastReceived(broadcastId: Int, user: Int, intent: Intent) {
57         val intentString = intent.toString()
58         log(INFO, {
59             int1 = broadcastId
60             int2 = user
61             str1 = intentString
62         }, {
63             "[$int1] Broadcast received for user $int2: $str1"
64         })
65     }
66 
logBroadcastDispatchednull67     fun logBroadcastDispatched(broadcastId: Int, action: String?, receiver: BroadcastReceiver) {
68         val receiverString = receiver.toString()
69         log(DEBUG, {
70             int1 = broadcastId
71             str1 = action
72             str2 = receiverString
73         }, {
74             "Broadcast $int1 ($str1) dispatched to $str2"
75         })
76     }
77 
logReceiverRegisterednull78     fun logReceiverRegistered(user: Int, receiver: BroadcastReceiver, flags: Int) {
79         val receiverString = receiver.toString()
80         val flagsString = flagToString(flags)
81         log(INFO, {
82             int1 = user
83             str1 = receiverString
84             str2 = flagsString
85         }, {
86             "Receiver $str1 ($str2) registered for user $int1"
87         })
88     }
89 
logTagForRemovalnull90     fun logTagForRemoval(user: Int, receiver: BroadcastReceiver) {
91         val receiverString = receiver.toString()
92         log(DEBUG, {
93             int1 = user
94             str1 = receiverString
95         }, {
96             "Receiver $str1 tagged for removal from user $int1"
97         })
98     }
99 
logClearedAfterRemovalnull100     fun logClearedAfterRemoval(user: Int, receiver: BroadcastReceiver) {
101         val receiverString = receiver.toString()
102         log(DEBUG, {
103             int1 = user
104             str1 = receiverString
105         }, {
106             "Receiver $str1 has been completely removed for user $int1"
107         })
108     }
109 
logReceiverUnregisterednull110     fun logReceiverUnregistered(user: Int, receiver: BroadcastReceiver) {
111         val receiverString = receiver.toString()
112         log(INFO, {
113             int1 = user
114             str1 = receiverString
115         }, {
116             "Receiver $str1 unregistered for user $int1"
117         })
118     }
119 
logContextReceiverRegisterednull120     fun logContextReceiverRegistered(user: Int, flags: Int, filter: IntentFilter) {
121         val actions = filter.actionsIterator().asSequence()
122                 .joinToString(separator = ",", prefix = "Actions(", postfix = ")")
123         val categories = if (filter.countCategories() != 0) {
124             filter.categoriesIterator().asSequence()
125                     .joinToString(separator = ",", prefix = "Categories(", postfix = ")")
126         } else {
127             ""
128         }
129         log(INFO, {
130             int1 = user
131             str1 = if (categories != "") {
132                 "${actions}\n$categories"
133             } else {
134                 actions
135             }
136             str2 = flagToString(flags)
137         }, {
138             """
139                 Receiver registered with Context for user $int1. Flags=$str2
140                 $str1
141             """.trimIndent()
142         })
143     }
144 
logContextReceiverUnregisterednull145     fun logContextReceiverUnregistered(user: Int, action: String) {
146         log(INFO, {
147             int1 = user
148             str1 = action
149         }, {
150             "Receiver unregistered with Context for user $int1, action $str1"
151         })
152     }
153 
lognull154     private inline fun log(
155         logLevel: LogLevel,
156         initializer: LogMessage.() -> Unit,
157         noinline printer: LogMessage.() -> String
158     ) {
159         buffer.log(TAG, logLevel, initializer, printer)
160     }
161 }