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