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