xref: /aosp_15_r20/development/tools/winscope/src/test/unit/trace_builder.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 {Timestamp} from 'common/time';
18import {
19  CustomQueryParserResultTypeMap,
20  CustomQueryType,
21} from 'trace/custom_query';
22import {FrameMap} from 'trace/frame_map';
23import {FrameMapBuilder} from 'trace/frame_map_builder';
24import {
25  AbsoluteEntryIndex,
26  AbsoluteFrameIndex,
27  EntriesRange,
28} from 'trace/index_types';
29import {Parser} from 'trace/parser';
30import {Trace} from 'trace/trace';
31import {TraceType} from 'trace/trace_type';
32import {ParserBuilder} from './parser_builder';
33
34export class TraceBuilder<T> {
35  private type = TraceType.SURFACE_FLINGER;
36  private parser?: Parser<T>;
37  private parserCustomQueryResult = new Map<CustomQueryType, {}>();
38  private entries?: T[];
39  private timestamps?: Timestamp[];
40  private frameMap?: FrameMap;
41  private frameMapBuilder?: FrameMapBuilder;
42  private descriptors: string[] = [];
43  private isCorrupted = false;
44
45  setType(type: TraceType): TraceBuilder<T> {
46    this.type = type;
47    return this;
48  }
49
50  setParser(parser: Parser<T>): TraceBuilder<T> {
51    this.parser = parser;
52    return this;
53  }
54
55  setEntries(entries: T[]): TraceBuilder<T> {
56    this.entries = entries;
57    return this;
58  }
59
60  setTimestamps(timestamps: Timestamp[]): TraceBuilder<T> {
61    this.timestamps = timestamps;
62    return this;
63  }
64
65  setFrameMap(frameMap?: FrameMap): TraceBuilder<T> {
66    this.frameMap = frameMap;
67    return this;
68  }
69
70  setFrame(entry: AbsoluteEntryIndex, frame: AbsoluteFrameIndex) {
71    if (!this.entries) {
72      throw new Error(`Can't set frames before specifying the entries`);
73    }
74    if (!this.frameMapBuilder) {
75      this.frameMapBuilder = new FrameMapBuilder(this.entries.length, 1000);
76    }
77    this.frameMapBuilder.setFrames(entry, {start: frame, end: frame + 1});
78    return this;
79  }
80
81  setParserCustomQueryResult<Q extends CustomQueryType>(
82    type: Q,
83    result: CustomQueryParserResultTypeMap[Q],
84  ): TraceBuilder<T> {
85    this.parserCustomQueryResult.set(type, result ?? {});
86    return this;
87  }
88
89  setDescriptors(descriptors: string[]): TraceBuilder<T> {
90    this.descriptors = descriptors;
91    return this;
92  }
93
94  setIsCorrupted(value: boolean): TraceBuilder<T> {
95    this.isCorrupted = value;
96    return this;
97  }
98
99  build(): Trace<T> {
100    if (!this.parser) {
101      this.parser = this.createParser();
102    }
103
104    const entriesRange: EntriesRange = {
105      start: 0,
106      end: this.parser.getLengthEntries(),
107    };
108    const trace = new Trace<T>(
109      this.type,
110      this.parser,
111      this.descriptors,
112      undefined,
113      entriesRange,
114    );
115
116    const frameMap = this.getFrameMap();
117    if (frameMap) {
118      trace.setFrameInfo(frameMap, frameMap.getFullTraceFramesRange());
119    }
120
121    return trace;
122  }
123
124  private createParser(): Parser<T> {
125    const builder = new ParserBuilder<T>()
126      .setType(this.type)
127      .setIsCorrupted(this.isCorrupted);
128
129    if (this.timestamps) {
130      builder.setTimestamps(this.timestamps);
131    }
132
133    if (this.entries) {
134      builder.setEntries(this.entries);
135    }
136
137    if (this.descriptors.length > 0) {
138      builder.setDescriptors(this.descriptors);
139    }
140
141    this.parserCustomQueryResult?.forEach((result, queryType) => {
142      builder.setCustomQueryResult(queryType, result as any);
143    });
144
145    return builder.build();
146  }
147
148  private getFrameMap(): FrameMap | undefined {
149    if (this.frameMap && this.frameMapBuilder) {
150      throw new Error(
151        `Cannot set a full frame map as well as individual entry's frames. Pick one of the two options.`,
152      );
153    }
154    if (this.frameMap) {
155      return this.frameMap;
156    }
157    if (this.frameMapBuilder) {
158      return this.frameMapBuilder.build();
159    }
160    return undefined;
161  }
162}
163