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 53 override val stableId: String 54 get() = "${this::class.simpleName} $token $title" 55 56 override val isFullscreen: Boolean = false 57 override val bounds: Rect = Rect() 58 toStringnull59 override fun toString(): String { 60 if ( 61 this.title.isEmpty() || 62 listOf("WindowContainer", "Task").any { it.contains(this.title) } 63 ) { 64 return "" 65 } 66 67 return "$${removeRedundancyInName(this.title)}@${this.token}" 68 } 69 removeRedundancyInNamenull70 private fun removeRedundancyInName(name: String): String { 71 if (!name.contains('/')) { 72 return name 73 } 74 75 val split = name.split('/') 76 val pkg = split[0] 77 var clazz = split.slice(1..split.lastIndex).joinToString("/") 78 79 if (clazz.startsWith("$pkg.")) { 80 clazz = clazz.slice(pkg.length + 1..clazz.lastIndex) 81 82 return "$pkg/$clazz" 83 } 84 85 return name 86 } 87 equalsnull88 override fun equals(other: Any?): Boolean { 89 if (this === other) return true 90 if (other !is WindowContainerImpl) return false 91 92 if (title != other.title) return false 93 if (token != other.token) return false 94 if (orientation != other.orientation) return false 95 if (isVisible != other.isVisible) return false 96 if (name != other.name) return false 97 if (isFullscreen != other.isFullscreen) return false 98 if (bounds != other.bounds) return false 99 100 return true 101 } 102 hashCodenull103 override fun hashCode(): Int { 104 var result = title.hashCode() 105 result = 31 * result + token.hashCode() 106 result = 31 * result + orientation 107 result = 31 * result + children.hashCode() 108 result = 31 * result + isVisible.hashCode() 109 result = 31 * result + name.hashCode() 110 result = 31 * result + isFullscreen.hashCode() 111 result = 31 * result + bounds.hashCode() 112 return result 113 } 114 115 override val isEmpty: Boolean 116 get() = configurationContainer.isEmpty && title.isEmpty() && token.isEmpty() 117 } 118