1 /* 2 * Copyright (C) 2022 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.shade 18 19 import android.view.MotionEvent 20 import com.android.systemui.log.dagger.ShadeLog 21 import com.android.systemui.log.LogBuffer 22 import com.android.systemui.log.core.LogLevel 23 import com.android.systemui.shade.ShadeViewController.Companion.FLING_COLLAPSE 24 import com.android.systemui.shade.ShadeViewController.Companion.FLING_EXPAND 25 import com.android.systemui.shade.ShadeViewController.Companion.FLING_HIDE 26 import com.google.errorprone.annotations.CompileTimeConstant 27 import javax.inject.Inject 28 29 private const val TAG = "systemui.shade" 30 31 /** Lightweight logging utility for the Shade. */ 32 class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) { 33 fun v(@CompileTimeConstant msg: String) { 34 buffer.log(TAG, LogLevel.VERBOSE, msg) 35 } 36 37 fun d(@CompileTimeConstant msg: String) { 38 buffer.log(TAG, LogLevel.DEBUG, msg) 39 } 40 41 fun onQsInterceptMoveQsTrackingEnabled(h: Float) { 42 buffer.log( 43 TAG, 44 LogLevel.VERBOSE, 45 { double1 = h.toDouble() }, 46 { "onQsIntercept: move action, QS tracking enabled. h = $double1" } 47 ) 48 } 49 50 fun logQsTrackingNotStarted( 51 initialTouchY: Float, 52 y: Float, 53 h: Float, 54 touchSlop: Float, 55 qsExpanded: Boolean, 56 keyguardShowing: Boolean, 57 qsExpansionEnabled: Boolean, 58 downTime: Long 59 ) { 60 buffer.log( 61 TAG, 62 LogLevel.VERBOSE, 63 { 64 int1 = initialTouchY.toInt() 65 int2 = y.toInt() 66 long1 = h.toLong() 67 double1 = touchSlop.toDouble() 68 bool1 = qsExpanded 69 bool2 = keyguardShowing 70 bool3 = qsExpansionEnabled 71 str1 = downTime.toString() 72 }, 73 { 74 "QsTrackingNotStarted: downTime=$str1,initTouchY=$int1,y=$int2,h=$long1," + 75 "slop=$double1,qsExpanded=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3" 76 } 77 ) 78 } 79 80 fun logMotionEvent(event: MotionEvent, message: String) { 81 buffer.log( 82 TAG, 83 LogLevel.VERBOSE, 84 { 85 str1 = message 86 long1 = event.eventTime 87 long2 = event.downTime 88 int1 = event.action 89 int2 = event.classification 90 }, 91 { 92 "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2" 93 } 94 ) 95 } 96 97 /** Logs motion event dispatch results from NotificationShadeWindowViewController. */ 98 fun logShadeWindowDispatch(event: MotionEvent, message: String, result: Boolean?) { 99 buffer.log( 100 TAG, 101 LogLevel.VERBOSE, 102 { 103 str1 = message 104 long1 = event.eventTime 105 long2 = event.downTime 106 }, 107 { 108 val prefix = when (result) { 109 true -> "SHADE TOUCH REROUTED" 110 false -> "SHADE TOUCH BLOCKED" 111 null -> "SHADE TOUCH DISPATCHED" 112 } 113 "$prefix: eventTime=$long1,downTime=$long2, reason=$str1" 114 } 115 ) 116 } 117 118 fun logMotionEventStatusBarState(event: MotionEvent, statusBarState: Int, message: String) { 119 buffer.log( 120 TAG, 121 LogLevel.VERBOSE, 122 { 123 str1 = message 124 long1 = event.eventTime 125 long2 = event.downTime 126 int1 = event.action 127 int2 = statusBarState 128 double1 = event.y.toDouble() 129 }, 130 { 131 "$str1\neventTime=$long1,downTime=$long2,y=$double1,action=$int1," + 132 "statusBarState=${when (int2) { 133 0 -> "SHADE" 134 1 -> "KEYGUARD" 135 2 -> "SHADE_LOCKED" 136 else -> "UNKNOWN:$int2" 137 }}" 138 } 139 ) 140 } 141 142 fun logExpansionChanged( 143 message: String, 144 fraction: Float, 145 expanded: Boolean, 146 tracking: Boolean, 147 dragDownPxAmount: Float, 148 ) { 149 buffer.log( 150 TAG, 151 LogLevel.VERBOSE, 152 { 153 str1 = message 154 double1 = fraction.toDouble() 155 bool1 = expanded 156 bool2 = tracking 157 long1 = dragDownPxAmount.toLong() 158 }, 159 { 160 "$str1 fraction=$double1,expanded=$bool1," + 161 "tracking=$bool2," + "dragDownPxAmount=$dragDownPxAmount" 162 } 163 ) 164 } 165 166 fun logHasVibrated(hasVibratedOnOpen: Boolean, fraction: Float) { 167 buffer.log( 168 TAG, 169 LogLevel.VERBOSE, 170 { 171 bool1 = hasVibratedOnOpen 172 double1 = fraction.toDouble() 173 }, 174 { "hasVibratedOnOpen=$bool1, expansionFraction=$double1" } 175 ) 176 } 177 178 fun logQsExpandImmediateChanged(newValue: Boolean) { 179 buffer.log( 180 TAG, 181 LogLevel.VERBOSE, 182 { 183 bool1 = newValue 184 }, 185 { "qsExpandImmediate=$bool1" } 186 ) 187 } 188 189 fun logQsExpansionChanged( 190 message: String, 191 qsExpanded: Boolean, 192 qsMinExpansionHeight: Int, 193 qsMaxExpansionHeight: Int, 194 stackScrollerOverscrolling: Boolean, 195 qsAnimatorExpand: Boolean, 196 animatingQs: Boolean 197 ) { 198 buffer.log( 199 TAG, 200 LogLevel.VERBOSE, 201 { 202 str1 = message 203 bool1 = qsExpanded 204 int1 = qsMinExpansionHeight 205 int2 = qsMaxExpansionHeight 206 bool2 = stackScrollerOverscrolling 207 bool3 = qsAnimatorExpand 208 // 0 = false, 1 = true 209 long1 = animatingQs.compareTo(false).toLong() 210 }, 211 { 212 "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," + 213 "stackScrollerOverscrolling=$bool2,qsAnimatorExpand=$bool3," + 214 "animatingQs=$long1" 215 } 216 ) 217 } 218 219 fun logSingleTapUp(isDozing: Boolean, singleTapEnabled: Boolean, isNotDocked: Boolean) { 220 buffer.log( 221 TAG, 222 LogLevel.DEBUG, 223 { 224 bool1 = isDozing 225 bool2 = singleTapEnabled 226 bool3 = isNotDocked 227 }, 228 { 229 "PulsingGestureListener#onSingleTapUp all of this must true for single " + 230 "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3" 231 }) 232 } 233 234 fun logSingleTapUpFalsingState(proximityIsNotNear: Boolean, isNotFalseTap: Boolean) { 235 buffer.log( 236 TAG, 237 LogLevel.DEBUG, 238 { 239 bool1 = proximityIsNotNear 240 bool2 = isNotFalseTap 241 }, 242 { 243 "PulsingGestureListener#onSingleTapUp all of this must true for single " + 244 "tap to be detected: proximityIsNotNear: $bool1, isNotFalseTap: $bool2" 245 } 246 ) 247 } 248 249 fun logNotInterceptingTouchInstantExpanding( 250 instantExpanding: Boolean, 251 notificationsDragEnabled: Boolean, 252 touchDisabled: Boolean 253 ) { 254 buffer.log( 255 TAG, 256 LogLevel.VERBOSE, 257 { 258 bool1 = instantExpanding 259 bool2 = notificationsDragEnabled 260 bool3 = touchDisabled 261 }, 262 { 263 "NPVC not intercepting touch, instantExpanding: $bool1, " + 264 "!notificationsDragEnabled: $bool2, touchDisabled: $bool3" 265 } 266 ) 267 } 268 269 fun logLastFlingWasExpanding(expand: Boolean) { 270 buffer.log( 271 TAG, 272 LogLevel.VERBOSE, 273 { bool1 = expand }, 274 { "NPVC mLastFlingWasExpanding set to: $bool1" } 275 ) 276 } 277 278 fun logFlingExpands( 279 vel: Float, 280 vectorVel: Float, 281 interactionType: Int, 282 minVelocityPxPerSecond: Float, 283 expansionOverHalf: Boolean, 284 allowExpandForSmallExpansion: Boolean 285 ) { 286 buffer.log( 287 TAG, 288 LogLevel.VERBOSE, 289 { 290 int1 = interactionType 291 long1 = vel.toLong() 292 long2 = vectorVel.toLong() 293 double1 = minVelocityPxPerSecond.toDouble() 294 bool1 = expansionOverHalf 295 bool2 = allowExpandForSmallExpansion 296 }, 297 { "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " + 298 "interactionType: $int1, minVelocityPxPerSecond: $double1 " + 299 "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2" } 300 ) 301 } 302 303 fun logEndMotionEvent( 304 msg: String, 305 forceCancel: Boolean, 306 expand: Boolean, 307 ) 308 { 309 buffer.log( 310 TAG, 311 LogLevel.VERBOSE, 312 { 313 str1 = msg 314 bool1 = forceCancel 315 bool2 = expand 316 }, 317 { "$str1; force=$bool1; expand=$bool2" } 318 ) 319 } 320 321 fun logPanelClosedOnDown( 322 msg: String, 323 panelClosedOnDown: Boolean, 324 expandFraction: Float, 325 ) 326 { 327 buffer.log( 328 TAG, 329 LogLevel.VERBOSE, 330 { 331 str1 = msg 332 bool1 = panelClosedOnDown 333 double1 = expandFraction.toDouble() 334 }, 335 { "$str1; mPanelClosedOnDown=$bool1; mExpandedFraction=$double1" } 336 ) 337 } 338 339 fun logPanelStateChanged(@PanelState panelState: Int) { 340 buffer.log( 341 TAG, 342 LogLevel.VERBOSE, 343 { 344 str1 = panelState.panelStateToString() 345 }, 346 { "New panel State: $str1" } 347 ) 348 } 349 350 fun flingQs(flingType: Int, isClick: Boolean) { 351 buffer.log( 352 TAG, 353 LogLevel.VERBOSE, 354 { 355 str1 = flingTypeToString(flingType) 356 bool1 = isClick 357 }, 358 { "QS fling with type $str1, originated from click: $isClick" } 359 ) 360 } 361 362 private fun flingTypeToString(flingType: Int) = when (flingType) { 363 FLING_EXPAND -> "FLING_EXPAND" 364 FLING_COLLAPSE -> "FLING_COLLAPSE" 365 FLING_HIDE -> "FLING_HIDE" 366 else -> "UNKNOWN" 367 } 368 369 fun logSplitShadeChanged(splitShadeEnabled: Boolean) { 370 buffer.log( 371 TAG, 372 LogLevel.VERBOSE, 373 { bool1 = splitShadeEnabled }, 374 { "Split shade state changed: split shade ${if (bool1) "enabled" else "disabled"}" } 375 ) 376 } 377 378 fun logUpdateNotificationPanelTouchState( 379 disabled: Boolean, 380 isGoingToSleep: Boolean, 381 shouldControlScreenOff: Boolean, 382 deviceInteractive: Boolean, 383 isPulsing: Boolean, 384 isFrpActive: Boolean, 385 ) { 386 buffer.log( 387 TAG, 388 LogLevel.VERBOSE, 389 { 390 bool1 = disabled 391 bool2 = isGoingToSleep 392 bool3 = shouldControlScreenOff 393 bool4 = deviceInteractive 394 str1 = isPulsing.toString() 395 str2 = isFrpActive.toString() 396 }, 397 { 398 "CentralSurfaces updateNotificationPanelTouchState set disabled to: $bool1\n" + 399 "isGoingToSleep: $bool2, !shouldControlScreenOff: $bool3," + 400 "!mDeviceInteractive: $bool4, !isPulsing: $str1, isFrpActive: $str2" 401 } 402 ) 403 } 404 } 405