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 */ 16import {com} from 'protos/windowmanager/latest/static'; 17import { 18 CustomQueryParserResultTypeMap, 19 CustomQueryType, 20} from 'trace/custom_query'; 21 22type WindowsTokenAndTitle = 23 CustomQueryParserResultTypeMap[CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE]; 24 25export class WmCustomQueryUtils { 26 private static readonly NA = 'n/a'; 27 28 static parseWindowsTokenAndTitle( 29 rootWindowContainer: com.android.server.wm.IRootWindowContainerProto, 30 result: WindowsTokenAndTitle, 31 ) { 32 const token = 33 rootWindowContainer?.windowContainer?.identifier?.hashCode?.toString( 34 16, 35 ) ?? WmCustomQueryUtils.NA; 36 const title = 37 rootWindowContainer?.windowContainer?.identifier?.title ?? 38 WmCustomQueryUtils.NA; 39 result.push({token, title}); 40 WmCustomQueryUtils.parseWindowContainerProto( 41 rootWindowContainer?.windowContainer, 42 result, 43 ); 44 } 45 46 private static parseWindowContainerProto( 47 proto: com.android.server.wm.IWindowContainerProto | null | undefined, 48 result: WindowsTokenAndTitle, 49 ) { 50 if (!proto) { 51 return; 52 } 53 54 for (const windowContainerChildProto of proto?.children ?? []) { 55 WmCustomQueryUtils.parseActivityRecordProto( 56 windowContainerChildProto.activity, 57 result, 58 ); 59 WmCustomQueryUtils.parseDisplayAreaProto( 60 windowContainerChildProto.displayArea, 61 result, 62 ); 63 WmCustomQueryUtils.parseDisplayContentProto( 64 windowContainerChildProto.displayContent, 65 result, 66 ); 67 WmCustomQueryUtils.parseTaskProto(windowContainerChildProto.task, result); 68 WmCustomQueryUtils.parseTaskFragmentProto( 69 windowContainerChildProto.taskFragment, 70 result, 71 ); 72 WmCustomQueryUtils.parseWindowStateProto( 73 windowContainerChildProto.window, 74 result, 75 ); 76 WmCustomQueryUtils.parseWindowContainerProto( 77 windowContainerChildProto.windowContainer, 78 result, 79 ); 80 WmCustomQueryUtils.parseWindowTokenProto( 81 windowContainerChildProto.windowToken, 82 result, 83 ); 84 } 85 } 86 87 private static parseActivityRecordProto( 88 proto: com.android.server.wm.IActivityRecordProto | null | undefined, 89 result: WindowsTokenAndTitle, 90 ) { 91 if (!proto) { 92 return; 93 } 94 const token = 95 proto.windowToken?.hashCode?.toString(16) ?? WmCustomQueryUtils.NA; 96 const title = proto.name ?? WmCustomQueryUtils.NA; 97 result.push({token, title}); 98 WmCustomQueryUtils.parseWindowContainerProto( 99 proto.windowToken?.windowContainer, 100 result, 101 ); 102 } 103 104 private static parseDisplayAreaProto( 105 proto: com.android.server.wm.IDisplayAreaProto | null | undefined, 106 result: WindowsTokenAndTitle, 107 ) { 108 if (!proto) { 109 return; 110 } 111 const token = 112 proto.windowContainer?.identifier?.hashCode?.toString(16) ?? 113 WmCustomQueryUtils.NA; 114 const title = proto.name ?? WmCustomQueryUtils.NA; 115 result.push({token, title}); 116 WmCustomQueryUtils.parseWindowContainerProto(proto.windowContainer, result); 117 } 118 119 private static parseDisplayContentProto( 120 proto: com.android.server.wm.IDisplayContentProto | null | undefined, 121 result: WindowsTokenAndTitle, 122 ) { 123 if (!proto) { 124 return; 125 } 126 const token = 127 proto.rootDisplayArea?.windowContainer?.identifier?.hashCode?.toString( 128 16, 129 ) ?? WmCustomQueryUtils.NA; 130 const title = proto.displayInfo?.name ?? WmCustomQueryUtils.NA; 131 result.push({token, title}); 132 WmCustomQueryUtils.parseWindowContainerProto( 133 proto.rootDisplayArea?.windowContainer, 134 result, 135 ); 136 } 137 138 private static parseTaskProto( 139 proto: com.android.server.wm.ITaskProto | null | undefined, 140 result: WindowsTokenAndTitle, 141 ) { 142 if (!proto) { 143 return; 144 } 145 const token = 146 proto.taskFragment?.windowContainer?.identifier?.hashCode?.toString(16) ?? 147 WmCustomQueryUtils.NA; 148 const title = 149 proto.taskFragment?.windowContainer?.identifier?.title ?? 150 WmCustomQueryUtils.NA; 151 result.push({token, title}); 152 for (const activity of proto.activities ?? []) { 153 WmCustomQueryUtils.parseActivityRecordProto(activity, result); 154 } 155 WmCustomQueryUtils.parseTaskFragmentProto(proto.taskFragment, result); 156 } 157 158 private static parseTaskFragmentProto( 159 proto: com.android.server.wm.ITaskFragmentProto | null | undefined, 160 result: WindowsTokenAndTitle, 161 ) { 162 if (!proto) { 163 return; 164 } 165 WmCustomQueryUtils.parseWindowContainerProto( 166 proto?.windowContainer, 167 result, 168 ); 169 } 170 171 private static parseWindowStateProto( 172 proto: com.android.server.wm.IWindowStateProto | null | undefined, 173 result: WindowsTokenAndTitle, 174 ) { 175 if (!proto) { 176 return; 177 } 178 const token = 179 proto.windowContainer?.identifier?.hashCode?.toString(16) ?? 180 WmCustomQueryUtils.NA; 181 const title = 182 proto.windowContainer?.identifier?.title ?? WmCustomQueryUtils.NA; 183 result.push({token, title}); 184 WmCustomQueryUtils.parseWindowContainerProto(proto.windowContainer, result); 185 } 186 187 private static parseWindowTokenProto( 188 proto: com.android.server.wm.IWindowTokenProto | null | undefined, 189 result: WindowsTokenAndTitle, 190 ) { 191 if (!proto) { 192 return; 193 } 194 const hash = proto.hashCode?.toString(16) ?? WmCustomQueryUtils.NA; 195 result.push({token: hash, title: hash}); 196 WmCustomQueryUtils.parseWindowContainerProto(proto.windowContainer, result); 197 } 198} 199