1 /* <lambda>null2 * 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.server.wm.traces.parser.windowmanager 18 19 import android.app.nano.WindowConfigurationProto 20 import android.content.nano.ConfigurationProto 21 import android.graphics.nano.RectProto 22 import android.util.Log 23 import android.view.nano.ViewProtoEnums 24 import android.view.nano.WindowLayoutParamsProto 25 import com.android.server.wm.nano.ActivityRecordProto 26 import com.android.server.wm.nano.AppTransitionProto 27 import com.android.server.wm.nano.ConfigurationContainerProto 28 import com.android.server.wm.nano.DisplayAreaProto 29 import com.android.server.wm.nano.DisplayContentProto 30 import com.android.server.wm.nano.KeyguardControllerProto 31 import com.android.server.wm.nano.RootWindowContainerProto 32 import com.android.server.wm.nano.TaskFragmentProto 33 import com.android.server.wm.nano.TaskProto 34 import com.android.server.wm.nano.WindowContainerChildProto 35 import com.android.server.wm.nano.WindowContainerProto 36 import com.android.server.wm.nano.WindowManagerPolicyProto 37 import com.android.server.wm.nano.WindowManagerServiceDumpProto 38 import com.android.server.wm.nano.WindowManagerTraceFileProto 39 import com.android.server.wm.nano.WindowStateProto 40 import com.android.server.wm.nano.WindowTokenProto 41 import com.android.server.wm.traces.common.Rect 42 import com.android.server.wm.traces.common.Size 43 import com.android.server.wm.traces.common.windowmanager.WindowManagerState 44 import com.android.server.wm.traces.common.windowmanager.WindowManagerTrace 45 import com.android.server.wm.traces.common.windowmanager.windows.Activity 46 import com.android.server.wm.traces.common.windowmanager.windows.Configuration 47 import com.android.server.wm.traces.common.windowmanager.windows.ConfigurationContainer 48 import com.android.server.wm.traces.common.windowmanager.windows.DisplayArea 49 import com.android.server.wm.traces.common.windowmanager.windows.DisplayContent 50 import com.android.server.wm.traces.common.windowmanager.windows.KeyguardControllerState 51 import com.android.server.wm.traces.common.windowmanager.windows.RootWindowContainer 52 import com.android.server.wm.traces.common.windowmanager.windows.Task 53 import com.android.server.wm.traces.common.windowmanager.windows.TaskFragment 54 import com.android.server.wm.traces.common.windowmanager.windows.WindowConfiguration 55 import com.android.server.wm.traces.common.windowmanager.windows.WindowContainer 56 import com.android.server.wm.traces.common.windowmanager.windows.WindowLayoutParams 57 import com.android.server.wm.traces.common.windowmanager.windows.WindowManagerPolicy 58 import com.android.server.wm.traces.common.windowmanager.windows.WindowState 59 import com.android.server.wm.traces.common.windowmanager.windows.WindowToken 60 import com.android.server.wm.traces.parser.LOG_TAG 61 import com.google.protobuf.nano.InvalidProtocolBufferNanoException 62 import kotlin.math.max 63 import kotlin.system.measureTimeMillis 64 65 object WindowManagerTraceParser { 66 private const val TRANSIT_ACTIVITY_OPEN = "TRANSIT_ACTIVITY_OPEN" 67 private const val TRANSIT_ACTIVITY_CLOSE = "TRANSIT_ACTIVITY_CLOSE" 68 private const val TRANSIT_TASK_OPEN = "TRANSIT_TASK_OPEN" 69 private const val TRANSIT_TASK_CLOSE = "TRANSIT_TASK_CLOSE" 70 private const val TRANSIT_WALLPAPER_OPEN = "TRANSIT_WALLPAPER_OPEN" 71 private const val TRANSIT_WALLPAPER_CLOSE = "TRANSIT_WALLPAPER_CLOSE" 72 private const val TRANSIT_WALLPAPER_INTRA_OPEN = "TRANSIT_WALLPAPER_INTRA_OPEN" 73 private const val TRANSIT_WALLPAPER_INTRA_CLOSE = "TRANSIT_WALLPAPER_INTRA_CLOSE" 74 private const val TRANSIT_KEYGUARD_GOING_AWAY = "TRANSIT_KEYGUARD_GOING_AWAY" 75 private const val TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 76 "TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER" 77 private const val TRANSIT_KEYGUARD_OCCLUDE = "TRANSIT_KEYGUARD_OCCLUDE" 78 private const val TRANSIT_KEYGUARD_UNOCCLUDE = "TRANSIT_KEYGUARD_UNOCCLUDE" 79 private const val TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = "TRANSIT_TRANSLUCENT_ACTIVITY_OPEN" 80 private const val TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = "TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE" 81 82 /** 83 * Parses [WindowManagerTraceFileProto] from [data] and uses the proto to generates 84 * a list of trace entries. 85 * 86 * @param data binary proto data 87 */ 88 @JvmOverloads 89 @JvmStatic 90 fun parseFromTrace( 91 data: ByteArray? 92 ): WindowManagerTrace { 93 var fileProto: WindowManagerTraceFileProto? = null 94 try { 95 measureTimeMillis { 96 fileProto = WindowManagerTraceFileProto.parseFrom(data) 97 }.also { 98 Log.v(LOG_TAG, "Parsing proto (WM Trace): ${it}ms") 99 } 100 } catch (e: InvalidProtocolBufferNanoException) { 101 throw RuntimeException(e) 102 } 103 104 return fileProto?.let { parseFromTrace(it) } 105 ?: error("Unable to read trace file") 106 } 107 108 /** 109 * Uses the proto to generates a list of trace entries. 110 * 111 * @param proto Parsed proto data 112 */ 113 @JvmOverloads 114 @JvmStatic 115 fun parseFromTrace( 116 proto: WindowManagerTraceFileProto 117 ): WindowManagerTrace { 118 val entries = mutableListOf<WindowManagerState>() 119 var traceParseTime = 0L 120 for (entryProto in proto.entry) { 121 val entryParseTime = measureTimeMillis { 122 val entry = newTraceEntry(entryProto.windowManagerService, 123 entryProto.elapsedRealtimeNanos, entryProto.where) 124 entries.add(entry) 125 } 126 traceParseTime += entryParseTime 127 } 128 129 Log.v(LOG_TAG, "Parsing duration (WM Trace): ${traceParseTime}ms " + 130 "(avg ${traceParseTime / max(entries.size, 1)}ms per entry)") 131 return WindowManagerTrace(entries.toTypedArray()) 132 } 133 134 /** 135 * Parses [WindowManagerServiceDumpProto] from [proto] dump and uses the proto to generates 136 * a list of trace entries. 137 * 138 * @param proto Parsed proto data 139 */ 140 @JvmStatic 141 fun parseFromDump(proto: WindowManagerServiceDumpProto): WindowManagerTrace { 142 return WindowManagerTrace( 143 arrayOf(newTraceEntry(proto, timestamp = 0, where = ""))) 144 } 145 146 /** 147 * Parses [WindowManagerServiceDumpProto] from [data] and uses the proto to generates 148 * a list of trace entries. 149 * 150 * @param data binary proto data 151 */ 152 @JvmStatic 153 fun parseFromDump(data: ByteArray?): WindowManagerTrace { 154 val fileProto = try { 155 WindowManagerServiceDumpProto.parseFrom(data) 156 } catch (e: InvalidProtocolBufferNanoException) { 157 throw RuntimeException(e) 158 } 159 return parseFromDump(fileProto) 160 } 161 162 private fun newTraceEntry( 163 proto: WindowManagerServiceDumpProto, 164 timestamp: Long, 165 where: String 166 ): WindowManagerState { 167 return WindowManagerState( 168 where = where, 169 policy = newWindowManagerPolicy(proto.policy), 170 focusedApp = proto.focusedApp, 171 focusedDisplayId = proto.focusedDisplayId, 172 focusedWindow = proto.focusedWindow?.title ?: "", 173 inputMethodWindowAppToken = if (proto.inputMethodWindow != null) { 174 Integer.toHexString(proto.inputMethodWindow.hashCode) 175 } else { 176 "" 177 }, 178 isHomeRecentsComponent = proto.rootWindowContainer.isHomeRecentsComponent, 179 isDisplayFrozen = proto.displayFrozen, 180 pendingActivities = proto.rootWindowContainer.pendingActivities 181 .map { it.title }.toTypedArray(), 182 root = newRootWindowContainer(proto.rootWindowContainer), 183 keyguardControllerState = newKeyguardControllerState( 184 proto.rootWindowContainer.keyguardController), 185 _timestamp = timestamp.toString() 186 ) 187 } 188 189 private fun newWindowManagerPolicy(proto: WindowManagerPolicyProto): WindowManagerPolicy { 190 return WindowManagerPolicy( 191 focusedAppToken = proto.focusedAppToken ?: "", 192 forceStatusBar = proto.forceStatusBar, 193 forceStatusBarFromKeyguard = proto.forceStatusBarFromKeyguard, 194 keyguardDrawComplete = proto.keyguardDrawComplete, 195 keyguardOccluded = proto.keyguardOccluded, 196 keyguardOccludedChanged = proto.keyguardOccludedChanged, 197 keyguardOccludedPending = proto.keyguardOccludedPending, 198 lastSystemUiFlags = proto.lastSystemUiFlags, 199 orientation = proto.orientation, 200 rotation = proto.rotation, 201 rotationMode = proto.rotationMode, 202 screenOnFully = proto.screenOnFully, 203 windowManagerDrawComplete = proto.windowManagerDrawComplete 204 ) 205 } 206 207 private fun newRootWindowContainer(proto: RootWindowContainerProto): RootWindowContainer { 208 return RootWindowContainer( 209 newWindowContainer( 210 proto.windowContainer, 211 proto.windowContainer.children 212 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree = false) } 213 ) ?: error("Window container should not be null") 214 ) 215 } 216 217 private fun newKeyguardControllerState( 218 proto: KeyguardControllerProto? 219 ): KeyguardControllerState { 220 return KeyguardControllerState( 221 isAodShowing = proto?.aodShowing ?: false, 222 isKeyguardShowing = proto?.keyguardShowing ?: false, 223 keyguardOccludedStates = proto?.keyguardOccludedStates 224 ?.map { it.displayId to it.keyguardOccluded } 225 ?.toMap() 226 ?: emptyMap() 227 ) 228 } 229 230 private fun newWindowContainerChild( 231 proto: WindowContainerChildProto, 232 isActivityInTree: Boolean 233 ): WindowContainer? { 234 return newDisplayContent(proto.displayContent, isActivityInTree) 235 ?: newDisplayArea(proto.displayArea, isActivityInTree) 236 ?: newTask(proto.task, isActivityInTree) 237 ?: newTaskFragment(proto.taskFragment, isActivityInTree) 238 ?: newActivity(proto.activity) 239 ?: newWindowToken(proto.windowToken, isActivityInTree) 240 ?: newWindowState(proto.window, isActivityInTree) 241 ?: newWindowContainer(proto.windowContainer, children = emptyList()) 242 } 243 244 private fun newDisplayContent( 245 proto: DisplayContentProto?, 246 isActivityInTree: Boolean 247 ): DisplayContent? { 248 return if (proto == null) { 249 null 250 } else { 251 DisplayContent( 252 id = proto.id, 253 focusedRootTaskId = proto.focusedRootTaskId, 254 resumedActivity = proto.resumedActivity?.title ?: "", 255 singleTaskInstance = proto.singleTaskInstance, 256 defaultPinnedStackBounds = proto.pinnedTaskController?.defaultBounds?.toRect() 257 ?: Rect.EMPTY, 258 pinnedStackMovementBounds = proto.pinnedTaskController?.movementBounds?.toRect() 259 ?: Rect.EMPTY, 260 displayRect = Rect(0, 0, proto.displayInfo?.logicalWidth 261 ?: 0, proto.displayInfo?.logicalHeight ?: 0), 262 appRect = Rect(0, 0, proto.displayInfo?.appWidth ?: 0, 263 proto.displayInfo?.appHeight 264 ?: 0), 265 dpi = proto.dpi, 266 flags = proto.displayInfo?.flags ?: 0, 267 stableBounds = proto.displayFrames?.stableBounds?.toRect() ?: Rect.EMPTY, 268 surfaceSize = proto.surfaceSize, 269 focusedApp = proto.focusedApp, 270 lastTransition = appTransitionToString( 271 proto.appTransition?.lastUsedAppTransition ?: 0), 272 appTransitionState = appStateToString( 273 proto.appTransition?.appTransitionState ?: 0), 274 rotation = proto.displayRotation?.rotation ?: 0, 275 lastOrientation = proto.displayRotation?.lastOrientation ?: 0, 276 windowContainer = newWindowContainer( 277 proto.rootDisplayArea.windowContainer, 278 proto.rootDisplayArea.windowContainer.children 279 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) }, 280 nameOverride = proto.displayInfo?.name ?: "" 281 ) ?: error("Window container should not be null") 282 ) 283 } 284 } 285 286 private fun newDisplayArea(proto: DisplayAreaProto?, isActivityInTree: Boolean): DisplayArea? { 287 return if (proto == null) { 288 null 289 } else { 290 DisplayArea( 291 isTaskDisplayArea = proto.isTaskDisplayArea, 292 windowContainer = newWindowContainer( 293 proto.windowContainer, 294 proto.windowContainer.children 295 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) } 296 ) ?: error("Window container should not be null") 297 ) 298 } 299 } 300 301 private fun newTask(proto: TaskProto?, isActivityInTree: Boolean): Task? { 302 return if (proto == null) { 303 null 304 } else { 305 Task( 306 activityType = proto.taskFragment?.activityType ?: proto.activityType, 307 isFullscreen = proto.fillsParent, 308 bounds = proto.bounds.toRect(), 309 taskId = proto.id, 310 rootTaskId = proto.rootTaskId, 311 displayId = proto.taskFragment?.displayId ?: proto.displayId, 312 lastNonFullscreenBounds = proto.lastNonFullscreenBounds?.toRect() ?: Rect.EMPTY, 313 realActivity = proto.realActivity, 314 origActivity = proto.origActivity, 315 resizeMode = proto.resizeMode, 316 _resumedActivity = proto.resumedActivity?.title ?: "", 317 animatingBounds = proto.animatingBounds, 318 surfaceWidth = proto.surfaceWidth, 319 surfaceHeight = proto.surfaceHeight, 320 createdByOrganizer = proto.createdByOrganizer, 321 minWidth = proto.taskFragment?.minWidth ?: proto.minWidth, 322 minHeight = proto.taskFragment?.minHeight ?: proto.minHeight, 323 windowContainer = newWindowContainer( 324 proto.taskFragment?.windowContainer ?: proto.windowContainer, 325 if (proto.taskFragment != null) { 326 proto.taskFragment.windowContainer.children 327 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) } 328 } else { 329 proto.windowContainer.children 330 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) } 331 } 332 ) ?: error("Window container should not be null") 333 ) 334 } 335 } 336 337 private fun newTaskFragment(proto: TaskFragmentProto?, isActivityInTree: Boolean): 338 TaskFragment? { 339 return if (proto == null) { 340 null 341 } else { 342 TaskFragment( 343 activityType = proto.activityType, 344 displayId = proto.displayId, 345 minWidth = proto.minWidth, 346 minHeight = proto.minHeight, 347 windowContainer = newWindowContainer( 348 proto.windowContainer, 349 proto.windowContainer.children 350 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) } 351 ) ?: error("Window container should not be null") 352 ) 353 } 354 } 355 356 private fun newActivity(proto: ActivityRecordProto?): Activity? { 357 return if (proto == null) { 358 null 359 } else { 360 Activity( 361 name = proto.name, 362 state = proto.state, 363 visible = proto.visible, 364 frontOfTask = proto.frontOfTask, 365 procId = proto.procId, 366 isTranslucent = proto.translucent, 367 windowContainer = newWindowContainer( 368 proto.windowToken.windowContainer, 369 proto.windowToken.windowContainer.children 370 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree = true) } 371 ) ?: error("Window container should not be null") 372 ) 373 } 374 } 375 376 private fun newWindowToken(proto: WindowTokenProto?, isActivityInTree: Boolean): WindowToken? { 377 return if (proto == null) { 378 null 379 } else { 380 WindowToken( 381 newWindowContainer( 382 proto.windowContainer, 383 proto.windowContainer.children 384 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) } 385 ) ?: error("Window container should not be null") 386 ) 387 } 388 } 389 390 private fun newWindowState(proto: WindowStateProto?, isActivityInTree: Boolean): WindowState? { 391 return if (proto == null) { 392 null 393 } else { 394 val identifierName = proto.windowContainer.identifier?.title ?: "" 395 WindowState( 396 attributes = newWindowLayerParams(proto.attributes), 397 displayId = proto.displayId, 398 stackId = proto.stackId, 399 layer = proto.animator?.surface?.layer ?: 0, 400 isSurfaceShown = proto.animator?.surface?.shown ?: false, 401 windowType = when { 402 identifierName.startsWith(WindowState.STARTING_WINDOW_PREFIX) -> 403 WindowState.WINDOW_TYPE_STARTING 404 proto.animatingExit -> WindowState.WINDOW_TYPE_EXITING 405 identifierName.startsWith(WindowState.DEBUGGER_WINDOW_PREFIX) -> 406 WindowState.WINDOW_TYPE_STARTING 407 else -> 0 408 }, 409 requestedSize = Size(proto.requestedWidth, proto.requestedHeight), 410 surfacePosition = proto.surfacePosition?.toRect(), 411 frame = proto.windowFrames?.frame?.toRect() ?: Rect.EMPTY, 412 containingFrame = proto.windowFrames?.containingFrame?.toRect() ?: Rect.EMPTY, 413 parentFrame = proto.windowFrames?.parentFrame?.toRect() ?: Rect.EMPTY, 414 contentFrame = proto.windowFrames?.contentFrame?.toRect() ?: Rect.EMPTY, 415 contentInsets = proto.windowFrames?.contentInsets?.toRect() ?: Rect.EMPTY, 416 surfaceInsets = proto.surfaceInsets?.toRect() ?: Rect.EMPTY, 417 givenContentInsets = proto.givenContentInsets?.toRect() ?: Rect.EMPTY, 418 crop = proto.animator?.lastClipRect?.toRect() ?: Rect.EMPTY, 419 windowContainer = newWindowContainer( 420 proto.windowContainer, 421 proto.windowContainer.children 422 .mapNotNull { p -> newWindowContainerChild(p, isActivityInTree) }, 423 nameOverride = when { 424 // Existing code depends on the prefix being removed 425 identifierName.startsWith(WindowState.STARTING_WINDOW_PREFIX) -> 426 identifierName.substring(WindowState.STARTING_WINDOW_PREFIX.length) 427 identifierName.startsWith(WindowState.DEBUGGER_WINDOW_PREFIX) -> 428 identifierName.substring(WindowState.DEBUGGER_WINDOW_PREFIX.length) 429 else -> identifierName 430 } 431 ) ?: error("Window container should not be null"), 432 isAppWindow = isActivityInTree 433 ) 434 } 435 } 436 437 private fun newWindowLayerParams(proto: WindowLayoutParamsProto?): WindowLayoutParams { 438 return WindowLayoutParams( 439 type = proto?.type ?: 0, 440 x = proto?.x ?: 0, 441 y = proto?.y ?: 0, 442 width = proto?.width ?: 0, 443 height = proto?.height ?: 0, 444 horizontalMargin = proto?.horizontalMargin ?: 0f, 445 verticalMargin = proto?.verticalMargin ?: 0f, 446 gravity = proto?.gravity ?: 0, 447 softInputMode = proto?.softInputMode ?: 0, 448 format = proto?.format ?: 0, 449 windowAnimations = proto?.windowAnimations ?: 0, 450 alpha = proto?.alpha ?: 0f, 451 screenBrightness = proto?.screenBrightness ?: 0f, 452 buttonBrightness = proto?.buttonBrightness ?: 0f, 453 rotationAnimation = proto?.rotationAnimation ?: 0, 454 preferredRefreshRate = proto?.preferredRefreshRate ?: 0f, 455 preferredDisplayModeId = proto?.preferredDisplayModeId ?: 0, 456 hasSystemUiListeners = proto?.hasSystemUiListeners ?: false, 457 inputFeatureFlags = proto?.inputFeatureFlags ?: 0, 458 userActivityTimeout = proto?.userActivityTimeout ?: 0, 459 colorMode = proto?.colorMode ?: 0, 460 flags = proto?.flags ?: 0, 461 privateFlags = proto?.privateFlags ?: 0, 462 systemUiVisibilityFlags = proto?.systemUiVisibilityFlags ?: 0, 463 subtreeSystemUiVisibilityFlags = proto?.subtreeSystemUiVisibilityFlags ?: 0, 464 appearance = proto?.appearance ?: 0, 465 behavior = proto?.behavior ?: 0, 466 fitInsetsTypes = proto?.fitInsetsTypes ?: 0, 467 fitInsetsSides = proto?.fitInsetsSides ?: 0, 468 fitIgnoreVisibility = proto?.fitIgnoreVisibility ?: false 469 ) 470 } 471 472 private fun newConfigurationContainer( 473 proto: ConfigurationContainerProto? 474 ): ConfigurationContainer { 475 return ConfigurationContainer( 476 overrideConfiguration = newConfiguration(proto?.overrideConfiguration), 477 fullConfiguration = newConfiguration(proto?.fullConfiguration), 478 mergedOverrideConfiguration = newConfiguration(proto?.mergedOverrideConfiguration) 479 ) 480 } 481 482 private fun newConfiguration(proto: ConfigurationProto?): Configuration? { 483 return if (proto == null) { 484 null 485 } else { 486 Configuration( 487 windowConfiguration = if (proto.windowConfiguration != null) { 488 newWindowConfiguration(proto.windowConfiguration) 489 } else { 490 null 491 }, 492 densityDpi = proto.densityDpi, 493 orientation = proto.orientation, 494 screenHeightDp = proto.screenHeightDp, 495 screenWidthDp = proto.screenWidthDp, 496 smallestScreenWidthDp = proto.smallestScreenWidthDp, 497 screenLayout = proto.screenLayout, 498 uiMode = proto.uiMode 499 ) 500 } 501 } 502 503 private fun newWindowConfiguration(proto: WindowConfigurationProto): WindowConfiguration { 504 return WindowConfiguration( 505 _appBounds = proto.appBounds?.toRect(), 506 _bounds = proto.bounds?.toRect(), 507 _maxBounds = proto.maxBounds?.toRect(), 508 windowingMode = proto.windowingMode, 509 activityType = proto.activityType 510 ) 511 } 512 513 private fun newWindowContainer( 514 proto: WindowContainerProto?, 515 children: List<WindowContainer>, 516 nameOverride: String? = null 517 ): WindowContainer? { 518 return if (proto == null) { 519 null 520 } else { 521 WindowContainer( 522 title = nameOverride ?: proto.identifier?.title ?: "", 523 token = proto.identifier?.hashCode?.toString(16) ?: "", 524 orientation = proto.orientation, 525 _isVisible = proto.visible, 526 configurationContainer = newConfigurationContainer( 527 proto.configurationContainer), 528 layerId = proto.surfaceControl?.layerId ?: 0, 529 children = children.toTypedArray() 530 ) 531 } 532 } 533 534 private fun appTransitionToString(transition: Int): String { 535 return when (transition) { 536 ViewProtoEnums.TRANSIT_UNSET -> "TRANSIT_UNSET" 537 ViewProtoEnums.TRANSIT_NONE -> "TRANSIT_NONE" 538 ViewProtoEnums.TRANSIT_ACTIVITY_OPEN -> TRANSIT_ACTIVITY_OPEN 539 ViewProtoEnums.TRANSIT_ACTIVITY_CLOSE -> TRANSIT_ACTIVITY_CLOSE 540 ViewProtoEnums.TRANSIT_TASK_OPEN -> TRANSIT_TASK_OPEN 541 ViewProtoEnums.TRANSIT_TASK_CLOSE -> TRANSIT_TASK_CLOSE 542 ViewProtoEnums.TRANSIT_TASK_TO_FRONT -> "TRANSIT_TASK_TO_FRONT" 543 ViewProtoEnums.TRANSIT_TASK_TO_BACK -> "TRANSIT_TASK_TO_BACK" 544 ViewProtoEnums.TRANSIT_WALLPAPER_CLOSE -> TRANSIT_WALLPAPER_CLOSE 545 ViewProtoEnums.TRANSIT_WALLPAPER_OPEN -> TRANSIT_WALLPAPER_OPEN 546 ViewProtoEnums.TRANSIT_WALLPAPER_INTRA_OPEN -> TRANSIT_WALLPAPER_INTRA_OPEN 547 ViewProtoEnums.TRANSIT_WALLPAPER_INTRA_CLOSE -> TRANSIT_WALLPAPER_INTRA_CLOSE 548 ViewProtoEnums.TRANSIT_TASK_OPEN_BEHIND -> "TRANSIT_TASK_OPEN_BEHIND" 549 ViewProtoEnums.TRANSIT_ACTIVITY_RELAUNCH -> "TRANSIT_ACTIVITY_RELAUNCH" 550 ViewProtoEnums.TRANSIT_DOCK_TASK_FROM_RECENTS -> "TRANSIT_DOCK_TASK_FROM_RECENTS" 551 ViewProtoEnums.TRANSIT_KEYGUARD_GOING_AWAY -> TRANSIT_KEYGUARD_GOING_AWAY 552 ViewProtoEnums.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER -> 553 TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER 554 ViewProtoEnums.TRANSIT_KEYGUARD_OCCLUDE -> TRANSIT_KEYGUARD_OCCLUDE 555 ViewProtoEnums.TRANSIT_KEYGUARD_UNOCCLUDE -> TRANSIT_KEYGUARD_UNOCCLUDE 556 ViewProtoEnums.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN -> 557 TRANSIT_TRANSLUCENT_ACTIVITY_OPEN 558 ViewProtoEnums.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE -> 559 TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE 560 ViewProtoEnums.TRANSIT_CRASHING_ACTIVITY_CLOSE -> "TRANSIT_CRASHING_ACTIVITY_CLOSE" 561 else -> error("Invalid lastUsedAppTransition") 562 } 563 } 564 565 private fun appStateToString(appState: Int): String { 566 return when (appState) { 567 AppTransitionProto.APP_STATE_IDLE -> "APP_STATE_IDLE" 568 AppTransitionProto.APP_STATE_READY -> "APP_STATE_READY" 569 AppTransitionProto.APP_STATE_RUNNING -> "APP_STATE_RUNNING" 570 AppTransitionProto.APP_STATE_TIMEOUT -> "APP_STATE_TIMEOUT" 571 else -> error("Invalid AppTransitionState") 572 } 573 } 574 575 private fun RectProto.toRect() = Rect(this.left, this.top, this.right, this.bottom) 576 } 577