blob: 5620b4c67ffa7435f960fd416f1ae7a0405f397a [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {FunctionUtils, OnProgressUpdateType} from 'common/function_utils';
import {ParserError, ParserFactory} from 'parsers/parser_factory';
import {FrameMapper} from 'trace/frame_mapper';
import {Parser} from 'trace/parser';
import {TimestampType} from 'trace/timestamp';
import {Trace} from 'trace/trace';
import {Traces} from 'trace/traces';
import {LoadedTraceFile, TraceFile} from 'trace/trace_file';
import {TraceType} from 'trace/trace_type';
class TracePipeline {
private parserFactory = new ParserFactory();
private parsers: Array<Parser<object>> = [];
private traces?: Traces;
private commonTimestampType?: TimestampType;
async loadTraceFiles(
traceFiles: TraceFile[],
onLoadProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
): Promise<ParserError[]> {
const [parsers, parserErrors] = await this.parserFactory.createParsers(
traceFiles,
onLoadProgressUpdate
);
this.parsers = parsers;
return parserErrors;
}
removeTraceFile(type: TraceType) {
this.parsers = this.parsers.filter((parser) => parser.getTraceType() !== type);
}
getLoadedTraceFiles(): LoadedTraceFile[] {
return this.parsers.map(
(parser: Parser<object>) => new LoadedTraceFile(parser.getTraceFile(), parser.getTraceType())
);
}
buildTraces() {
const commonTimestampType = this.getCommonTimestampType();
this.traces = new Traces();
this.parsers.forEach((parser) => {
const trace = new Trace(
parser.getTraceType(),
parser.getTraceFile(),
undefined,
parser,
commonTimestampType,
{start: 0, end: parser.getLengthEntries()}
);
this.traces?.setTrace(parser.getTraceType(), trace);
});
new FrameMapper(this.traces).computeMapping();
}
getTraces(): Traces {
this.checkTracesWereBuilt();
return this.traces!;
}
getScreenRecordingVideo(): undefined | Blob {
const screenRecording = this.getTraces().getTrace(TraceType.SCREEN_RECORDING);
if (!screenRecording || screenRecording.lengthEntries === 0) {
return undefined;
}
return screenRecording.getEntry(0).getValue().videoData;
}
clear() {
this.parserFactory = new ParserFactory();
this.parsers = [];
this.traces = undefined;
this.commonTimestampType = undefined;
}
private getCommonTimestampType(): TimestampType {
if (this.commonTimestampType !== undefined) {
return this.commonTimestampType;
}
const priorityOrder = [TimestampType.REAL, TimestampType.ELAPSED];
for (const type of priorityOrder) {
if (this.parsers.every((it) => it.getTimestamps(type) !== undefined)) {
this.commonTimestampType = type;
return this.commonTimestampType;
}
}
throw Error('Failed to find common timestamp type across all traces');
}
private checkTracesWereBuilt() {
if (!this.traces) {
throw new Error(
`Can't access traces before building them. Did you forget to call '${this.buildTraces.name}'?`
);
}
}
}
export {TracePipeline};