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