1/* 2 * Copyright (C) 2022 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 17import {assertDefined} from 'common/assert_utils'; 18import {Timestamp} from 'common/time'; 19import {AbstractParser} from 'parsers/legacy/abstract_parser'; 20import {com} from 'protos/windowmanager/latest/static'; 21import { 22 CustomQueryParserResultTypeMap, 23 CustomQueryType, 24 VisitableParserCustomQuery, 25} from 'trace/custom_query'; 26import {EntriesRange} from 'trace/index_types'; 27import {TraceType} from 'trace/trace_type'; 28import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 29import {PropertiesProvider} from 'trace/tree_node/properties_provider'; 30import {RectsComputation} from './computations/rects_computation'; 31import {WmCustomQueryUtils} from './custom_query_utils'; 32import {HierarchyTreeBuilderWm} from './hierarchy_tree_builder_wm'; 33import {ParserWmUtils} from './parser_window_manager_utils'; 34import {WindowManagerServiceField} from './wm_tampered_protos'; 35 36class ParserWindowManagerDump extends AbstractParser { 37 override getTraceType(): TraceType { 38 return TraceType.WINDOW_MANAGER; 39 } 40 41 override getMagicNumber(): undefined { 42 return undefined; 43 } 44 45 override getRealToBootTimeOffsetNs(): bigint | undefined { 46 return undefined; 47 } 48 49 override getRealToMonotonicTimeOffsetNs(): bigint | undefined { 50 return undefined; 51 } 52 53 override decodeTrace( 54 buffer: Uint8Array, 55 ): com.android.server.wm.IWindowManagerServiceDumpProto[] { 56 const entryProto = assertDefined( 57 WindowManagerServiceField.tamperedMessageType, 58 ).decode(buffer) as com.android.server.wm.IWindowManagerServiceDumpProto; 59 60 // This parser is prone to accepting invalid inputs because it lacks a magic 61 // number. Let's reduce the chances of accepting invalid inputs by making 62 // sure that a trace entry can actually be created from the decoded proto. 63 // If the trace entry creation fails, an exception is thrown and the parser 64 // will be considered unsuited for this input data. 65 this.processDecodedEntry(0, entryProto); 66 67 return [entryProto]; 68 } 69 70 protected override getTimestamp( 71 entryProto: com.android.server.wm.IWindowManagerServiceDumpProto, 72 ): Timestamp { 73 return this.timestampConverter.makeZeroTimestamp(); 74 } 75 76 override processDecodedEntry( 77 index: number, 78 entryProto: com.android.server.wm.IWindowManagerServiceDumpProto, 79 ): HierarchyTreeNode { 80 return this.makeHierarchyTree(entryProto); 81 } 82 83 private makeHierarchyTree( 84 entryProto: com.android.server.wm.IWindowManagerServiceDumpProto, 85 ): HierarchyTreeNode { 86 const containers: PropertiesProvider[] = ParserWmUtils.extractContainers( 87 assertDefined(entryProto), 88 ); 89 90 const entry = ParserWmUtils.makeEntryProperties(entryProto); 91 92 return new HierarchyTreeBuilderWm() 93 .setRoot(entry) 94 .setChildren(containers) 95 .setComputations([new RectsComputation()]) 96 .build(); 97 } 98 99 override customQuery<Q extends CustomQueryType>( 100 type: Q, 101 entriesRange: EntriesRange, 102 ): Promise<CustomQueryParserResultTypeMap[Q]> { 103 return new VisitableParserCustomQuery(type) 104 .visit(CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE, () => { 105 const result: CustomQueryParserResultTypeMap[CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE] = 106 []; 107 this.decodedEntries 108 .slice(entriesRange.start, entriesRange.end) 109 .forEach((windowManagerServiceDumpProto) => { 110 WmCustomQueryUtils.parseWindowsTokenAndTitle( 111 windowManagerServiceDumpProto?.rootWindowContainer, 112 result, 113 ); 114 }); 115 return Promise.resolve(result); 116 }) 117 .getResult(); 118 } 119} 120 121export {ParserWindowManagerDump}; 122