add support for traces real timestamp
Parsers support real timestamps (along the legacy elapsed timestamps) for the following trace types: - Accessibility - InputMethodClients - InputMethodManagerService - InputMethodService - ProtoLog - SurfaceFlinger - Transactions - WindowManager Bug: 235196806 Test: cd development/tools/winscope-ng && npm run build:unit && npm run test:unit Change-Id: Ib26fa7c4b8b4cc0ed3128c6805c57fcb1ce7ae85
This commit is contained in:
@@ -41,7 +41,7 @@ abstract class Parser {
|
||||
let areTimestampsValid = true;
|
||||
|
||||
for (const entry of this.decodedEntries) {
|
||||
const timestamp = this.getTimestamp(entry, type);
|
||||
const timestamp = this.getTimestamp(type, entry);
|
||||
if (timestamp === undefined) {
|
||||
areTimestampsValid = false;
|
||||
break;
|
||||
@@ -82,8 +82,7 @@ abstract class Parser {
|
||||
|
||||
protected abstract getMagicNumber(): undefined|number[];
|
||||
protected abstract decodeTrace(trace: Uint8Array): any[];
|
||||
//TODO: invert parameters below
|
||||
protected abstract getTimestamp(decodedEntry: any, type: TimestampType): undefined|Timestamp;
|
||||
protected abstract getTimestamp(type: TimestampType, decodedEntry: any): undefined|Timestamp;
|
||||
protected abstract processDecodedEntry(decodedEntry: any): any;
|
||||
|
||||
protected trace: Blob;
|
||||
|
||||
@@ -16,34 +16,72 @@
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserAccessibility", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/Accessibility.pb");
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/Accessibility.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.ACCESSIBILITY);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 14499089524n),
|
||||
new Timestamp(TimestampType.ELAPSED, 14499599656n),
|
||||
new Timestamp(TimestampType.ELAPSED, 14953120693n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107089100052652n),
|
||||
new Timestamp(TimestampType.REAL, 1659107089100562784n),
|
||||
new Timestamp(TimestampType.REAL, 1659107089554083821n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 14499599656n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(14499599656n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089100562784n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(14499599656n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.ACCESSIBILITY);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
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);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/Accessibility.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850297444302n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(850297444302n);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.ACCESSIBILITY);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 850297444302n));
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ import {AccessibilityTraceFileProto} from "./proto_types";
|
||||
class ParserAccessibility extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
override getTraceType(): TraceType {
|
||||
@@ -32,20 +33,31 @@ class ParserAccessibility extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>AccessibilityTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>AccessibilityTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
return entryProto;
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x41, 0x31, 0x31, 0x59, 0x54, 0x52, 0x41, 0x43]; // .A11YTRAC
|
||||
}
|
||||
|
||||
|
||||
@@ -14,57 +14,97 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("Parser", () => {
|
||||
let parser: Parser;
|
||||
describe("real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_WindowManager.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/WindowManager.pb");
|
||||
});
|
||||
|
||||
it("provides timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107089075566202n),
|
||||
new Timestamp(TimestampType.REAL, 1659107089999048990n),
|
||||
new Timestamp(TimestampType.REAL, 1659107090010194213n)
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (no timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089075566201n);
|
||||
expect(parser.getTraceEntry(timestamp))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089075566202n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(14474594000n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089999048990n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(15398076788n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (lower timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089999048991n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(15398076788n);
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
describe("elapsed timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("retrieves trace entry (no timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319342n);
|
||||
expect(parser.getTraceEntry(timestamp))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/WindowManager.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850254319343n);
|
||||
});
|
||||
it("provides 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 (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506110n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850763506110n);
|
||||
});
|
||||
it("retrieves trace entry (no timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319342n);
|
||||
expect(parser.getTraceEntry(timestamp))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (lower timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319344n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850254319343n);
|
||||
});
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850254319343n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506111n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850763506110n);
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506110n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850763506110n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (lower timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319344n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850254319343n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry (equal timestamp matches)", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850763506111n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.timestampMs))
|
||||
.toEqual(850763506110n);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,40 +15,76 @@
|
||||
*/
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserInputMethodlClients", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_InputMethodClients.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/InputMethodClients.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_CLIENTS);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.length)
|
||||
.toEqual(13);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 15613638434n),
|
||||
new Timestamp(TimestampType.ELAPSED, 15647516364n),
|
||||
new Timestamp(TimestampType.ELAPSED, 15677650967n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107090215405395n),
|
||||
new Timestamp(TimestampType.REAL, 1659107090249283325n),
|
||||
new Timestamp(TimestampType.REAL, 1659107090279417928n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 15647516364n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(15647516364n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107090249283325n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(15647516364n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_CLIENTS);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.length)
|
||||
.toEqual(33);
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/InputMethodClients.pb");
|
||||
});
|
||||
|
||||
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("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_CLIENTS);
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 1149083651642n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(1149083651642n);
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 1149083651642n));
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 1149083651642n));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ import {InputMethodClientsTraceFileProto} from "./proto_types";
|
||||
class ParserInputMethodClients extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
getTraceType(): TraceType {
|
||||
@@ -32,20 +33,32 @@ class ParserInputMethodClients extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>InputMethodClientsTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
return (<any>InputMethodClientsTraceFileProto.decode(buffer)).entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs != undefined) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos) + this.realToElapsedTimeOffsetNs);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
return entryProto;
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x43, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMCTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -15,37 +15,63 @@
|
||||
*/
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserInputMethodManagerService", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_InputMethodManagerService.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/InputMethodManagerService.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_MANAGER_SERVICE);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED))
|
||||
.toEqual([new Timestamp(TimestampType.ELAPSED, 15963782518n)]);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual([new Timestamp(TimestampType.REAL, 1659107090565549479n)]);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 15963782518n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(15963782518n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107090565549479n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(15963782518n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_MANAGER_SERVICE);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
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);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/InputMethodManagerService.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 1149226290110n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(1149226290110n);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_MANAGER_SERVICE);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 1149226290110n));
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ import {InputMethodManagerServiceTraceFileProto} from "./proto_types";
|
||||
class ParserInputMethodManagerService extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
getTraceType(): TraceType {
|
||||
@@ -32,20 +33,31 @@ class ParserInputMethodManagerService extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>InputMethodManagerServiceTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>InputMethodManagerServiceTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
protected override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
protected override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected override processDecodedEntry(entryProto: any): any {
|
||||
return entryProto;
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x4d, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMMTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -20,36 +20,65 @@ import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserInputMethodService", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_InputMethodService.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/InputMethodService.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_SERVICE);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 16578752896n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107091180519857n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 16578752896n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(16578752896n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107091180519857n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(16578752896n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_SERVICE);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("provides timestamps", () => {
|
||||
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);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/InputMethodService.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 1149230019887n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(1149230019887n);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.INPUT_METHOD_SERVICE);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 1149230019887n));
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ import {InputMethodServiceTraceFileProto} from "./proto_types";
|
||||
class ParserInputMethodService extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
getTraceType(): TraceType {
|
||||
@@ -32,20 +33,31 @@ class ParserInputMethodService extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>InputMethodServiceTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>InputMethodServiceTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
return entryProto;
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x53, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMSTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
import {LogMessage} from "../common/trace/protolog";
|
||||
@@ -33,10 +32,7 @@ describe("ParserProtoLog", () => {
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_ProtoLog.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/ProtoLog.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
@@ -57,6 +53,20 @@ describe("ParserProtoLog", () => {
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.REAL)!;
|
||||
expect(timestamps.length)
|
||||
.toEqual(50);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1655727125377266486n),
|
||||
new Timestamp(TimestampType.REAL, 1655727125377336718n),
|
||||
new Timestamp(TimestampType.REAL, 1655727125377350430n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("reconstructs human-readable log message", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850746266486n);
|
||||
const actualMessage = parser.getTraceEntry(timestamp)!;
|
||||
|
||||
@@ -48,6 +48,8 @@ class ParserProtoLog extends Parser {
|
||||
throw new TypeError(message);
|
||||
}
|
||||
|
||||
this.realToElapsedTimeOffsetNs = BigInt(fileProto.realTimeToElapsedTimeOffsetMillis) * 1000000n;
|
||||
|
||||
fileProto.log.sort((a: any, b: any) => {
|
||||
return Number(a.elapsedRealtimeNanos) - Number(b.elapsedRealtimeNanos);
|
||||
});
|
||||
@@ -55,11 +57,14 @@ class ParserProtoLog extends Parser {
|
||||
return fileProto.log;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type == TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type == TimestampType.REAL) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos) + this.realToElapsedTimeOffsetNs!);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): LogMessage {
|
||||
@@ -85,6 +90,7 @@ class ParserProtoLog extends Parser {
|
||||
});
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint = undefined;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x4c, 0x4f, 0x47]; // .PROTOLOG
|
||||
private static readonly PROTOLOG_VERSION = "1.0.0";
|
||||
}
|
||||
|
||||
@@ -18,16 +18,12 @@ import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
|
||||
describe("ParserScreenRecording", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const trace = UnitTestUtils.getFixtureBlob("screen_recording.mp4");
|
||||
const parsers = await new ParserFactory().createParsers([trace]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/screen_recording.mp4");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
@@ -38,12 +34,12 @@ describe("ParserScreenRecording", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!;
|
||||
|
||||
expect(timestamps.length)
|
||||
.toEqual(88);
|
||||
.toEqual(15);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 732949304000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 733272129000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 733283916000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 144857685000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 144866679000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 144875772000n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
@@ -53,12 +49,12 @@ describe("ParserScreenRecording", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.REAL)!;
|
||||
|
||||
expect(timestamps.length)
|
||||
.toEqual(88);
|
||||
.toEqual(15);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1658843852566916386n),
|
||||
new Timestamp(TimestampType.REAL, 1658843852889741386n),
|
||||
new Timestamp(TimestampType.REAL, 1658843852901528386n),
|
||||
new Timestamp(TimestampType.REAL, 1659687791485257266n),
|
||||
new Timestamp(TimestampType.REAL, 1659687791494251266n),
|
||||
new Timestamp(TimestampType.REAL, 1659687791503344266n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
@@ -66,30 +62,30 @@ describe("ParserScreenRecording", () => {
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
{
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 732949304000n);
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 144857685000n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry);
|
||||
expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0);
|
||||
}
|
||||
|
||||
{
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 733272129000n);
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 145300550000n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry);
|
||||
expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0.322, 0.001);
|
||||
expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0.442, 0.001);
|
||||
}
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
{
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1658843852566916386n);
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659687791485257266n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry);
|
||||
expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0);
|
||||
}
|
||||
|
||||
{
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1658843852889741386n);
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659687791928122266n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(ScreenRecordingTraceEntry);
|
||||
expect(Number(entry.videoTimeSeconds)).toBeCloseTo(0.322, 0.001);
|
||||
|
||||
@@ -52,19 +52,19 @@ class ParserScreenRecording extends Parser {
|
||||
});
|
||||
}
|
||||
|
||||
override getTimestamp(decodedEntry: ScreenRecordingMetadataEntry, type: TimestampType): undefined|Timestamp {
|
||||
override getTimestamp(type: TimestampType, decodedEntry: ScreenRecordingMetadataEntry): 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.
|
||||
// Traces typically contain "elapsed" timestamps (SYSTEM_TIME_BOOTTIME),
|
||||
// whereas 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.
|
||||
// correspond to SYSTEM_TIME_BOOTTIME and things will work as expected.
|
||||
return new Timestamp(type, decodedEntry.timestampMonotonicNs);
|
||||
}
|
||||
else if (type === TimestampType.REAL) {
|
||||
@@ -125,8 +125,6 @@ class ParserScreenRecording extends Parser {
|
||||
for (let i = 0; i < count; ++i) {
|
||||
const timestamp = ArrayUtils.toUintLittleEndian(videoData, pos, pos+8);
|
||||
pos += 8;
|
||||
//parse VSYNC ID here when available
|
||||
pos += 8;
|
||||
timestamps.push(timestamp);
|
||||
}
|
||||
return timestamps;
|
||||
|
||||
@@ -18,16 +18,12 @@ import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
|
||||
describe("ParserScreenRecordingLegacy", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const trace = UnitTestUtils.getFixtureBlob("screen_recording_legacy.mp4");
|
||||
const parsers = await new ParserFactory().createParsers([trace]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/screen_recording.mp4");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
|
||||
@@ -38,7 +38,7 @@ class ParserScreenRecordingLegacy extends Parser {
|
||||
return this.parseTimestamps(videoData, posTimestamps, count);
|
||||
}
|
||||
|
||||
override getTimestamp(decodedEntry: Timestamp, type: TimestampType): undefined|Timestamp {
|
||||
override getTimestamp(type: TimestampType, decodedEntry: Timestamp): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -18,36 +18,73 @@ import {TraceType} from "common/trace/trace_type";
|
||||
import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
|
||||
describe("ParserSurfaceFlinger", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_SurfaceFlinger.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/SurfaceFlinger.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 14500282843n),
|
||||
new Timestamp(TimestampType.ELAPSED, 14631249355n),
|
||||
new Timestamp(TimestampType.ELAPSED, 15403446377n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107089102062832n),
|
||||
new Timestamp(TimestampType.REAL, 1659107089233029344n),
|
||||
new Timestamp(TimestampType.REAL, 1659107090005226366n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 14631249355n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(14631249355n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089233029344n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(14631249355n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
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);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/SurfaceFlinger.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850335483446n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(850335483446n);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)![0])
|
||||
.toEqual(new Timestamp(TimestampType.ELAPSED, 850335483446n));
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ import {LayersTraceFileProto} from "./proto_types";
|
||||
class ParserSurfaceFlinger extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
override getTraceType(): TraceType {
|
||||
@@ -33,20 +34,36 @@ class ParserSurfaceFlinger extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>LayersTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>LayersTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
const isDump = !Object.prototype.hasOwnProperty.call(entryProto, "elapsedRealtimeNanos");
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return isDump
|
||||
? new Timestamp(type, 0n)
|
||||
: new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(TimestampType.ELAPSED, entryProto.elapsedRealtimeNanos);
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return isDump
|
||||
? new Timestamp(type, 0n)
|
||||
: new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
return LayerTraceEntry.fromProto(entryProto.layers.layers, entryProto.displays, entryProto.elapsedRealtimeNanos, entryProto.hwcBlob);
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x4c, 0x59, 0x52, 0x54, 0x52, 0x41, 0x43, 0x45]; // .LYRTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -18,35 +18,68 @@ import {TraceType} from "common/trace/trace_type";
|
||||
import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
|
||||
describe("ParserSurfaceFlingerDump", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("dump_SurfaceFlinger.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/dump_SurfaceFlinger.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamp", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 0n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)).toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamp (always zero)", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 0n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)).toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 0n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(0n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 0n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(0n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("provides timestamp", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 0n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)).toEqual(expected);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/dump_SurfaceFlinger.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 0n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(LayerTraceEntry);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(0n);
|
||||
});
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.SURFACE_FLINGER);
|
||||
});
|
||||
|
||||
//TODO: add real timestamp
|
||||
it("provides elapsed timestamp (always zero)", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 0n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)).toEqual(expected);
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamp", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL)).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,41 +16,92 @@
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {Parser} from "./parser";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserTransactions", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_Transactions.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/Transactions.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!;
|
||||
|
||||
expect(timestamps.length)
|
||||
.toEqual(712);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 2450981445n),
|
||||
new Timestamp(TimestampType.ELAPSED, 2517952515n),
|
||||
new Timestamp(TimestampType.ELAPSED, 4021151449n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.REAL)!;
|
||||
|
||||
expect(timestamps.length)
|
||||
.toEqual(712);
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659507541051480997n),
|
||||
new Timestamp(TimestampType.REAL, 1659507541118452067n),
|
||||
new Timestamp(TimestampType.REAL, 1659507542621651001n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elsapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 2517952515n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(2517952515n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659507541118452067n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(2517952515n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS);
|
||||
});
|
||||
describe("trace with elapsed (only) timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("provides timestamps", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!;
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/Transactions.pb");
|
||||
});
|
||||
|
||||
expect(timestamps.length)
|
||||
.toEqual(4997);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS);
|
||||
});
|
||||
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 14862317023n),
|
||||
new Timestamp(TimestampType.ELAPSED, 14873423549n),
|
||||
new Timestamp(TimestampType.ELAPSED, 14884850511n),
|
||||
];
|
||||
expect(timestamps.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
it("provides elapsed timestamps", () => {
|
||||
const timestamps = parser.getTimestamps(TimestampType.ELAPSED)!;
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 14862317023n);
|
||||
expect(BigInt(parser.getTraceEntry(timestamp)!.elapsedRealtimeNanos))
|
||||
.toEqual(14862317023n);
|
||||
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(expected);
|
||||
});
|
||||
|
||||
it("doesn't provide real timestamps", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {Parser} from "./parser";
|
||||
import {TransactionsTraceFileProto} from "./proto_types";
|
||||
import {AccessibilityTraceFileProto, TransactionsTraceFileProto} from "./proto_types";
|
||||
|
||||
class ParserTransactions extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
override getTraceType(): TraceType {
|
||||
@@ -32,20 +33,31 @@ class ParserTransactions extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>TransactionsTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>TransactionsTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
return entryProto;
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x54, 0x4e, 0x58, 0x54, 0x52, 0x41, 0x43, 0x45]; // .TNXTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -16,38 +16,82 @@
|
||||
import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState";
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
describe("ParserWindowManager", () => {
|
||||
let parser: Parser;
|
||||
describe("trace with elapsed + real timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("trace_WindowManager.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_and_real_timestamp/WindowManager.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER);
|
||||
});
|
||||
|
||||
it("provides elapsed timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 14474594000n),
|
||||
new Timestamp(TimestampType.ELAPSED, 15398076788n),
|
||||
new Timestamp(TimestampType.ELAPSED, 15409222011n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.ELAPSED)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("provides real timestamps", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.REAL, 1659107089075566202n),
|
||||
new Timestamp(TimestampType.REAL, 1659107089999048990n),
|
||||
new Timestamp(TimestampType.REAL, 1659107090010194213n),
|
||||
];
|
||||
expect(parser.getTimestamps(TimestampType.REAL)!.slice(0, 3))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 15398076788n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(WindowManagerState);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(15398076788n);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from real timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.REAL, 1659107089999048990n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(WindowManagerState);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(15398076788n);
|
||||
});
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER);
|
||||
});
|
||||
describe("trace elapsed timestamp", () => {
|
||||
let parser: Parser;
|
||||
|
||||
it("provides 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);
|
||||
});
|
||||
beforeAll(async () => {
|
||||
parser = await UnitTestUtils.getParser("traces/elapsed_timestamp/WindowManager.pb");
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(WindowManagerState);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(850254319343n);
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER);
|
||||
});
|
||||
|
||||
it("provides 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", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 850254319343n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(WindowManagerState);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(850254319343n);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerS
|
||||
class ParserWindowManager extends Parser {
|
||||
constructor(trace: Blob) {
|
||||
super(trace);
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
override getTraceType(): TraceType {
|
||||
@@ -33,20 +34,31 @@ class ParserWindowManager extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
return (<any>WindowManagerTraceFileProto.decode(buffer)).entry;
|
||||
const decoded = <any>WindowManagerTraceFileProto.decode(buffer);
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, "realToElapsedTimeOffsetNanos")) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
}
|
||||
else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
return decoded.entry;
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return new Timestamp(TimestampType.ELAPSED, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(type, this.realToElapsedTimeOffsetNs + BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): WindowManagerState {
|
||||
return WindowManagerState.fromProto(entryProto.windowManagerService, entryProto.elapsedRealtimeNanos, entryProto.where);
|
||||
}
|
||||
|
||||
private realToElapsedTimeOffsetNs: undefined|bigint;
|
||||
private static readonly MAGIC_NUMBER = [0x09, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45]; // .WINTRACE
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState";
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
import {TraceType} from "common/trace/trace_type";
|
||||
import {ParserFactory} from "./parser_factory";
|
||||
import {Parser} from "./parser";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
@@ -24,17 +23,14 @@ describe("ParserWindowManagerDump", () => {
|
||||
let parser: Parser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buffer = UnitTestUtils.getFixtureBlob("dump_WindowManager.pb");
|
||||
const parsers = await new ParserFactory().createParsers([buffer]);
|
||||
expect(parsers.length).toEqual(1);
|
||||
parser = parsers[0];
|
||||
parser = await UnitTestUtils.getParser("traces/dump_WindowManager.pb");
|
||||
});
|
||||
|
||||
it("has expected trace type", () => {
|
||||
expect(parser.getTraceType()).toEqual(TraceType.WINDOW_MANAGER);
|
||||
});
|
||||
|
||||
it("provides timestamps", () => {
|
||||
it("provides elapsed timestamp (always zero)", () => {
|
||||
const expected = [
|
||||
new Timestamp(TimestampType.ELAPSED, 0n),
|
||||
];
|
||||
@@ -42,12 +38,15 @@ describe("ParserWindowManagerDump", () => {
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
it("retrieves trace entry", () => {
|
||||
it("doesn't provide real timestamp (never)", () => {
|
||||
expect(parser.getTimestamps(TimestampType.REAL))
|
||||
.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("retrieves trace entry from elapsed timestamp", () => {
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 0n);
|
||||
const entry = parser.getTraceEntry(timestamp)!;
|
||||
expect(entry).toBeInstanceOf(WindowManagerState);
|
||||
expect(BigInt(entry.timestampMs)).toEqual(0n);
|
||||
});
|
||||
|
||||
//TODO: add real timestamp
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ class ParserWindowManagerDump extends Parser {
|
||||
return [WindowManagerServiceDumpProto.decode(buffer)];
|
||||
}
|
||||
|
||||
override getTimestamp(entryProto: any, type: TimestampType): undefined|Timestamp {
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined|Timestamp {
|
||||
if (type !== TimestampType.ELAPSED) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ class CommonTestUtils {
|
||||
}
|
||||
|
||||
static getFixturePath(filename: string): string {
|
||||
if (path.isAbsolute(filename)) {
|
||||
return filename;
|
||||
}
|
||||
return path.join(CommonTestUtils.getProjectRootPath(), "src/test/fixtures", filename);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("Viewer WindowManager", () => {
|
||||
|
||||
it("processes trace and renders view", () => {
|
||||
const inputFile = element(by.css("input[type=\"file\"]"));
|
||||
inputFile.sendKeys(E2eTestUtils.getFixturePath("trace_WindowManager.pb"));
|
||||
inputFile.sendKeys(E2eTestUtils.getFixturePath("traces/elapsed_and_real_timestamp/WindowManager.pb"));
|
||||
|
||||
const windowManagerViewerTitle = element(by.css(".viewer-window-manager .title"));
|
||||
expect(windowManagerViewerTitle.getText()).toContain("Window Manager");
|
||||
|
||||
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/Accessibility.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/Accessibility.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodClients.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodClients.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodManagerService.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodManagerService.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodService.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/InputMethodService.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/SurfaceFlinger.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/SurfaceFlinger.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/Transactions.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/Transactions.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/WindowManager.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/WindowManager.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/dump_SurfaceFlinger.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/dump_SurfaceFlinger.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/screen_recording.mp4
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/elapsed_and_real_timestamp/screen_recording.mp4
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user