1 /* 2 * 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.wm 18 19 import android.graphics.Rect 20 21 /** 22 * Represents WindowContainer classes such as DisplayContent.WindowContainers and 23 * DisplayContent.NonAppWindowContainers. This can be expanded into a specific class if we need 24 * track and assert some state in the future. 25 * 26 * This is a generic object that is reused by both Flicker and Winscope and cannot access internal 27 * Java/Android functionality 28 */ 29 class WindowContainerImpl( 30 override val title: String, 31 final override val token: String, 32 override val orientation: Int, 33 override val layerId: Int, 34 _isVisible: Boolean, 35 private val configurationContainer: ConfigurationContainer, 36 _children: Collection<WindowContainer>, 37 override val computedZ: Int 38 ) : ConfigurationContainer by configurationContainer, WindowContainer { 39 override val id: Int = if (token.isEmpty()) -1 else token.toInt(16) 40 41 override val children: Collection<WindowContainer> = _children 42 43 override var parent: WindowContainer? = null 44 45 init { <lambda>null46 _children.forEach { it.parent = this } 47 } 48 49 override val isVisible: Boolean = _isVisible 50 override val name: String 51 get() = title 52 override val stableId: String 53 get() = "${this::class.simpleName} $token $title" 54 override val isFullscreen: Boolean = false 55 override val bounds: Rect = Rect() 56 toStringnull57 override fun toString(): String { 58 if ( 59 this.title.isEmpty() || 60 listOf("WindowContainer", "Task").any { it.contains(this.title) } 61 ) { 62 return "" 63 } 64 65 return "$${removeRedundancyInName(this.title)}@${this.token}" 66 } 67 removeRedundancyInNamenull68 private fun removeRedundancyInName(name: String): String { 69 if (!name.contains('/')) { 70 return name 71 } 72 73 val split = name.split('/') 74 val pkg = split[0] 75 var clazz = split.slice(1..split.lastIndex).joinToString("/") 76 77 if (clazz.startsWith("$pkg.")) { 78 clazz = clazz.slice(pkg.length + 1..clazz.lastIndex) 79 80 return "$pkg/$clazz" 81 } 82 83 return name 84 } 85 equalsnull86 override fun equals(other: Any?): Boolean { 87 if (this === other) return true 88 if (other !is WindowContainerImpl) return false 89 90 if (title != other.title) return false 91 if (token != other.token) return false 92 if (orientation != other.orientation) return false 93 if (isVisible != other.isVisible) return false 94 if (name != other.name) return false 95 if (isFullscreen != other.isFullscreen) return false 96 if (bounds != other.bounds) return false 97 98 return true 99 } 100 hashCodenull101 override fun hashCode(): Int { 102 var result = title.hashCode() 103 result = 31 * result + token.hashCode() 104 result = 31 * result + orientation 105 result = 31 * result + children.hashCode() 106 result = 31 * result + isVisible.hashCode() 107 result = 31 * result + name.hashCode() 108 result = 31 * result + isFullscreen.hashCode() 109 result = 31 * result + bounds.hashCode() 110 return result 111 } 112 113 override val isEmpty: Boolean 114 get() = configurationContainer.isEmpty && title.isEmpty() && token.isEmpty() 115 } 116