xref: /aosp_15_r20/development/tools/winscope/src/parsers/window_manager/legacy/parser_window_manager.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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 {TamperedMessageType} from 'parsers/tampered_message_type';
21import {RectsComputation} from 'parsers/window_manager/computations/rects_computation';
22import {WmCustomQueryUtils} from 'parsers/window_manager/custom_query_utils';
23import {HierarchyTreeBuilderWm} from 'parsers/window_manager/hierarchy_tree_builder_wm';
24import {PropertiesProviderFactory} from 'parsers/window_manager/properties_provider_factory';
25import root from 'protos/windowmanager/udc/json';
26import {com} from 'protos/windowmanager/udc/static';
27import {
28  CustomQueryParserResultTypeMap,
29  CustomQueryType,
30  VisitableParserCustomQuery,
31} from 'trace/custom_query';
32import {EntriesRange} from 'trace/trace';
33import {TraceType} from 'trace/trace_type';
34import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node';
35import {PropertiesProvider} from 'trace/tree_node/properties_provider';
36import {TAMPERED_PROTOS_UDC} from './tampered_protos_udc';
37
38export class ParserWindowManager extends AbstractParser<HierarchyTreeNode> {
39  private static readonly MAGIC_NUMBER = [
40    0x09, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
41  ]; // .WINTRACE
42  private static readonly WindowManagerTraceFileProto =
43    TamperedMessageType.tamper(
44      root.lookupType('com.android.server.wm.WindowManagerTraceFileProto'),
45    );
46
47  private readonly factory = new PropertiesProviderFactory(TAMPERED_PROTOS_UDC);
48  private realToBootTimeOffsetNs: bigint | undefined;
49
50  override getTraceType(): TraceType {
51    return TraceType.WINDOW_MANAGER;
52  }
53
54  override getMagicNumber(): number[] {
55    return ParserWindowManager.MAGIC_NUMBER;
56  }
57
58  override getRealToBootTimeOffsetNs(): bigint | undefined {
59    return this.realToBootTimeOffsetNs;
60  }
61
62  override getRealToMonotonicTimeOffsetNs(): bigint | undefined {
63    return undefined;
64  }
65
66  override decodeTrace(
67    buffer: Uint8Array,
68  ): com.android.server.wm.IWindowManagerTraceProto[] {
69    const decoded = ParserWindowManager.WindowManagerTraceFileProto.decode(
70      buffer,
71    ) as com.android.server.wm.IWindowManagerTraceFileProto;
72    const timeOffset = BigInt(
73      decoded.realToElapsedTimeOffsetNanos?.toString() ?? '0',
74    );
75    this.realToBootTimeOffsetNs = timeOffset !== 0n ? timeOffset : undefined;
76    return decoded.entry ?? [];
77  }
78
79  protected override getTimestamp(
80    entry: com.android.server.wm.IWindowManagerTraceProto,
81  ): Timestamp {
82    return this.timestampConverter.makeTimestampFromBootTimeNs(
83      BigInt(assertDefined(entry.elapsedRealtimeNanos).toString()),
84    );
85  }
86
87  override processDecodedEntry(
88    index: number,
89    entry: com.android.server.wm.IWindowManagerTraceProto,
90  ): HierarchyTreeNode {
91    return this.makeHierarchyTree(entry);
92  }
93
94  override customQuery<Q extends CustomQueryType>(
95    type: Q,
96    entriesRange: EntriesRange,
97  ): Promise<CustomQueryParserResultTypeMap[Q]> {
98    return new VisitableParserCustomQuery(type)
99      .visit(CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE, () => {
100        const result: CustomQueryParserResultTypeMap[CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE] =
101          [];
102        this.decodedEntries
103          .slice(entriesRange.start, entriesRange.end)
104          .forEach((windowManagerTraceProto) => {
105            WmCustomQueryUtils.parseWindowsTokenAndTitle(
106              windowManagerTraceProto?.windowManagerService
107                ?.rootWindowContainer,
108              result,
109            );
110          });
111        return Promise.resolve(result);
112      })
113      .getResult();
114  }
115
116  private makeHierarchyTree(
117    entryProto: com.android.server.wm.IWindowManagerTraceProto,
118  ): HierarchyTreeNode {
119    const containers: PropertiesProvider[] =
120      this.factory.makeContainerProperties(
121        assertDefined(entryProto.windowManagerService),
122      );
123
124    const entry = this.factory.makeEntryProperties(
125      assertDefined(entryProto.windowManagerService),
126    );
127
128    return new HierarchyTreeBuilderWm()
129      .setRoot(entry)
130      .setChildren(containers)
131      .setComputations([new RectsComputation()])
132      .build();
133  }
134}
135