• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17import {Timestamp} from 'common/time/time';
18import {AbstractParser} from 'parsers/legacy/abstract_parser';
19import {EntryPropertiesTreeFactory} from 'parsers/transitions/entry_properties_tree_factory';
20import root from 'protos/transitions/udc/json';
21import {com} from 'protos/transitions/udc/static';
22import {TraceType} from 'trace/trace_type';
23import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
24
25type TransitionProto = com.android.server.wm.shell.ITransition;
26
27export class ParserTransitionsWm extends AbstractParser<
28  PropertyTreeNode,
29  TransitionProto
30> {
31  private static readonly TransitionTraceProto = root.lookupType(
32    'com.android.server.wm.shell.TransitionTraceProto',
33  );
34
35  private realToBootTimeOffsetNs: bigint | undefined;
36
37  override getTraceType(): TraceType {
38    return TraceType.WM_TRANSITION;
39  }
40
41  override getRealToBootTimeOffsetNs(): bigint | undefined {
42    return this.realToBootTimeOffsetNs;
43  }
44
45  override getRealToMonotonicTimeOffsetNs(): bigint | undefined {
46    return undefined;
47  }
48
49  override processDecodedEntry(
50    index: number,
51    entryProto: TransitionProto,
52  ): PropertyTreeNode {
53    return this.makePropertiesTree(entryProto);
54  }
55
56  override decodeTrace(buffer: Uint8Array): TransitionProto[] {
57    const decodedProto = ParserTransitionsWm.TransitionTraceProto.decode(
58      buffer,
59    ) as unknown as com.android.server.wm.shell.ITransitionTraceProto;
60
61    const timeOffset = BigInt(
62      decodedProto.realToElapsedTimeOffsetNanos?.toString() ?? '0',
63    );
64    this.realToBootTimeOffsetNs = timeOffset !== 0n ? timeOffset : undefined;
65
66    return decodedProto.transitions ?? [];
67  }
68
69  override getMagicNumber(): number[] | undefined {
70    return [0x09, 0x54, 0x52, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45]; // .TRNTRACE
71  }
72
73  protected override getTimestamp(entry: TransitionProto): Timestamp {
74    // for consistency with all transitions, elapsed nanos are defined as
75    // shell dispatch time else INVALID_TIME_NS
76    return this.timestampConverter.makeZeroTimestamp();
77  }
78
79  private validateWmTransitionEntry(entry: TransitionProto) {
80    if (entry.id === 0) {
81      throw new Error('WM Transition entry needs non-null id');
82    }
83    if (
84      !entry.createTimeNs &&
85      !entry.sendTimeNs &&
86      !entry.abortTimeNs &&
87      !entry.finishTimeNs
88    ) {
89      throw new Error(
90        'WM Transition entry requires at least one non-null timestamp',
91      );
92    }
93    if (this.realToBootTimeOffsetNs === undefined) {
94      throw new Error('WM Transition trace missing realToBootTimeOffsetNs');
95    }
96  }
97
98  private makePropertiesTree(entryProto: TransitionProto): PropertyTreeNode {
99    this.validateWmTransitionEntry(entryProto);
100
101    const shellEntryTree = EntryPropertiesTreeFactory.makeShellPropertiesTree();
102    const wmEntryTree = EntryPropertiesTreeFactory.makeWmPropertiesTree({
103      entry: entryProto,
104      realToBootTimeOffsetNs: this.realToBootTimeOffsetNs,
105      timestampConverter: this.timestampConverter,
106    });
107
108    return EntryPropertiesTreeFactory.makeTransitionPropertiesTree(
109      shellEntryTree,
110      wmEntryTree,
111    );
112  }
113}
114