1 /* 2 * 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.common.windowmanager.windows 18 19 import com.android.server.wm.traces.common.Size 20 import com.android.server.wm.traces.common.Rect 21 import com.android.server.wm.traces.common.region.Region 22 23 /** 24 * Represents a window in the window manager hierarchy 25 * 26 * This is a generic object that is reused by both Flicker and Winscope and cannot 27 * access internal Java/Android functionality 28 * 29 */ 30 open class WindowState( 31 val attributes: WindowLayoutParams, 32 val displayId: Int, 33 val stackId: Int, 34 val layer: Int, 35 val isSurfaceShown: Boolean, 36 val windowType: Int, 37 val requestedSize: Size, 38 val surfacePosition: Rect?, 39 val frame: Rect, 40 val containingFrame: Rect, 41 val parentFrame: Rect, 42 val contentFrame: Rect, 43 val contentInsets: Rect, 44 val surfaceInsets: Rect, 45 val givenContentInsets: Rect, 46 val crop: Rect, 47 windowContainer: WindowContainer, 48 val isAppWindow: Boolean 49 ) : WindowContainer(windowContainer, getWindowTitle(windowContainer.title)) { 50 override val isVisible: Boolean get() = super.isVisible && attributes.alpha > 0 51 52 override val isFullscreen: Boolean get() = this.attributes.flags.and(FLAG_FULLSCREEN) > 0 53 val isStartingWindow: Boolean = windowType == WINDOW_TYPE_STARTING 54 val isExitingWindow: Boolean = windowType == WINDOW_TYPE_EXITING 55 val isDebuggerWindow: Boolean = windowType == WINDOW_TYPE_DEBUGGER 56 val isValidNavBarType: Boolean = attributes.isValidNavBarType 57 58 val frameRegion: Region = Region.from(frame) 59 getWindowTypeSuffixnull60 private fun getWindowTypeSuffix(windowType: Int): String = 61 when (windowType) { 62 WINDOW_TYPE_STARTING -> " STARTING" 63 WINDOW_TYPE_EXITING -> " EXITING" 64 WINDOW_TYPE_DEBUGGER -> " DEBUGGER" 65 else -> "" 66 } 67 toStringnull68 override fun toString(): String = "${this::class.simpleName}: " + 69 "{$token $title${getWindowTypeSuffix(windowType)}} " + 70 "type=${attributes.type} cf=$containingFrame pf=$parentFrame" 71 72 override fun equals(other: Any?): Boolean { 73 if (this === other) return true 74 if (other !is WindowState) return false 75 76 if (name != other.name) return false 77 if (attributes != other.attributes) return false 78 if (displayId != other.displayId) return false 79 if (stackId != other.stackId) return false 80 if (layer != other.layer) return false 81 if (isSurfaceShown != other.isSurfaceShown) return false 82 if (windowType != other.windowType) return false 83 if (requestedSize != other.requestedSize) return false 84 if (surfacePosition != other.surfacePosition) return false 85 if (frame != other.frame) return false 86 if (containingFrame != other.containingFrame) return false 87 if (parentFrame != other.parentFrame) return false 88 if (contentFrame != other.contentFrame) return false 89 if (contentInsets != other.contentInsets) return false 90 if (surfaceInsets != other.surfaceInsets) return false 91 if (givenContentInsets != other.givenContentInsets) return false 92 if (crop != other.crop) return false 93 if (isAppWindow != other.isAppWindow) return false 94 95 return true 96 } 97 hashCodenull98 override fun hashCode(): Int { 99 var result = attributes.hashCode() 100 result = 31 * result + displayId 101 result = 31 * result + stackId 102 result = 31 * result + layer 103 result = 31 * result + isSurfaceShown.hashCode() 104 result = 31 * result + windowType 105 result = 31 * result + frame.hashCode() 106 result = 31 * result + containingFrame.hashCode() 107 result = 31 * result + parentFrame.hashCode() 108 result = 31 * result + contentFrame.hashCode() 109 result = 31 * result + contentInsets.hashCode() 110 result = 31 * result + surfaceInsets.hashCode() 111 result = 31 * result + givenContentInsets.hashCode() 112 result = 31 * result + crop.hashCode() 113 result = 31 * result + isAppWindow.hashCode() 114 result = 31 * result + isStartingWindow.hashCode() 115 result = 31 * result + isExitingWindow.hashCode() 116 result = 31 * result + isDebuggerWindow.hashCode() 117 result = 31 * result + isValidNavBarType.hashCode() 118 result = 31 * result + frameRegion.hashCode() 119 return result 120 } 121 122 companion object { 123 /** 124 * From {@see android.view.WindowManager.FLAG_FULLSCREEN}. 125 * 126 * This class is shared between JVM and JS (Winscope) and cannot access 127 * Android internals 128 */ 129 private const val FLAG_FULLSCREEN = 0x00000400 130 internal const val WINDOW_TYPE_STARTING = 1 131 internal const val WINDOW_TYPE_EXITING = 2 132 private const val WINDOW_TYPE_DEBUGGER = 3 133 134 internal const val STARTING_WINDOW_PREFIX = "Starting " 135 internal const val DEBUGGER_WINDOW_PREFIX = "Waiting For Debugger: " 136 getWindowTitlenull137 private fun getWindowTitle(title: String): String { 138 return when { 139 // Existing code depends on the prefix being removed 140 title.startsWith(STARTING_WINDOW_PREFIX) -> 141 title.substring(STARTING_WINDOW_PREFIX.length) 142 title.startsWith(DEBUGGER_WINDOW_PREFIX) -> 143 title.substring(DEBUGGER_WINDOW_PREFIX.length) 144 else -> title 145 } 146 } 147 } 148 } 149