1/* 2 * Copyright 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 {assertDefined} from 'common/assert_utils'; 18import {Cuj, EventLog, Transition} from 'trace/flickerlib/common'; 19import {Parser} from 'trace/parser'; 20import {Timestamp, TimestampType} from 'trace/timestamp'; 21import {TraceType} from 'trace/trace_type'; 22import {AbstractTracesParser} from './abstract_traces_parser'; 23import {ParserEventLog} from './parser_eventlog'; 24 25export class TracesParserCujs extends AbstractTracesParser<Transition> { 26 private readonly eventLogTrace: ParserEventLog | undefined; 27 private readonly descriptors: string[]; 28 private decodedEntries: Cuj[] | undefined; 29 30 constructor(parsers: Array<Parser<object>>) { 31 super(); 32 33 const eventlogTraces = parsers.filter((it) => it.getTraceType() === TraceType.EVENT_LOG); 34 if (eventlogTraces.length > 0) { 35 this.eventLogTrace = eventlogTraces[0] as ParserEventLog; 36 } 37 38 if (this.eventLogTrace !== undefined) { 39 this.descriptors = this.eventLogTrace.getDescriptors(); 40 } else { 41 this.descriptors = []; 42 } 43 } 44 45 override async parse() { 46 if (this.eventLogTrace === undefined) { 47 throw new Error('eventLogTrace not defined'); 48 } 49 50 const events: Event[] = []; 51 52 for (let i = 0; i < this.eventLogTrace.getLengthEntries(); i++) { 53 events.push(await this.eventLogTrace.getEntry(i, TimestampType.REAL)); 54 } 55 56 this.decodedEntries = new EventLog(events).cujTrace.entries; 57 58 await this.parseTimestamps(); 59 } 60 61 getLengthEntries(): number { 62 return assertDefined(this.decodedEntries).length; 63 } 64 65 getEntry(index: number, timestampType: TimestampType): Promise<Transition> { 66 const entry = assertDefined(this.decodedEntries)[index]; 67 return Promise.resolve(entry); 68 } 69 70 override getDescriptors(): string[] { 71 return this.descriptors; 72 } 73 74 getTraceType(): TraceType { 75 return TraceType.CUJS; 76 } 77 78 override getTimestamp(type: TimestampType, transition: Transition): undefined | Timestamp { 79 if (type === TimestampType.ELAPSED) { 80 return new Timestamp(type, BigInt(transition.timestamp.elapsedNanos.toString())); 81 } else if (type === TimestampType.REAL) { 82 return new Timestamp(type, BigInt(transition.timestamp.unixNanos.toString())); 83 } 84 return undefined; 85 } 86} 87