From e081cfee6bffa9bfc7cd373de5e1bfeec34481de Mon Sep 17 00:00:00 2001 From: Kean Mariotti Date: Wed, 27 Jul 2022 05:46:55 +0000 Subject: [PATCH] refactor Parser's interface - add class TimestampType (ELAPSED or REAL) - add class Timestamp (timestamp value + type) - use bigint (instead of number) to represent timestamp values Test: cd development/tools/winscope-ng && npm run build:all && npm run test:all Change-Id: I1db9f2f9d48ca54bd79d3ffb989f6dde9ac11cd7 --- tools/winscope-ng/src/app/app.component.ts | 15 ++--- tools/winscope-ng/src/app/core.ts | 41 +++++++++----- .../src/common/trace/screen_recording.ts | 4 +- .../winscope-ng/src/common/trace/timestamp.ts | 44 +++++++++++++++ .../trace/{type_id.ts => trace_type.ts} | 4 +- tools/winscope-ng/src/parsers/parser.ts | 44 +++++++++++---- .../src/parsers/parser_accessibility.spec.ts | 24 +++++--- .../src/parsers/parser_accessibility.ts | 14 +++-- .../src/parsers/parser_common.spec.ts | 36 +++++++----- .../parser_input_method_clients.spec.ts | 24 +++++--- .../parsers/parser_input_method_clients.ts | 14 +++-- ...arser_input_method_manager_service.spec.ts | 21 ++++--- .../parser_input_method_manager_service.ts | 14 +++-- .../parser_input_method_service.spec.ts | 23 ++++++-- .../parsers/parser_input_method_service.ts | 14 +++-- .../src/parsers/parser_protolog.spec.ts | 20 +++++-- .../src/parsers/parser_protolog.ts | 16 ++++-- .../parsers/parser_screen_recording.spec.ts | 55 ++++++++++++++++--- .../src/parsers/parser_screen_recording.ts | 34 +++++++++--- .../parser_screen_recording_legacy.spec.ts | 34 +++++++++--- .../parsers/parser_screen_recording_legacy.ts | 32 +++++++---- .../parsers/parser_surface_flinger.spec.ts | 21 ++++--- .../src/parsers/parser_surface_flinger.ts | 14 +++-- .../parser_surface_flinger_dump.spec.ts | 17 ++++-- .../src/parsers/parser_transactions.spec.ts | 21 +++++-- .../src/parsers/parser_transactions.ts | 14 +++-- .../src/parsers/parser_window_manager.spec.ts | 19 +++++-- .../src/parsers/parser_window_manager.ts | 14 +++-- .../parser_window_manager_dump.spec.ts | 19 +++++-- .../src/parsers/parser_window_manager_dump.ts | 14 +++-- tools/winscope-ng/src/viewers/viewer.ts | 4 +- .../winscope-ng/src/viewers/viewer_factory.ts | 6 +- .../viewer_window_manager/presenter.ts | 4 +- .../viewer_window_manager.ts | 6 +- 34 files changed, 495 insertions(+), 205 deletions(-) create mode 100644 tools/winscope-ng/src/common/trace/timestamp.ts rename tools/winscope-ng/src/common/trace/{type_id.ts => trace_type.ts} (95%) diff --git a/tools/winscope-ng/src/app/app.component.ts b/tools/winscope-ng/src/app/app.component.ts index b2d586d21..dc6eca0b7 100644 --- a/tools/winscope-ng/src/app/app.component.ts +++ b/tools/winscope-ng/src/app/app.component.ts @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Component, Injector, Inject } from "@angular/core"; -import { createCustomElement } from "@angular/elements"; -import { ViewerWindowManagerComponent } from "viewers/viewer_window_manager/viewer_window_manager.component"; -import { Core } from "./core"; -import { ProxyState } from "trace_collection/proxy_client"; -import { PersistentStore } from "../common/persistent_store"; +import {Component, Inject, Injector} from "@angular/core"; +import {createCustomElement} from "@angular/elements"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {PersistentStore} from "common/persistent_store"; +import {ViewerWindowManagerComponent} from "viewers/viewer_window_manager/viewer_window_manager.component"; +import {Core} from "./core"; +import {ProxyState} from "trace_collection/proxy_client"; @Component({ selector: "app-root", @@ -81,7 +82,7 @@ export class AppComponent { } public notifyCurrentTimestamp() { - const dummyTimestamp = 1000000; //TODO: get timestamp from time scrub + const dummyTimestamp = new Timestamp(TimestampType.ELAPSED, 1000000n); this.core.notifyCurrentTimestamp(dummyTimestamp); } diff --git a/tools/winscope-ng/src/app/core.ts b/tools/winscope-ng/src/app/core.ts index 57d476c61..1f2810395 100644 --- a/tools/winscope-ng/src/app/core.ts +++ b/tools/winscope-ng/src/app/core.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "parsers/parser"; import {ParserFactory} from "parsers/parser_factory"; import { setTraces } from "trace_collection/set_traces"; @@ -35,10 +36,10 @@ class Core { this.parsers = await new ParserFactory().createParsers(traces); console.log("created parsers: ", this.parsers); - const activeTraceTypes = this.parsers.map(parser => parser.getTraceTypeId()); + const activeTraceTypes = this.parsers.map(parser => parser.getTraceType()); console.log("active trace types: ", activeTraceTypes); - this.viewers = new ViewerFactory().createViewers(new Set(activeTraceTypes)); + this.viewers = new ViewerFactory().createViewers(new Set(activeTraceTypes)); console.log("created viewers: ", this.viewers); } @@ -46,27 +47,37 @@ class Core { return this.viewers.map(viewer => viewer.getView()); } - getTimestamps(): number[] { - const mergedTimestamps: number[] = []; + getTimestamps(): Timestamp[] { + for (const type of [TimestampType.REAL, TimestampType.ELAPSED]) { + const mergedTimestamps: Timestamp[] = []; - this.parsers - .map(parser => parser.getTimestamps()) - .forEach(timestamps => { - mergedTimestamps.push(...timestamps); - }); + let isTypeProvidedByAllParsers = true; - const uniqueTimestamps = [... new Set(mergedTimestamps)]; + for(const timestamps of this.parsers.map(parser => parser.getTimestamps(type))) { + if (timestamps === undefined) { + isTypeProvidedByAllParsers = false; + break; + } + mergedTimestamps.push(...timestamps!); + } - return uniqueTimestamps; + if (isTypeProvidedByAllParsers) { + const uniqueTimestamps = [... new Set(mergedTimestamps)]; + uniqueTimestamps.sort(); + return uniqueTimestamps; + } + } + + throw new Error("Failed to create aggregated timestamps (any type)"); } - notifyCurrentTimestamp(timestamp: number) { - const traceEntries: Map = new Map(); + notifyCurrentTimestamp(timestamp: Timestamp) { + const traceEntries: Map = new Map(); this.parsers.forEach(parser => { const entry = parser.getTraceEntry(timestamp); if (entry != undefined) { - traceEntries.set(parser.getTraceTypeId(), entry); + traceEntries.set(parser.getTraceType(), entry); } }); diff --git a/tools/winscope-ng/src/common/trace/screen_recording.ts b/tools/winscope-ng/src/common/trace/screen_recording.ts index 907655950..2bc398069 100644 --- a/tools/winscope-ng/src/common/trace/screen_recording.ts +++ b/tools/winscope-ng/src/common/trace/screen_recording.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + class ScreenRecordingTraceEntry { - constructor(public timestamp: number, - public videoTimeSeconds: number, + constructor(public videoTimeSeconds: number, public videoData: Blob) { } } diff --git a/tools/winscope-ng/src/common/trace/timestamp.ts b/tools/winscope-ng/src/common/trace/timestamp.ts new file mode 100644 index 000000000..2c409cf4a --- /dev/null +++ b/tools/winscope-ng/src/common/trace/timestamp.ts @@ -0,0 +1,44 @@ +/* + * 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. + */ + +enum TimestampType { + ELAPSED, + REAL, +} + +class Timestamp { + constructor(type: TimestampType, valueNs: bigint) { + this.type = type; + this.valueNs = valueNs; + } + + public getType(): TimestampType { + return this.type; + } + + public getValueNs(): bigint { + return this.valueNs; + } + + public valueOf(): bigint { + return this.getValueNs(); + } + + private readonly type: TimestampType; + private readonly valueNs: bigint; +} + +export {Timestamp, TimestampType}; diff --git a/tools/winscope-ng/src/common/trace/type_id.ts b/tools/winscope-ng/src/common/trace/trace_type.ts similarity index 95% rename from tools/winscope-ng/src/common/trace/type_id.ts rename to tools/winscope-ng/src/common/trace/trace_type.ts index 508076e05..0d51d2efe 100644 --- a/tools/winscope-ng/src/common/trace/type_id.ts +++ b/tools/winscope-ng/src/common/trace/trace_type.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -enum TraceTypeId { +enum TraceType { ACCESSIBILITY, WINDOW_MANAGER, SURFACE_FLINGER, @@ -32,4 +32,4 @@ enum TraceTypeId { ERROR, } -export {TraceTypeId}; +export {TraceType}; diff --git a/tools/winscope-ng/src/parsers/parser.ts b/tools/winscope-ng/src/parsers/parser.ts index 23909f8bc..ff683a138 100644 --- a/tools/winscope-ng/src/parsers/parser.ts +++ b/tools/winscope-ng/src/parsers/parser.ts @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {ArrayUtils} from "../common/utils/array_utils"; -import {TraceTypeId} from "common/trace/type_id"; +import {ArrayUtils} from "common/utils/array_utils"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; abstract class Parser { protected constructor(trace: Blob) { @@ -34,17 +35,39 @@ abstract class Parser { } this.decodedEntries = this.decodeTrace(traceBuffer); - this.timestamps = this.decodedEntries.map((entry: any) => this.getTimestamp(entry)); + + for (const type of [TimestampType.ELAPSED, TimestampType.REAL]) { + const timestamps: Timestamp[] = []; + let areTimestampsValid = true; + + for (const entry of this.decodedEntries) { + const timestamp = this.getTimestamp(entry, type); + if (timestamp === undefined) { + areTimestampsValid = false; + break; + } + timestamps.push(timestamp); + } + + if (areTimestampsValid) { + this.timestamps.set(type, timestamps); + } + } } - public abstract getTraceTypeId(): TraceTypeId; + public abstract getTraceType(): TraceType; - public getTimestamps(): number[] { - return this.timestamps; + public getTimestamps(type: TimestampType): undefined|Timestamp[] { + return this.timestamps.get(type); } - public getTraceEntry(timestamp: number): undefined|any { - const index = ArrayUtils.binarySearchLowerOrEqual(this.getTimestamps(), timestamp); + public getTraceEntry(timestamp: Timestamp): undefined|any { + const timestamps = this.getTimestamps(timestamp.getType()); + if (timestamps === undefined) { + throw TypeError(`Timestamps with type "${timestamp.getType()}" not available`); + } + + const index = ArrayUtils.binarySearchLowerOrEqual(timestamps, timestamp); if (index === undefined) { return undefined; } @@ -59,12 +82,13 @@ abstract class Parser { protected abstract getMagicNumber(): undefined|number[]; protected abstract decodeTrace(trace: Uint8Array): any[]; - protected abstract getTimestamp(decodedEntry: any): number; + //TODO: invert parameters below + protected abstract getTimestamp(decodedEntry: any, type: TimestampType): undefined|Timestamp; protected abstract processDecodedEntry(decodedEntry: any): any; protected trace: Blob; protected decodedEntries: any[] = []; - protected timestamps: number[] = []; + private timestamps: Map = new Map(); } export {Parser}; diff --git a/tools/winscope-ng/src/parsers/parser_accessibility.spec.ts b/tools/winscope-ng/src/parsers/parser_accessibility.spec.ts index b55362f12..a648dbf27 100644 --- a/tools/winscope-ng/src/parsers/parser_accessibility.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_accessibility.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {ParserFactory} from "./parser_factory"; import {TestUtils} from "test/test_utils"; @@ -29,16 +30,23 @@ describe("ParserAccessibility", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.ACCESSIBILITY); + expect(parser.getTraceType()).toEqual(TraceType.ACCESSIBILITY); }); - it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([850297444302, 850297882046, 850756176154, 850773581835]); + it("provides elapsed timestamps", () => { + const expected = [ + new Timestamp(TimestampType.ELAPSED, 850297444302n), + new Timestamp(TimestampType.ELAPSED, 850297882046n), + new Timestamp(TimestampType.ELAPSED, 850756176154n), + new Timestamp(TimestampType.ELAPSED, 850773581835n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); - it("retrieves trace entry", () => { - expect(Number(parser.getTraceEntry(850297444302)!.elapsedRealtimeNanos)) - .toEqual(850297444302); + it("retrieves trace entry from elapsed timestamp", () => { + const timestamp = new Timestamp(TimestampType.ELAPSED, 850297444302n); + expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos)) + .toEqual(850297444302n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_accessibility.ts b/tools/winscope-ng/src/parsers/parser_accessibility.ts index 28ed4012c..0ed7caa4f 100644 --- a/tools/winscope-ng/src/parsers/parser_accessibility.ts +++ b/tools/winscope-ng/src/parsers/parser_accessibility.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {AccessibilityTraceFileProto} from "./proto_types"; @@ -22,8 +23,8 @@ class ParserAccessibility extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.ACCESSIBILITY; + override getTraceType(): TraceType { + return TraceType.ACCESSIBILITY; } override getMagicNumber(): number[] { @@ -34,8 +35,11 @@ class ParserAccessibility extends Parser { return (AccessibilityTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_common.spec.ts b/tools/winscope-ng/src/parsers/parser_common.spec.ts index 41ef38e14..391bc78c8 100644 --- a/tools/winscope-ng/src/parsers/parser_common.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_common.spec.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -28,33 +28,43 @@ describe("Parser", () => { parser = parsers[0]; }); - it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([850254319343, 850763506110, 850782750048]); + it("provides elapsed timestamps", () => { + const expected = [ + new Timestamp(TimestampType.ELAPSED, 850254319343n), + new Timestamp(TimestampType.ELAPSED, 850763506110n), + new Timestamp(TimestampType.ELAPSED, 850782750048n) + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry (no timestamp matches)", () => { - expect(parser.getTraceEntry(850254319342)) + const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319342n); + expect(parser.getTraceEntry(timestamp)) .toEqual(undefined); }); it("retrieves trace entry (equal timestamp matches)", () => { - expect(Number(parser.getTraceEntry(850254319343)!.timestampMs)) - .toEqual(850254319343); + const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n); + expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs)) + .toEqual(850254319343n); }); it("retrieves trace entry (equal timestamp matches)", () => { - expect(Number(parser.getTraceEntry(850763506110)!.timestampMs)) - .toEqual(850763506110); + const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506110n); + expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs)) + .toEqual(850763506110n); }); it("retrieves trace entry (lower timestamp matches)", () => { - expect(Number(parser.getTraceEntry(850254319344)!.timestampMs)) - .toEqual(850254319343); + const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319344n); + expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs)) + .toEqual(850254319343n); }); it("retrieves trace entry (equal timestamp matches)", () => { - expect(Number(parser.getTraceEntry(850763506111)!.timestampMs)) - .toEqual(850763506110); + const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506111n); + expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs)) + .toEqual(850763506110n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_input_method_clients.spec.ts b/tools/winscope-ng/src/parsers/parser_input_method_clients.spec.ts index 7530b3455..8ad3f785b 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_clients.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_clients.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -29,18 +30,25 @@ describe("ParserInputMethodlClients", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.INPUT_METHOD_CLIENTS); + expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_CLIENTS); }); - it("provides timestamps", () => { - expect(parser.getTimestamps().length) + it("provides elapsed timestamps", () => { + expect(parser.getTimestamps(TimestampType.ELAPSED)!.length) .toEqual(33); - expect(parser.getTimestamps().slice(0, 3)) - .toEqual([1149083651642, 1149083950633, 1149127567251]); + + const expected = [ + new Timestamp(TimestampType.ELAPSED, 1149083651642n), + new Timestamp(TimestampType.ELAPSED, 1149083950633n), + new Timestamp(TimestampType.ELAPSED, 1149127567251n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)!.slice(0, 3)) + .toEqual(expected); }); it("retrieves trace entry", () => { - expect(Number(parser.getTraceEntry(1149083651642)!.elapsedRealtimeNanos)) - .toEqual(1149083651642); + const timestamp = new Timestamp(TimestampType.ELAPSED, 1149083651642n); + expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos)) + .toEqual(1149083651642n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_input_method_clients.ts b/tools/winscope-ng/src/parsers/parser_input_method_clients.ts index 06886288e..c8dfd4e9a 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_clients.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_clients.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {InputMethodClientsTraceFileProto} from "./proto_types"; @@ -22,8 +23,8 @@ class ParserInputMethodClients extends Parser { super(trace); } - getTraceTypeId(): TraceTypeId { - return TraceTypeId.INPUT_METHOD_CLIENTS; + getTraceType(): TraceType { + return TraceType.INPUT_METHOD_CLIENTS; } override getMagicNumber(): number[] { @@ -34,8 +35,11 @@ class ParserInputMethodClients extends Parser { return (InputMethodClientsTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_input_method_manager_service.spec.ts b/tools/winscope-ng/src/parsers/parser_input_method_manager_service.spec.ts index 7592c8dc5..293af4604 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_manager_service.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_manager_service.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -29,16 +30,22 @@ describe("ParserInputMethodManagerService", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.INPUT_METHOD_MANAGER_SERVICE); + expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_MANAGER_SERVICE); }); - it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([1149226290110, 1149237707591, 1149238950389]); + it("provides elapsed timestamps", () => { + const expected = [ + new Timestamp(TimestampType.ELAPSED, 1149226290110n), + new Timestamp(TimestampType.ELAPSED, 1149237707591n), + new Timestamp(TimestampType.ELAPSED, 1149238950389n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry", () => { - expect(Number(parser.getTraceEntry(1149226290110)!.elapsedRealtimeNanos)) - .toEqual(1149226290110); + const timestamp = new Timestamp(TimestampType.ELAPSED, 1149226290110n); + expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos)) + .toEqual(1149226290110n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_input_method_manager_service.ts b/tools/winscope-ng/src/parsers/parser_input_method_manager_service.ts index 0b5802ba6..cd9146625 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_manager_service.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_manager_service.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {InputMethodManagerServiceTraceFileProto} from "./proto_types"; @@ -22,8 +23,8 @@ class ParserInputMethodManagerService extends Parser { super(trace); } - getTraceTypeId(): TraceTypeId { - return TraceTypeId.INPUT_METHOD_MANAGER_SERVICE; + getTraceType(): TraceType { + return TraceType.INPUT_METHOD_MANAGER_SERVICE; } override getMagicNumber(): number[] { @@ -34,8 +35,11 @@ class ParserInputMethodManagerService extends Parser { return (InputMethodManagerServiceTraceFileProto.decode(buffer)).entry; } - protected override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + protected override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos)); } protected override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_input_method_service.spec.ts b/tools/winscope-ng/src/parsers/parser_input_method_service.spec.ts index 7f71b3a84..f3c2f1995 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_service.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_service.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -29,16 +30,26 @@ describe("ParserInputMethodService", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.INPUT_METHOD_SERVICE); + expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_SERVICE); }); it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([1149230019887, 1149234359324, 1149241227244, 1149243083608, 1149249518016, 1149249784617, 1149272993520]); + const expected = [ + new Timestamp(TimestampType.ELAPSED, 1149230019887n), + new Timestamp(TimestampType.ELAPSED, 1149234359324n), + new Timestamp(TimestampType.ELAPSED, 1149241227244n), + new Timestamp(TimestampType.ELAPSED, 1149243083608n), + new Timestamp(TimestampType.ELAPSED, 1149249518016n), + new Timestamp(TimestampType.ELAPSED, 1149249784617n), + new Timestamp(TimestampType.ELAPSED, 1149272993520n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry", () => { - expect(Number(parser.getTraceEntry(1149230019887)!.elapsedRealtimeNanos)) - .toEqual(1149230019887); + const timestamp = new Timestamp(TimestampType.ELAPSED, 1149230019887n); + expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos)) + .toEqual(1149230019887n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_input_method_service.ts b/tools/winscope-ng/src/parsers/parser_input_method_service.ts index b88bc5dc9..f8d258806 100644 --- a/tools/winscope-ng/src/parsers/parser_input_method_service.ts +++ b/tools/winscope-ng/src/parsers/parser_input_method_service.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {InputMethodServiceTraceFileProto} from "./proto_types"; @@ -22,8 +23,8 @@ class ParserInputMethodService extends Parser { super(trace); } - getTraceTypeId(): TraceTypeId { - return TraceTypeId.INPUT_METHOD_SERVICE; + getTraceType(): TraceType { + return TraceType.INPUT_METHOD_SERVICE; } override getMagicNumber(): number[] { @@ -34,8 +35,11 @@ class ParserInputMethodService extends Parser { return (InputMethodServiceTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_protolog.spec.ts b/tools/winscope-ng/src/parsers/parser_protolog.spec.ts index b4419c5d2..eb5f40d4d 100644 --- a/tools/winscope-ng/src/parsers/parser_protolog.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_protolog.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -39,19 +40,26 @@ describe("ParserProtoLog", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.PROTO_LOG); + expect(parser.getTraceType()).toEqual(TraceType.PROTO_LOG); }); - it("provides timestamps", () => { - const timestamps = parser.getTimestamps(); + it("provides elapsed timestamps", () => { + const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!; expect(timestamps.length) .toEqual(50); + + const expected = [ + new Timestamp(TimestampType.ELAPSED, 850746266486n), + new Timestamp(TimestampType.ELAPSED, 850746336718n), + new Timestamp(TimestampType.ELAPSED, 850746350430n), + ]; expect(timestamps.slice(0, 3)) - .toEqual([850746266486, 850746336718, 850746350430]); + .toEqual(expected); }); it("reconstructs human-readable log message", () => { - const actualMessage = parser.getTraceEntry(850746266486)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 850746266486n); + const actualMessage = parser.getTraceEntry(timestamp)!; expect(actualMessage).toBeInstanceOf(LogMessage); expect(Object.assign({}, actualMessage)).toEqual(expectedFirstLogMessage); diff --git a/tools/winscope-ng/src/parsers/parser_protolog.ts b/tools/winscope-ng/src/parsers/parser_protolog.ts index dd6fdb4af..34aac33a6 100644 --- a/tools/winscope-ng/src/parsers/parser_protolog.ts +++ b/tools/winscope-ng/src/parsers/parser_protolog.ts @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {LogMessage, FormattedLogMessage, UnformattedLogMessage} from "common/trace/protolog"; -import {TraceTypeId} from "common/trace/type_id"; +import {FormattedLogMessage, LogMessage, UnformattedLogMessage} from "common/trace/protolog"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {ProtoLogFileProto} from "./proto_types"; import configJson from "../../../../../frameworks/base/data/etc/services.core.protolog.json"; @@ -24,8 +25,8 @@ class ParserProtoLog extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.PROTO_LOG; + override getTraceType(): TraceType { + return TraceType.PROTO_LOG; } override getMagicNumber(): number[] { @@ -54,8 +55,11 @@ class ParserProtoLog extends Parser { return fileProto.log; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): LogMessage { diff --git a/tools/winscope-ng/src/parsers/parser_screen_recording.spec.ts b/tools/winscope-ng/src/parsers/parser_screen_recording.spec.ts index 4d8b5e2f7..95620bdea 100644 --- a/tools/winscope-ng/src/parsers/parser_screen_recording.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_screen_recording.spec.ts @@ -14,7 +14,8 @@ * limitations under the License. */ import {ScreenRecordingTraceEntry} from "common/trace/screen_recording"; -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {TestUtils} from "test/test_utils"; import {Parser} from "./parser"; import {ParserFactory} from "./parser_factory"; @@ -30,28 +31,66 @@ describe("ParserScreenRecording", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.SCREEN_RECORDING); + expect(parser.getTraceType()).toEqual(TraceType.SCREEN_RECORDING); }); - it("provides timestamps", () => { - const timestamps = parser.getTimestamps(); + it ("provides elapsed timestamps", () => { + const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!; expect(timestamps.length) .toEqual(88); + const expected = [ + new Timestamp(TimestampType.ELAPSED, 732949304000n), + new Timestamp(TimestampType.ELAPSED, 733272129000n), + new Timestamp(TimestampType.ELAPSED, 733283916000n), + ]; expect(timestamps.slice(0, 3)) - .toEqual([1658843852566916400, 1658843852889741300, 1658843852901528300]); + .toEqual(expected); }); - it("retrieves trace entry", () => { + it("provides real timestamps", () => { + const timestamps = parser.getTimestamps(TimestampType.REAL)!; + + expect(timestamps.length) + .toEqual(88); + + const expected = [ + new Timestamp(TimestampType.REAL, 1658843852566916386n), + new Timestamp(TimestampType.REAL, 1658843852889741386n), + new Timestamp(TimestampType.REAL, 1658843852901528386n), + ]; + expect(timestamps.slice(0, 3)) + .toEqual(expected); + }); + + it("retrieves trace entry from elapsed timestamp", () => { { - const entry = parser.getTraceEntry(1658843852566916400)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 732949304000n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0); } { - const entry = parser.getTraceEntry(1658843852889741300)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 733272129000n); + const entry = parser.getTraceEntry(timestamp)!; + expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); + expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0.322, 0.001); + } + }); + + it("retrieves trace entry from real timestamp", () => { + { + const timestamp = new Timestamp(TimestampType.REAL, 1658843852566916386n); + const entry = parser.getTraceEntry(timestamp)!; + expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); + expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0); + } + + { + const timestamp = new Timestamp(TimestampType.REAL, 1658843852889741386n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0.322, 0.001); } diff --git a/tools/winscope-ng/src/parsers/parser_screen_recording.ts b/tools/winscope-ng/src/parsers/parser_screen_recording.ts index 99ee2b2b5..cc1def217 100644 --- a/tools/winscope-ng/src/parsers/parser_screen_recording.ts +++ b/tools/winscope-ng/src/parsers/parser_screen_recording.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ArrayUtils} from "common/utils/array_utils"; import {Parser} from "./parser"; import {ScreenRecordingTraceEntry} from "common/trace/screen_recording"; @@ -28,8 +29,8 @@ class ParserScreenRecording extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.SCREEN_RECORDING; + override getTraceType(): TraceType { + return TraceType.SCREEN_RECORDING; } override getMagicNumber(): number[] { @@ -51,14 +52,33 @@ class ParserScreenRecording extends Parser { }); } - override getTimestamp(decodedEntry: ScreenRecordingMetadataEntry): number { - return Number(decodedEntry.timestampRealtimeNs); + override getTimestamp(decodedEntry: ScreenRecordingMetadataEntry, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED && type !== TimestampType.REAL) { + return undefined; + } + if (type === TimestampType.ELAPSED) { + // Traces typically contain "elapsed" timestamps (SYSTEM_TIME_BOOTTIME). + // Screen recordings contain SYSTEM_TIME_MONOTONIC timestamps. + // + // Here we are pretending that screen recordings contain "elapsed" timestamps + // as well, in order to synchronize with the other traces. + // + // If no device suspensions are involved, SYSTEM_TIME_MONOTONIC should indeed + // correspond to SYSTEM_TIME_BOOTTIME and things should work as expected. + return new Timestamp(type, decodedEntry.timestampMonotonicNs); + } + else if (type === TimestampType.REAL) { + return new Timestamp(type, decodedEntry.timestampRealtimeNs); + } + return undefined; } override processDecodedEntry(entry: ScreenRecordingMetadataEntry): ScreenRecordingTraceEntry { - const videoTimeSeconds = (Number(entry.timestampRealtimeNs) - this.timestamps[0]) / 1000000000; + const initialTimestampNs = this.getTimestamps(TimestampType.ELAPSED)![0].getValueNs(); + const currentTimestampNs = entry.timestampMonotonicNs; + const videoTimeSeconds = Number(currentTimestampNs - initialTimestampNs) / 1000000000; const videoData = this.trace; - return new ScreenRecordingTraceEntry(Number(entry.timestampRealtimeNs), videoTimeSeconds, videoData); + return new ScreenRecordingTraceEntry(videoTimeSeconds, videoData); } private searchMagicString(videoData: Uint8Array): number { diff --git a/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.spec.ts b/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.spec.ts index eff10b838..648ce05de 100644 --- a/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.spec.ts @@ -14,7 +14,8 @@ * limitations under the License. */ import {ScreenRecordingTraceEntry} from "common/trace/screen_recording"; -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {TestUtils} from "test/test_utils"; import {Parser} from "./parser"; import {ParserFactory} from "./parser_factory"; @@ -30,31 +31,48 @@ describe("ParserScreenRecordingLegacy", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.SCREEN_RECORDING); + expect(parser.getTraceType()).toEqual(TraceType.SCREEN_RECORDING); }); - it("provides timestamps", () => { - const timestamps = parser.getTimestamps(); + it("provides elapsed timestamps", () => { + const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!; expect(timestamps.length) .toEqual(85); + let expected = [ + new Timestamp(TimestampType.ELAPSED, 19446131807000n), + new Timestamp(TimestampType.ELAPSED, 19446158500000n), + new Timestamp(TimestampType.ELAPSED, 19446167117000n), + ]; expect(timestamps.slice(0, 3)) - .toEqual([19446131807000, 19446158500000, 19446167117000]); + .toEqual(expected); + expected = [ + new Timestamp(TimestampType.ELAPSED, 19448470076000n), + new Timestamp(TimestampType.ELAPSED, 19448487525000n), + new Timestamp(TimestampType.ELAPSED, 19448501007000n), + ]; expect(timestamps.slice(timestamps.length-3, timestamps.length)) - .toEqual([19448470076000, 19448487525000, 19448501007000]); + .toEqual(expected); + }); + + it("doesn't provide real timestamps", () => { + expect(parser.getTimestamps(TimestampType.REAL)) + .toEqual(undefined); }); it("retrieves trace entry", () => { { - const entry = parser.getTraceEntry(19446131807000)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 19446131807000n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0); } { - const entry = parser.getTraceEntry(19448501007000)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 19448501007000n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry); expect(Number(entry.videoTimeSeconds)).toBeCloseTo(2.37, 0.001); } diff --git a/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.ts b/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.ts index 900016e12..01550cef9 100644 --- a/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.ts +++ b/tools/winscope-ng/src/parsers/parser_screen_recording_legacy.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ArrayUtils} from "common/utils/array_utils"; import {Parser} from "./parser"; import {ScreenRecordingTraceEntry} from "common/trace/screen_recording"; @@ -23,28 +24,35 @@ class ParserScreenRecordingLegacy extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.SCREEN_RECORDING; + override getTraceType(): TraceType { + return TraceType.SCREEN_RECORDING; } override getMagicNumber(): number[] { return ParserScreenRecordingLegacy.MPEG4_MAGIC_NMBER; } - override decodeTrace(videoData: Uint8Array): number[] { + override decodeTrace(videoData: Uint8Array): Timestamp[] { const posCount = this.searchMagicString(videoData); const [posTimestamps, count] = this.parseFramesCount(videoData, posCount); return this.parseTimestamps(videoData, posTimestamps, count); } - override getTimestamp(decodedEntry: number): number { + override getTimestamp(decodedEntry: Timestamp, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } return decodedEntry; } - override processDecodedEntry(timestamp: number): ScreenRecordingTraceEntry { - const videoTimeSeconds = (timestamp - this.timestamps[0]) / 1000000000 + ParserScreenRecordingLegacy.EPSILON; + override processDecodedEntry(entry: Timestamp): ScreenRecordingTraceEntry { + const currentTimestamp = entry; + const initialTimestamp = this.getTimestamps(TimestampType.ELAPSED)![0]; + const videoTimeSeconds = + Number(currentTimestamp.getValueNs() - initialTimestamp.getValueNs()) / 1000000000 + + ParserScreenRecordingLegacy.EPSILON; const videoData = this.trace; - return new ScreenRecordingTraceEntry(timestamp, videoTimeSeconds, videoData); + return new ScreenRecordingTraceEntry(videoTimeSeconds, videoData); } private searchMagicString(videoData: Uint8Array): number { @@ -65,15 +73,15 @@ class ParserScreenRecordingLegacy extends Parser { return [pos, framesCount]; } - private parseTimestamps(videoData: Uint8Array, pos: number, count: number): number[] { + private parseTimestamps(videoData: Uint8Array, pos: number, count: number): Timestamp[] { if (pos + count * 8 > videoData.length) { throw new TypeError("Failed to parse timestamps. Video data is too short."); } - const timestamps: number[] = []; + const timestamps: Timestamp[] = []; for (let i = 0; i < count; ++i) { - const timestamp = Number(ArrayUtils.toUintLittleEndian(videoData, pos, pos+8) * 1000n); + const value = ArrayUtils.toUintLittleEndian(videoData, pos, pos+8) * 1000n; pos += 8; - timestamps.push(timestamp); + timestamps.push(new Timestamp(TimestampType.ELAPSED, value)); } return timestamps; } diff --git a/tools/winscope-ng/src/parsers/parser_surface_flinger.spec.ts b/tools/winscope-ng/src/parsers/parser_surface_flinger.spec.ts index aa4b6c8f3..17a2894d1 100644 --- a/tools/winscope-ng/src/parsers/parser_surface_flinger.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_surface_flinger.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry"; import {TestUtils} from "test/test_utils"; import {Parser} from "./parser"; @@ -30,17 +31,23 @@ describe("ParserSurfaceFlinger", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.SURFACE_FLINGER); + expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER); }); - it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([850335483446, 850686322883, 850736507697]); + it("provides elapsed timestamps", () => { + const expected = [ + new Timestamp(TimestampType.ELAPSED, 850335483446n), + new Timestamp(TimestampType.ELAPSED, 850686322883n), + new Timestamp(TimestampType.ELAPSED, 850736507697n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry", () => { - const entry = parser.getTraceEntry(850335483446)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 850335483446n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(LayerTraceEntry); - expect(Number(entry.timestampMs)).toEqual(850335483446); + expect(BigInt(entry.timestampMs)).toEqual(850335483446n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_surface_flinger.ts b/tools/winscope-ng/src/parsers/parser_surface_flinger.ts index 15eb57f57..c8cedf033 100644 --- a/tools/winscope-ng/src/parsers/parser_surface_flinger.ts +++ b/tools/winscope-ng/src/parsers/parser_surface_flinger.ts @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import {Timestamp, TimestampType} from "common/trace/timestamp"; import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry"; -import {TraceTypeId} from "common/trace/type_id"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {LayersTraceFileProto} from "./proto_types"; @@ -23,8 +24,8 @@ class ParserSurfaceFlinger extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.SURFACE_FLINGER; + override getTraceType(): TraceType { + return TraceType.SURFACE_FLINGER; } override getMagicNumber(): number[] { @@ -35,8 +36,11 @@ class ParserSurfaceFlinger extends Parser { return (LayersTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, entryProto.elapsedRealtimeNanos); } override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_surface_flinger_dump.spec.ts b/tools/winscope-ng/src/parsers/parser_surface_flinger_dump.spec.ts index 5fdb0697d..f6b79faff 100644 --- a/tools/winscope-ng/src/parsers/parser_surface_flinger_dump.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_surface_flinger_dump.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry"; import {TestUtils} from "test/test_utils"; import {Parser} from "./parser"; @@ -30,16 +31,22 @@ describe("ParserSurfaceFlingerDump", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.SURFACE_FLINGER); + expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER); }); it("provides timestamp", () => { - expect(parser.getTimestamps()).toEqual([0]); + const expected = [ + new Timestamp(TimestampType.ELAPSED, 0n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)).toEqual(expected); }); it("retrieves trace entry", () => { - const entry = parser.getTraceEntry(0)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 0n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(LayerTraceEntry); - expect(Number(entry.timestampMs)).toEqual(0); + expect(BigInt(entry.timestampMs)).toEqual(0n); }); + + //TODO: add real timestamp }); diff --git a/tools/winscope-ng/src/parsers/parser_transactions.spec.ts b/tools/winscope-ng/src/parsers/parser_transactions.spec.ts index 6a195e590..cd6f4cadb 100644 --- a/tools/winscope-ng/src/parsers/parser_transactions.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_transactions.spec.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {ParserFactory} from "./parser_factory"; import {TestUtils} from "test/test_utils"; @@ -29,19 +30,27 @@ describe("ParserTransactions", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.TRANSACTIONS); + expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS); }); it("provides timestamps", () => { - const timestamps = parser.getTimestamps(); + const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!; + expect(timestamps.length) .toEqual(4997); + + const expected = [ + new Timestamp(TimestampType.ELAPSED, 14862317023n), + new Timestamp(TimestampType.ELAPSED, 14873423549n), + new Timestamp(TimestampType.ELAPSED, 14884850511n), + ]; expect(timestamps.slice(0, 3)) - .toEqual([14862317023, 14873423549, 14884850511]); + .toEqual(expected); }); it("retrieves trace entry", () => { - expect(Number(parser.getTraceEntry(14862317023)!.elapsedRealtimeNanos)) - .toEqual(14862317023); + const timestamp = new Timestamp(TimestampType.ELAPSED, 14862317023n); + expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos)) + .toEqual(14862317023n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_transactions.ts b/tools/winscope-ng/src/parsers/parser_transactions.ts index 3aecb54ff..b3da697cc 100644 --- a/tools/winscope-ng/src/parsers/parser_transactions.ts +++ b/tools/winscope-ng/src/parsers/parser_transactions.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {TransactionsTraceFileProto} from "./proto_types"; @@ -22,8 +23,8 @@ class ParserTransactions extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.TRANSACTIONS; + override getTraceType(): TraceType { + return TraceType.TRANSACTIONS; } override getMagicNumber(): number[] { @@ -34,8 +35,11 @@ class ParserTransactions extends Parser { return (TransactionsTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): any { diff --git a/tools/winscope-ng/src/parsers/parser_window_manager.spec.ts b/tools/winscope-ng/src/parsers/parser_window_manager.spec.ts index 1d4fe1389..5409f3a56 100644 --- a/tools/winscope-ng/src/parsers/parser_window_manager.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_window_manager.spec.ts @@ -14,7 +14,8 @@ * limitations under the License. */ import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState"; -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -30,17 +31,23 @@ describe("ParserWindowManager", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.WINDOW_MANAGER); + expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER); }); it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([850254319343, 850763506110, 850782750048]); + const expected = [ + new Timestamp(TimestampType.ELAPSED, 850254319343n), + new Timestamp(TimestampType.ELAPSED, 850763506110n), + new Timestamp(TimestampType.ELAPSED, 850782750048n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry", () => { - const entry = parser.getTraceEntry(850254319343)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(WindowManagerState); - expect(Number(entry.timestampMs)).toEqual(850254319343); + expect(BigInt(entry.timestampMs)).toEqual(850254319343n); }); }); diff --git a/tools/winscope-ng/src/parsers/parser_window_manager.ts b/tools/winscope-ng/src/parsers/parser_window_manager.ts index 820143ed1..958aa48a6 100644 --- a/tools/winscope-ng/src/parsers/parser_window_manager.ts +++ b/tools/winscope-ng/src/parsers/parser_window_manager.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {WindowManagerTraceFileProto} from "./proto_types"; import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState"; @@ -23,8 +24,8 @@ class ParserWindowManager extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.WINDOW_MANAGER; + override getTraceType(): TraceType { + return TraceType.WINDOW_MANAGER; } override getMagicNumber(): number[] { @@ -35,8 +36,11 @@ class ParserWindowManager extends Parser { return (WindowManagerTraceFileProto.decode(buffer)).entry; } - override getTimestamp(entryProto: any): number { - return Number(entryProto.elapsedRealtimeNanos); + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos)); } override processDecodedEntry(entryProto: any): WindowManagerState { diff --git a/tools/winscope-ng/src/parsers/parser_window_manager_dump.spec.ts b/tools/winscope-ng/src/parsers/parser_window_manager_dump.spec.ts index 62138353e..9e05202b8 100644 --- a/tools/winscope-ng/src/parsers/parser_window_manager_dump.spec.ts +++ b/tools/winscope-ng/src/parsers/parser_window_manager_dump.spec.ts @@ -14,7 +14,8 @@ * limitations under the License. */ import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState"; -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {ParserFactory} from "./parser_factory"; import {Parser} from "./parser"; import {TestUtils} from "test/test_utils"; @@ -30,17 +31,23 @@ describe("ParserWindowManagerDump", () => { }); it("has expected trace type", () => { - expect(parser.getTraceTypeId()).toEqual(TraceTypeId.WINDOW_MANAGER); + expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER); }); it("provides timestamps", () => { - expect(parser.getTimestamps()) - .toEqual([0]); + const expected = [ + new Timestamp(TimestampType.ELAPSED, 0n), + ]; + expect(parser.getTimestamps(TimestampType.ELAPSED)) + .toEqual(expected); }); it("retrieves trace entry", () => { - const entry = parser.getTraceEntry(0)!; + const timestamp = new Timestamp(TimestampType.ELAPSED, 0n); + const entry = parser.getTraceEntry(timestamp)!; expect(entry).toBeInstanceOf(WindowManagerState); - expect(Number(entry.timestampMs)).toEqual(0); + expect(BigInt(entry.timestampMs)).toEqual(0n); }); + + //TODO: add real timestamp }); diff --git a/tools/winscope-ng/src/parsers/parser_window_manager_dump.ts b/tools/winscope-ng/src/parsers/parser_window_manager_dump.ts index 2b4f9ae0a..c1e0ab2c8 100644 --- a/tools/winscope-ng/src/parsers/parser_window_manager_dump.ts +++ b/tools/winscope-ng/src/parsers/parser_window_manager_dump.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {Timestamp, TimestampType} from "common/trace/timestamp"; +import {TraceType} from "common/trace/trace_type"; import {Parser} from "./parser"; import {WindowManagerServiceDumpProto} from "./proto_types"; import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState"; @@ -23,8 +24,8 @@ class ParserWindowManagerDump extends Parser { super(trace); } - override getTraceTypeId(): TraceTypeId { - return TraceTypeId.WINDOW_MANAGER; + override getTraceType(): TraceType { + return TraceType.WINDOW_MANAGER; } override getMagicNumber(): undefined { @@ -35,8 +36,11 @@ class ParserWindowManagerDump extends Parser { return [WindowManagerServiceDumpProto.decode(buffer)]; } - override getTimestamp(entryProto: any): number { - return 0; + override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp { + if (type !== TimestampType.ELAPSED) { + return undefined; + } + return new Timestamp(TimestampType.ELAPSED, 0n); } override processDecodedEntry(entryProto: any): WindowManagerState { diff --git a/tools/winscope-ng/src/viewers/viewer.ts b/tools/winscope-ng/src/viewers/viewer.ts index b8ef3ece2..5c66d09b2 100644 --- a/tools/winscope-ng/src/viewers/viewer.ts +++ b/tools/winscope-ng/src/viewers/viewer.ts @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { TraceTypeId } from "common/trace/type_id"; +import { TraceType } from "common/trace/trace_type"; interface Viewer { //TODO: add TraceEntry data type - notifyCurrentTraceEntries(entries: Map): void; + notifyCurrentTraceEntries(entries: Map): void; getView(): HTMLElement; } diff --git a/tools/winscope-ng/src/viewers/viewer_factory.ts b/tools/winscope-ng/src/viewers/viewer_factory.ts index 45bbacafd..82cf1e3c9 100644 --- a/tools/winscope-ng/src/viewers/viewer_factory.ts +++ b/tools/winscope-ng/src/viewers/viewer_factory.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { TraceTypeId } from "common/trace/type_id"; +import { TraceType } from "common/trace/trace_type"; import { Viewer } from "./viewer"; import { ViewerWindowManager } from "./viewer_window_manager/viewer_window_manager"; @@ -22,11 +22,11 @@ class ViewerFactory { ViewerWindowManager, ]; - public createViewers(activeTraceTypes: Set): Viewer[] { + public createViewers(activeTraceTypes: Set): Viewer[] { const viewers: Viewer[] = []; for (const Viewer of ViewerFactory.VIEWERS) { - const areViewerDepsSatisfied = Viewer.DEPENDENCIES.every((traceType: TraceTypeId) => + const areViewerDepsSatisfied = Viewer.DEPENDENCIES.every((traceType: TraceType) => activeTraceTypes.has(traceType) ); diff --git a/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.ts b/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.ts index d4ca2b2bc..30bf20fd9 100644 --- a/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.ts +++ b/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {TraceType} from "common/trace/trace_type"; import {UiData} from "./ui_data"; type UiDataCallbackType = (uiData: UiData) => void; @@ -25,7 +25,7 @@ class Presenter { this.uiDataCallback(this.uiData); } - public notifyCurrentTraceEntries(entries: Map) { + public notifyCurrentTraceEntries(entries: Map) { this.uiData = new UiData("UI data selected by user on time scrub"); this.uiDataCallback(this.uiData); } diff --git a/tools/winscope-ng/src/viewers/viewer_window_manager/viewer_window_manager.ts b/tools/winscope-ng/src/viewers/viewer_window_manager/viewer_window_manager.ts index 697d744a3..1f4b1c400 100644 --- a/tools/winscope-ng/src/viewers/viewer_window_manager/viewer_window_manager.ts +++ b/tools/winscope-ng/src/viewers/viewer_window_manager/viewer_window_manager.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {TraceTypeId} from "common/trace/type_id"; +import {TraceType} from "common/trace/trace_type"; import {Viewer} from "viewers/viewer"; import {Presenter} from "./presenter"; import {UiData} from "./ui_data"; @@ -27,7 +27,7 @@ class ViewerWindowManager implements Viewer { this.view.addEventListener("outputEvent", () => this.presenter.notifyUiEvent()); } - public notifyCurrentTraceEntries(entries: Map): void { + public notifyCurrentTraceEntries(entries: Map): void { this.presenter.notifyCurrentTraceEntries(entries); } @@ -35,7 +35,7 @@ class ViewerWindowManager implements Viewer { return this.view; } - public static readonly DEPENDENCIES: TraceTypeId[] = [TraceTypeId.WINDOW_MANAGER]; + public static readonly DEPENDENCIES: TraceType[] = [TraceType.WINDOW_MANAGER]; private view: HTMLElement; private presenter: Presenter; }