Support multiple files for a single trace
Bug: 277181336 Test: npm run build:all && npm run test:all Change-Id: I7eb981367191c47d3b50b31ee66f147ff1d69431
This commit is contained in:
@@ -331,24 +331,23 @@ export class AppComponent implements TraceDataListener {
|
||||
private makeActiveTraceFileInfo(view: View): string {
|
||||
const traceFile = this.tracePipeline
|
||||
.getLoadedTraceFiles()
|
||||
.find((file) => file.type === view.dependencies[0])?.traceFile;
|
||||
.find((file) => file.type === view.dependencies[0]);
|
||||
|
||||
if (!traceFile) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!traceFile.parentArchive) {
|
||||
return traceFile.file.name;
|
||||
}
|
||||
|
||||
return `${traceFile.parentArchive.name} - ${traceFile.file.name}`;
|
||||
return `${traceFile.type} (${traceFile.descriptors.join(', ')})`;
|
||||
}
|
||||
|
||||
private async makeTraceFilesForDownload(): Promise<File[]> {
|
||||
return this.tracePipeline.getLoadedTraceFiles().map((trace) => {
|
||||
const traceType = TRACE_INFO[trace.type].name;
|
||||
const newName = traceType + '/' + FileUtils.removeDirFromFileName(trace.traceFile.file.name);
|
||||
return new File([trace.traceFile.file], newName);
|
||||
const loadedFiles = this.tracePipeline.getLoadedFiles();
|
||||
return [...loadedFiles.keys()].map((traceType) => {
|
||||
const file = loadedFiles.get(traceType)!;
|
||||
const path = TRACE_INFO[traceType].downloadArchiveDir;
|
||||
|
||||
const newName = path + '/' + FileUtils.removeDirFromFileName(file.file.name);
|
||||
return new File([file.file], newName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export class SnackBarOpener implements UserNotificationListener {
|
||||
}
|
||||
|
||||
private convertErrorToMessage(error: ParserError): string {
|
||||
const fileName = error.trace !== undefined ? error.trace.name : '<no file name>';
|
||||
const fileName = error.trace !== undefined ? error.trace : '<no file name>';
|
||||
const traceTypeName =
|
||||
error.traceType !== undefined ? TRACE_INFO[error.traceType].name : '<unknown>';
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
import {TRACE_INFO} from 'app/trace_info';
|
||||
import {TracePipeline} from 'app/trace_pipeline';
|
||||
import {ProgressListener} from 'interfaces/progress_listener';
|
||||
import {LoadedTraceFile} from 'trace/trace_file';
|
||||
import {LoadedTrace} from 'trace/loaded_trace';
|
||||
import {LoadProgressComponent} from './load_progress_component';
|
||||
|
||||
@Component({
|
||||
@@ -63,7 +63,8 @@ import {LoadProgressComponent} from './load_progress_component';
|
||||
{{ TRACE_INFO[trace.type].icon }}
|
||||
</mat-icon>
|
||||
|
||||
<p matLine>{{ trace.traceFile.file.name }} ({{ TRACE_INFO[trace.type].name }})</p>
|
||||
<p matLine>{{ TRACE_INFO[trace.type].name }}</p>
|
||||
<p matLine *ngFor="let descriptor of trace.descriptors">{{ descriptor }}</p>
|
||||
|
||||
<button color="primary" mat-icon-button (click)="onRemoveTrace($event, trace)">
|
||||
<mat-icon>close</mat-icon>
|
||||
@@ -235,7 +236,7 @@ export class UploadTracesComponent implements ProgressListener {
|
||||
this.filesUploaded.emit(Array.from(droppedFiles));
|
||||
}
|
||||
|
||||
onRemoveTrace(event: MouseEvent, trace: LoadedTraceFile) {
|
||||
onRemoveTrace(event: MouseEvent, trace: LoadedTrace) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.tracePipeline.removeTraceFile(trace.type);
|
||||
|
||||
@@ -36,6 +36,7 @@ interface TraceInfoMap {
|
||||
name: string;
|
||||
icon: string;
|
||||
color: string;
|
||||
downloadArchiveDir: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,95 +45,114 @@ export const TRACE_INFO: TraceInfoMap = {
|
||||
name: 'Accessibility',
|
||||
icon: ACCESSIBILITY_ICON,
|
||||
color: '#FF63B8',
|
||||
downloadArchiveDir: 'accessibility',
|
||||
},
|
||||
[TraceType.WINDOW_MANAGER]: {
|
||||
name: 'Window Manager',
|
||||
icon: WINDOW_MANAGER_ICON,
|
||||
color: '#AF5CF7',
|
||||
downloadArchiveDir: 'wm',
|
||||
},
|
||||
[TraceType.SURFACE_FLINGER]: {
|
||||
name: 'Surface Flinger',
|
||||
icon: SURFACE_FLINGER_ICON,
|
||||
color: '#4ECDE6',
|
||||
downloadArchiveDir: 'sf',
|
||||
},
|
||||
[TraceType.SCREEN_RECORDING]: {
|
||||
name: 'Screen Recording',
|
||||
icon: SCREEN_RECORDING_ICON,
|
||||
color: '#8A9CF9',
|
||||
downloadArchiveDir: '',
|
||||
},
|
||||
[TraceType.TRANSACTIONS]: {
|
||||
name: 'Transactions',
|
||||
icon: TRANSACTION_ICON,
|
||||
color: '#5BB974',
|
||||
downloadArchiveDir: 'sf',
|
||||
},
|
||||
[TraceType.TRANSACTIONS_LEGACY]: {
|
||||
name: 'Transactions Legacy',
|
||||
icon: TRANSACTION_ICON,
|
||||
color: '#5BB974',
|
||||
downloadArchiveDir: 'sf',
|
||||
},
|
||||
[TraceType.WAYLAND]: {
|
||||
name: 'Wayland',
|
||||
icon: WAYLAND_ICON,
|
||||
color: '#FDC274',
|
||||
downloadArchiveDir: 'wayland',
|
||||
},
|
||||
[TraceType.WAYLAND_DUMP]: {
|
||||
name: 'Wayland Dump',
|
||||
icon: WAYLAND_ICON,
|
||||
color: '#D01884',
|
||||
downloadArchiveDir: 'wayland',
|
||||
},
|
||||
[TraceType.PROTO_LOG]: {
|
||||
name: 'ProtoLog',
|
||||
icon: PROTO_LOG_ICON,
|
||||
color: '#40A58A',
|
||||
downloadArchiveDir: 'protolog',
|
||||
},
|
||||
[TraceType.SYSTEM_UI]: {
|
||||
name: 'System UI',
|
||||
icon: SYSTEM_UI_ICON,
|
||||
color: '#7A86FF',
|
||||
downloadArchiveDir: 'sysui',
|
||||
},
|
||||
[TraceType.LAUNCHER]: {
|
||||
name: 'Launcher',
|
||||
icon: LAUNCHER_ICON,
|
||||
color: '#137333',
|
||||
downloadArchiveDir: 'launcher',
|
||||
},
|
||||
[TraceType.INPUT_METHOD_CLIENTS]: {
|
||||
name: 'IME Clients',
|
||||
icon: IME_ICON,
|
||||
color: '#FA903E',
|
||||
downloadArchiveDir: 'ime',
|
||||
},
|
||||
[TraceType.INPUT_METHOD_SERVICE]: {
|
||||
name: 'IME Service',
|
||||
icon: IME_ICON,
|
||||
color: '#F29900',
|
||||
downloadArchiveDir: 'ime',
|
||||
},
|
||||
[TraceType.INPUT_METHOD_MANAGER_SERVICE]: {
|
||||
name: 'IME Manager Service',
|
||||
icon: IME_ICON,
|
||||
color: '#D93025',
|
||||
downloadArchiveDir: 'ime',
|
||||
},
|
||||
[TraceType.TAG]: {
|
||||
name: 'Tag',
|
||||
icon: TAG_ICON,
|
||||
color: '#4575B4',
|
||||
downloadArchiveDir: '',
|
||||
},
|
||||
[TraceType.ERROR]: {
|
||||
name: 'Error',
|
||||
icon: TRACE_ERROR_ICON,
|
||||
color: '#D73027',
|
||||
downloadArchiveDir: '',
|
||||
},
|
||||
[TraceType.EVENT_LOG]: {
|
||||
name: 'Event Log',
|
||||
icon: EVENT_LOG_ICON,
|
||||
color: '#fdd663',
|
||||
downloadArchiveDir: 'eventlog',
|
||||
},
|
||||
[TraceType.WM_TRANSITION]: {
|
||||
name: 'WM Transitions',
|
||||
icon: TRANSITION_ICON,
|
||||
color: '#EC407A',
|
||||
downloadArchiveDir: 'transition',
|
||||
},
|
||||
[TraceType.SHELL_TRANSITION]: {
|
||||
name: 'Shell Transitions',
|
||||
icon: TRANSITION_ICON,
|
||||
color: '#EC407A',
|
||||
downloadArchiveDir: 'transition',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -17,16 +17,18 @@
|
||||
import {FunctionUtils, OnProgressUpdateType} from 'common/function_utils';
|
||||
import {ParserError, ParserFactory} from 'parsers/parser_factory';
|
||||
import {FrameMapper} from 'trace/frame_mapper';
|
||||
import {LoadedTrace} from 'trace/loaded_trace';
|
||||
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 {TraceFile} from 'trace/trace_file';
|
||||
import {TraceType} from 'trace/trace_type';
|
||||
|
||||
class TracePipeline {
|
||||
private parserFactory = new ParserFactory();
|
||||
private parsers: Array<Parser<object>> = [];
|
||||
private files = new Map<TraceType, TraceFile>();
|
||||
private traces?: Traces;
|
||||
private commonTimestampType?: TimestampType;
|
||||
|
||||
@@ -38,7 +40,12 @@ class TracePipeline {
|
||||
traceFiles,
|
||||
onLoadProgressUpdate
|
||||
);
|
||||
this.parsers = parsers;
|
||||
this.parsers = parsers.map((it) => it.parser);
|
||||
|
||||
for (const parser of parsers) {
|
||||
this.files.set(parser.parser.getTraceType(), parser.file);
|
||||
}
|
||||
|
||||
return parserErrors;
|
||||
}
|
||||
|
||||
@@ -46,9 +53,13 @@ class TracePipeline {
|
||||
this.parsers = this.parsers.filter((parser) => parser.getTraceType() !== type);
|
||||
}
|
||||
|
||||
getLoadedTraceFiles(): LoadedTraceFile[] {
|
||||
getLoadedFiles(): Map<TraceType, TraceFile> {
|
||||
return this.files;
|
||||
}
|
||||
|
||||
getLoadedTraceFiles(): LoadedTrace[] {
|
||||
return this.parsers.map(
|
||||
(parser: Parser<object>) => new LoadedTraceFile(parser.getTraceFile(), parser.getTraceType())
|
||||
(parser: Parser<object>) => new LoadedTrace(parser.getDescriptors(), parser.getTraceType())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -57,14 +68,7 @@ class TracePipeline {
|
||||
|
||||
this.traces = new Traces();
|
||||
this.parsers.forEach((parser) => {
|
||||
const trace = new Trace(
|
||||
parser.getTraceType(),
|
||||
parser.getTraceFile(),
|
||||
undefined,
|
||||
parser,
|
||||
commonTimestampType,
|
||||
{start: 0, end: parser.getLengthEntries()}
|
||||
);
|
||||
const trace = Trace.newUninitializedTrace(parser);
|
||||
this.traces?.setTrace(parser.getTraceType(), trace);
|
||||
});
|
||||
new FrameMapper(this.traces).computeMapping();
|
||||
@@ -88,6 +92,7 @@ class TracePipeline {
|
||||
this.parsers = [];
|
||||
this.traces = undefined;
|
||||
this.commonTimestampType = undefined;
|
||||
this.files.clear();
|
||||
}
|
||||
|
||||
private getCommonTimestampType(): TimestampType {
|
||||
|
||||
@@ -93,7 +93,8 @@ describe('TracePipeline', () => {
|
||||
|
||||
const files = tracePipeline.getLoadedTraceFiles();
|
||||
expect(files.length).toEqual(2);
|
||||
expect(files[0].traceFile).toBeTruthy();
|
||||
expect(files[0].descriptors).toBeTruthy();
|
||||
expect(files[0].descriptors.length).toBeGreaterThan(0);
|
||||
|
||||
const actualTraceTypes = new Set(files.map((file) => file.type));
|
||||
const expectedTraceTypes = new Set([TraceType.SURFACE_FLINGER, TraceType.WINDOW_MANAGER]);
|
||||
|
||||
@@ -42,7 +42,7 @@ abstract class AbstractParser implements Parser<object> {
|
||||
throw TypeError("buffer doesn't contain expected magic number");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.decodedEntries = this.decodeTrace(traceBuffer).map((it) => this.addDefaultProtoFields(it));
|
||||
|
||||
for (const type of [TimestampType.ELAPSED, TimestampType.REAL]) {
|
||||
@@ -66,8 +66,8 @@ abstract class AbstractParser implements Parser<object> {
|
||||
|
||||
abstract getTraceType(): TraceType;
|
||||
|
||||
getTraceFile(): TraceFile {
|
||||
return this.traceFile;
|
||||
getDescriptors(): string[] {
|
||||
return [this.traceFile.getDescriptor()];
|
||||
}
|
||||
|
||||
getLengthEntries(): number {
|
||||
|
||||
@@ -56,9 +56,11 @@ export class ParserFactory {
|
||||
async createParsers(
|
||||
traceFiles: TraceFile[],
|
||||
onProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
|
||||
): Promise<[Array<Parser<object>>, ParserError[]]> {
|
||||
): Promise<[Array<{file: TraceFile; parser: Parser<object>}>, ParserError[]]> {
|
||||
const errors: ParserError[] = [];
|
||||
|
||||
const parsers = new Array<{file: TraceFile; parser: Parser<object>}>();
|
||||
|
||||
if (traceFiles.length === 0) {
|
||||
errors.push(new ParserError(ParserErrorType.NO_INPUT_FILES));
|
||||
}
|
||||
@@ -73,6 +75,7 @@ export class ParserFactory {
|
||||
hasFoundParser = true;
|
||||
if (this.shouldUseParser(parser, errors)) {
|
||||
this.parsers.set(parser.getTraceType(), parser);
|
||||
parsers.push({file: traceFile, parser});
|
||||
}
|
||||
break;
|
||||
} catch (error) {
|
||||
@@ -82,37 +85,37 @@ export class ParserFactory {
|
||||
|
||||
if (!hasFoundParser) {
|
||||
console.log(`Failed to load trace ${traceFile.file.name}`);
|
||||
errors.push(new ParserError(ParserErrorType.UNSUPPORTED_FORMAT, traceFile.file));
|
||||
errors.push(new ParserError(ParserErrorType.UNSUPPORTED_FORMAT, traceFile.getDescriptor()));
|
||||
}
|
||||
|
||||
onProgressUpdate((100 * (index + 1)) / traceFiles.length);
|
||||
}
|
||||
|
||||
return [Array.from(this.parsers.values()), errors];
|
||||
return [parsers, errors];
|
||||
}
|
||||
|
||||
private shouldUseParser(newParser: Parser<object>, errors: ParserError[]): boolean {
|
||||
const oldParser = this.parsers.get(newParser.getTraceType());
|
||||
if (!oldParser) {
|
||||
console.log(
|
||||
`Loaded trace ${
|
||||
newParser.getTraceFile().file.name
|
||||
} (trace type: ${newParser.getTraceType()})`
|
||||
`Loaded trace ${newParser
|
||||
.getDescriptors()
|
||||
.join()} (trace type: ${newParser.getTraceType()})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (newParser.getLengthEntries() > oldParser.getLengthEntries()) {
|
||||
console.log(
|
||||
`Loaded trace ${
|
||||
newParser.getTraceFile().file.name
|
||||
} (trace type: ${newParser.getTraceType()}).` +
|
||||
` Replace trace ${oldParser.getTraceFile().file.name}`
|
||||
`Loaded trace ${newParser
|
||||
.getDescriptors()
|
||||
.join()} (trace type: ${newParser.getTraceType()}).` +
|
||||
` Replace trace ${oldParser.getDescriptors().join()}`
|
||||
);
|
||||
errors.push(
|
||||
new ParserError(
|
||||
ParserErrorType.OVERRIDE,
|
||||
oldParser.getTraceFile().file,
|
||||
oldParser.getDescriptors().join(),
|
||||
oldParser.getTraceType()
|
||||
)
|
||||
);
|
||||
@@ -120,15 +123,15 @@ export class ParserFactory {
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Skipping trace ${
|
||||
newParser.getTraceFile().file.name
|
||||
} (trace type: ${newParser.getTraceType()}).` +
|
||||
` Keep trace ${oldParser.getTraceFile().file.name}`
|
||||
`Skipping trace ${newParser
|
||||
.getDescriptors()
|
||||
.join()} (trace type: ${newParser.getTraceType()}).` +
|
||||
` Keep trace ${oldParser.getDescriptors().join()}`
|
||||
);
|
||||
errors.push(
|
||||
new ParserError(
|
||||
ParserErrorType.OVERRIDE,
|
||||
newParser.getTraceFile().file,
|
||||
newParser.getDescriptors().join(),
|
||||
newParser.getTraceType()
|
||||
)
|
||||
);
|
||||
@@ -145,7 +148,7 @@ export enum ParserErrorType {
|
||||
export class ParserError {
|
||||
constructor(
|
||||
public type: ParserErrorType,
|
||||
public trace: File | undefined = undefined,
|
||||
public trace: string | undefined = undefined,
|
||||
public traceType: TraceType | undefined = undefined
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export class TraceBuilder<T> {
|
||||
private timestampType = TimestampType.REAL;
|
||||
private frameMap?: FrameMap;
|
||||
private frameMapBuilder?: FrameMapBuilder;
|
||||
private descriptors: string[] = [];
|
||||
|
||||
setType(type: TraceType): TraceBuilder<T> {
|
||||
this.type = type;
|
||||
@@ -73,6 +74,11 @@ export class TraceBuilder<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
setDescriptors(descriptors: string[]): TraceBuilder<T> {
|
||||
this.descriptors = descriptors;
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): Trace<T> {
|
||||
if (!this.parser) {
|
||||
this.parser = this.createParser();
|
||||
@@ -82,11 +88,10 @@ export class TraceBuilder<T> {
|
||||
start: 0,
|
||||
end: this.parser.getLengthEntries(),
|
||||
};
|
||||
const trace = new Trace<T>(
|
||||
const trace = Trace.newInitializedTrace<T>(
|
||||
this.type,
|
||||
undefined,
|
||||
undefined,
|
||||
this.parser,
|
||||
this.descriptors,
|
||||
this.timestampType,
|
||||
entriesRange
|
||||
);
|
||||
|
||||
@@ -19,15 +19,28 @@ import {CommonTestUtils} from 'test/common/utils';
|
||||
import {LayerTraceEntry, WindowManagerState} from 'trace/flickerlib/common';
|
||||
import {Parser} from 'trace/parser';
|
||||
import {TimestampType} from 'trace/timestamp';
|
||||
import {Trace} from 'trace/trace';
|
||||
import {TraceFile} from 'trace/trace_file';
|
||||
import {TraceType} from 'trace/trace_type';
|
||||
|
||||
class UnitTestUtils extends CommonTestUtils {
|
||||
static async getTraceFromFile(filename: string): Promise<Trace<object>> {
|
||||
const parser = await UnitTestUtils.getParser(filename);
|
||||
|
||||
const trace = Trace.newUninitializedTrace(parser);
|
||||
trace.init(
|
||||
parser.getTimestamps(TimestampType.REAL) !== undefined
|
||||
? TimestampType.REAL
|
||||
: TimestampType.ELAPSED
|
||||
);
|
||||
return trace;
|
||||
}
|
||||
|
||||
static async getParser(filename: string): Promise<Parser<object>> {
|
||||
const file = new TraceFile(await CommonTestUtils.getFixtureFile(filename), undefined);
|
||||
const [parsers, errors] = await new ParserFactory().createParsers([file]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
return parsers[0];
|
||||
return parsers[0].parser;
|
||||
}
|
||||
|
||||
static async getWindowManagerState(): Promise<WindowManagerState> {
|
||||
|
||||
21
tools/winscope/src/trace/loaded_trace.ts
Normal file
21
tools/winscope/src/trace/loaded_trace.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 {TraceType} from './trace_type';
|
||||
|
||||
export class LoadedTrace {
|
||||
constructor(public descriptors: string[], public type: TraceType) {}
|
||||
}
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
|
||||
import {Timestamp, TimestampType} from './timestamp';
|
||||
import {TraceFile} from './trace_file';
|
||||
import {TraceType} from './trace_type';
|
||||
|
||||
export interface Parser<T> {
|
||||
getTraceType(): TraceType;
|
||||
getTraceFile(): TraceFile;
|
||||
getLengthEntries(): number;
|
||||
getTimestamps(type: TimestampType): Timestamp[] | undefined;
|
||||
getEntry(index: number, timestampType: TimestampType): T;
|
||||
|
||||
getDescriptors(): string[];
|
||||
}
|
||||
|
||||
@@ -48,4 +48,8 @@ export class ParserMock<T> implements Parser<T> {
|
||||
getEntry(index: number): T {
|
||||
return this.entries[index];
|
||||
}
|
||||
|
||||
getDescriptors(): string[] {
|
||||
return ['MockTrace'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,32 +72,56 @@ export class TraceEntry<T> {
|
||||
}
|
||||
|
||||
export class Trace<T> {
|
||||
readonly type: TraceType;
|
||||
readonly file?: TraceFile;
|
||||
readonly lengthEntries: number;
|
||||
readonly fullTrace: Trace<T>;
|
||||
|
||||
private readonly parser: Parser<T>;
|
||||
private readonly timestampType: TimestampType;
|
||||
private timestampType: TimestampType | undefined;
|
||||
private readonly entriesRange: EntriesRange;
|
||||
private frameMap?: FrameMap;
|
||||
private framesRange?: FramesRange;
|
||||
|
||||
constructor(
|
||||
static newUninitializedTrace<T>(parser: Parser<T>): Trace<T> {
|
||||
return new Trace(
|
||||
parser.getTraceType(),
|
||||
parser,
|
||||
parser.getDescriptors(),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
static newInitializedTrace<T>(
|
||||
type: TraceType,
|
||||
file: TraceFile | undefined,
|
||||
fullTrace: Trace<T> | undefined,
|
||||
parser: Parser<T>,
|
||||
entryProvider: Parser<T>,
|
||||
descriptors: string[],
|
||||
timestampType: TimestampType,
|
||||
entriesRange: EntriesRange
|
||||
) {
|
||||
this.type = type;
|
||||
this.file = file;
|
||||
this.lengthEntries = entriesRange.end - entriesRange.start;
|
||||
this.fullTrace = fullTrace ? fullTrace : this;
|
||||
this.parser = parser;
|
||||
): Trace<T> {
|
||||
return new Trace(type, entryProvider, descriptors, undefined, timestampType, entriesRange);
|
||||
}
|
||||
|
||||
init(timestampType: TimestampType) {
|
||||
this.timestampType = timestampType;
|
||||
this.entriesRange = entriesRange;
|
||||
}
|
||||
|
||||
private constructor(
|
||||
readonly type: TraceType,
|
||||
readonly parser: Parser<T>,
|
||||
readonly descriptors: string[],
|
||||
fullTrace: Trace<T> | undefined,
|
||||
timestampType: TimestampType | undefined,
|
||||
entriesRange: EntriesRange | undefined
|
||||
) {
|
||||
this.fullTrace = fullTrace ?? this;
|
||||
this.entriesRange = entriesRange ?? {start: 0, end: parser.getLengthEntries()};
|
||||
this.lengthEntries = this.entriesRange.end - this.entriesRange.start;
|
||||
this.timestampType = timestampType;
|
||||
}
|
||||
|
||||
getDescriptors(): string[] {
|
||||
return this.parser.getDescriptors();
|
||||
}
|
||||
|
||||
setFrameInfo(frameMap: FrameMap, framesRange: FramesRange | undefined) {
|
||||
@@ -315,6 +339,10 @@ export class Trace<T> {
|
||||
}
|
||||
|
||||
private getFullTraceTimestamps(): Timestamp[] {
|
||||
if (this.timestampType === undefined) {
|
||||
throw new Error('Forgot to initialize trace?');
|
||||
}
|
||||
|
||||
const timestamps = this.parser.getTimestamps(this.timestampType);
|
||||
if (!timestamps) {
|
||||
throw new Error(`Timestamp type ${this.timestampType} is expected to be available`);
|
||||
@@ -350,9 +378,9 @@ export class Trace<T> {
|
||||
|
||||
const slice = new Trace<T>(
|
||||
this.type,
|
||||
this.file,
|
||||
this.fullTrace,
|
||||
this.parser,
|
||||
this.descriptors,
|
||||
this.fullTrace,
|
||||
this.timestampType,
|
||||
entries
|
||||
);
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {TraceType} from './trace_type';
|
||||
|
||||
export class TraceFile {
|
||||
constructor(public file: File, public parentArchive?: File) {}
|
||||
}
|
||||
|
||||
export class LoadedTraceFile {
|
||||
constructor(public traceFile: TraceFile, public type: TraceType) {}
|
||||
getDescriptor(): string {
|
||||
let descriptor = this.file.name;
|
||||
if (this.parentArchive?.name !== undefined) {
|
||||
descriptor += ` (${this.parentArchive?.name})`;
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user