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.statusbar.notification.collection.listbuilder 18 19 import com.android.systemui.log.LogBuffer 20 import com.android.systemui.log.LogLevel.DEBUG 21 import com.android.systemui.log.LogLevel.INFO 22 import com.android.systemui.log.LogLevel.WARNING 23 import com.android.systemui.log.dagger.NotificationLog 24 import com.android.systemui.statusbar.notification.collection.GroupEntry 25 import com.android.systemui.statusbar.notification.collection.ListEntry 26 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter 27 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter 28 import javax.inject.Inject 29 30 class ShadeListBuilderLogger @Inject constructor( 31 @NotificationLog private val buffer: LogBuffer 32 ) { logOnBuildListnull33 fun logOnBuildList() { 34 buffer.log(TAG, INFO, { 35 }, { 36 "Request received from NotifCollection" 37 }) 38 } 39 logEndBuildListnull40 fun logEndBuildList(iterationCount: Int, topLevelEntries: Int, numChildren: Int) { 41 buffer.log(TAG, INFO, { 42 long1 = iterationCount.toLong() 43 int1 = topLevelEntries 44 int2 = numChildren 45 }, { 46 "(Build $long1) Build complete ($int1 top-level entries, $int2 children)" 47 }) 48 } 49 logPreGroupFilterInvalidatednull50 fun logPreGroupFilterInvalidated(filterName: String, pipelineState: Int) { 51 buffer.log(TAG, DEBUG, { 52 str1 = filterName 53 int1 = pipelineState 54 }, { 55 """Pre-group NotifFilter "$str1" invalidated; pipeline state is $int1""" 56 }) 57 } 58 logReorderingAllowedInvalidatednull59 fun logReorderingAllowedInvalidated(name: String, pipelineState: Int) { 60 buffer.log(TAG, DEBUG, { 61 str1 = name 62 int1 = pipelineState 63 }, { 64 """ReorderingNowAllowed "$str1" invalidated; pipeline state is $int1""" 65 }) 66 } 67 logPromoterInvalidatednull68 fun logPromoterInvalidated(name: String, pipelineState: Int) { 69 buffer.log(TAG, DEBUG, { 70 str1 = name 71 int1 = pipelineState 72 }, { 73 """NotifPromoter "$str1" invalidated; pipeline state is $int1""" 74 }) 75 } 76 logNotifSectionInvalidatednull77 fun logNotifSectionInvalidated(name: String, pipelineState: Int) { 78 buffer.log(TAG, DEBUG, { 79 str1 = name 80 int1 = pipelineState 81 }, { 82 """NotifSection "$str1" invalidated; pipeline state is $int1""" 83 }) 84 } 85 logNotifComparatorInvalidatednull86 fun logNotifComparatorInvalidated(name: String, pipelineState: Int) { 87 buffer.log(TAG, DEBUG, { 88 str1 = name 89 int1 = pipelineState 90 }, { 91 """NotifComparator "$str1" invalidated; pipeline state is $int1""" 92 }) 93 } 94 logFinalizeFilterInvalidatednull95 fun logFinalizeFilterInvalidated(name: String, pipelineState: Int) { 96 buffer.log(TAG, DEBUG, { 97 str1 = name 98 int1 = pipelineState 99 }, { 100 """Finalize NotifFilter "$str1" invalidated; pipeline state is $int1""" 101 }) 102 } 103 logDuplicateSummarynull104 fun logDuplicateSummary(buildId: Int, groupKey: String, existingKey: String, newKey: String) { 105 buffer.log(TAG, WARNING, { 106 int1 = buildId 107 str1 = groupKey 108 str2 = existingKey 109 str3 = newKey 110 }, { 111 """(Build $int1) Duplicate summary for group "$str1": "$str2" vs. "$str3"""" 112 }) 113 } 114 115 fun logDuplicateTopLevelKey(buildId: Int, topLevelKey: String) { 116 buffer.log(TAG, WARNING, { 117 int1 = buildId 118 str1 = topLevelKey 119 }, { 120 "(Build $int1) Duplicate top-level key: $str1" 121 }) 122 } 123 124 fun logEntryAttachStateChanged( 125 buildId: Int, 126 key: String, 127 prevParent: GroupEntry?, 128 newParent: GroupEntry? 129 ) { 130 buffer.log(TAG, INFO, { 131 int1 = buildId 132 str1 = key 133 str2 = prevParent?.key 134 str3 = newParent?.key 135 }, { 136 137 val action = if (str2 == null && str3 != null) { 138 "ATTACHED" 139 } else if (str2 != null && str3 == null) { 140 "DETACHED" 141 } else if (str2 == null && str3 == null) { 142 "MODIFIED (DETACHED)" 143 } else { 144 "MODIFIED (ATTACHED)" 145 } 146 147 "(Build $int1) $action {$str1}" 148 }) 149 } 150 151 fun logParentChanged(buildId: Int, prevParent: GroupEntry?, newParent: GroupEntry?) { 152 buffer.log(TAG, INFO, { 153 int1 = buildId 154 str1 = prevParent?.key 155 str2 = newParent?.key 156 }, { 157 if (str1 == null && str2 != null) { 158 "(Build $int1) Parent is {$str2}" 159 } else if (str1 != null && str2 == null) { 160 "(Build $int1) Parent was {$str1}" 161 } else { 162 "(Build $int1) Reparent: {$str1} -> {$str2}" 163 } 164 }) 165 } 166 167 fun logParentChangeSuppressed( 168 buildId: Int, 169 suppressedParent: GroupEntry?, 170 keepingParent: GroupEntry? 171 ) { 172 buffer.log(TAG, INFO, { 173 int1 = buildId 174 str1 = suppressedParent?.key 175 str2 = keepingParent?.key 176 }, { 177 "(Build $long1) Change of parent to '$str1' suppressed; keeping parent '$str2'" 178 }) 179 } 180 181 fun logGroupPruningSuppressed( 182 buildId: Int, 183 keepingParent: GroupEntry? 184 ) { 185 buffer.log(TAG, INFO, { 186 int1 = buildId 187 str1 = keepingParent?.key 188 }, { 189 "(Build $long1) Group pruning suppressed; keeping parent '$str1'" 190 }) 191 } 192 193 fun logFilterChanged( 194 buildId: Int, 195 prevFilter: NotifFilter?, 196 newFilter: NotifFilter? 197 ) { 198 buffer.log(TAG, INFO, { 199 int1 = buildId 200 str1 = prevFilter?.name 201 str2 = newFilter?.name 202 }, { 203 "(Build $int1) Filter changed: $str1 -> $str2" 204 }) 205 } 206 207 fun logPromoterChanged( 208 buildId: Int, 209 prevPromoter: NotifPromoter?, 210 newPromoter: NotifPromoter? 211 ) { 212 buffer.log(TAG, INFO, { 213 int1 = buildId 214 str1 = prevPromoter?.name 215 str2 = newPromoter?.name 216 }, { 217 "(Build $int1) Promoter changed: $str1 -> $str2" 218 }) 219 } 220 221 fun logSectionChanged( 222 buildId: Int, 223 prevSection: NotifSection?, 224 newSection: NotifSection? 225 ) { 226 buffer.log(TAG, INFO, { 227 long1 = buildId.toLong() 228 str1 = prevSection?.label 229 str2 = newSection?.label 230 }, { 231 if (str1 == null) { 232 "(Build $long1) Section assigned: $str2" 233 } else { 234 "(Build $long1) Section changed: $str1 -> $str2" 235 } 236 }) 237 } 238 239 fun logSectionChangeSuppressed( 240 buildId: Int, 241 suppressedSection: NotifSection?, 242 assignedSection: NotifSection? 243 ) { 244 buffer.log(TAG, INFO, { 245 long1 = buildId.toLong() 246 str1 = suppressedSection?.label 247 str2 = assignedSection?.label 248 }, { 249 "(Build $long1) Suppressing section change to $str1 (staying at $str2)" 250 }) 251 } 252 253 fun logFinalList(entries: List<ListEntry>) { 254 if (entries.isEmpty()) { 255 buffer.log(TAG, DEBUG, {}, { "(empty list)" }) 256 } 257 for (i in entries.indices) { 258 val entry = entries[i] 259 buffer.log(TAG, DEBUG, { 260 int1 = i 261 str1 = entry.key 262 }, { 263 "[$int1] $str1" 264 }) 265 266 if (entry is GroupEntry) { 267 entry.summary?.let { 268 buffer.log(TAG, DEBUG, { 269 str1 = it.key 270 }, { 271 " [*] $str1 (summary)" 272 }) 273 } 274 for (j in entry.children.indices) { 275 val child = entry.children[j] 276 buffer.log(TAG, DEBUG, { 277 int1 = j 278 str1 = child.key 279 }, { 280 " [$int1] $str1" 281 }) 282 } 283 } 284 } 285 } 286 } 287 288 private const val TAG = "ShadeListBuilder"