Prep for new data interfaces from parsers.
Added geometry utils, which are used in rects/timeline components to improve typing by unifying a common Rect interface.
Bug: b/307906075 b/311403104
Test: npm run test:unit:ci
Change-Id: Idf39b22c69dc4de7f178afb3b301ffed707b8bb0
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/abstract_timeline_row_component.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/abstract_timeline_row_component.ts
index 7795728..dd9ab56 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/abstract_timeline_row_component.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/abstract_timeline_row_component.ts
@@ -15,6 +15,7 @@
*/
import {ElementRef, EventEmitter, SimpleChanges} from '@angular/core';
+import {Point} from 'common/geometry_utils';
import {TraceEntry} from 'trace/trace';
import {TracePosition} from 'trace/trace_position';
import {CanvasDrawer} from './canvas_drawer';
@@ -100,10 +101,12 @@
async handleMouseDown(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
- const mouseX = e.offsetX;
- const mouseY = e.offsetY;
+ const mousePoint = {
+ x: e.offsetX,
+ y: e.offsetY,
+ };
- const transitionEntry = await this.getEntryAt(mouseX, mouseY);
+ const transitionEntry = await this.getEntryAt(mousePoint);
// TODO: This can probably get made better by getting the transition and checking both the end and start timestamps match
if (transitionEntry && transitionEntry !== this.selectedEntry) {
this.redraw();
@@ -115,23 +118,25 @@
handleMouseMove(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
- const mouseX = e.offsetX;
- const mouseY = e.offsetY;
+ const mousePoint = {
+ x: e.offsetX,
+ y: e.offsetY,
+ };
- this.updateCursor(mouseX, mouseY);
- this.onHover(mouseX, mouseY);
+ this.updateCursor(mousePoint);
+ this.onHover(mousePoint);
}
- protected async updateCursor(mouseX: number, mouseY: number) {
- if (this.getEntryAt(mouseX, mouseY) !== undefined) {
+ protected async updateCursor(mousePoint: Point) {
+ if (this.getEntryAt(mousePoint) !== undefined) {
this.getCanvas().style.cursor = 'pointer';
} else {
this.getCanvas().style.cursor = 'auto';
}
}
- protected abstract getEntryAt(mouseX: number, mouseY: number): Promise<TraceEntry<T> | undefined>;
- protected abstract onHover(mouseX: number, mouseY: number): void;
+ protected abstract getEntryAt(mousePoint: Point): Promise<TraceEntry<T> | undefined>;
+ protected abstract onHover(mousePoint: Point): void;
protected abstract handleMouseOut(e: MouseEvent): void;
protected async redraw() {
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer.ts
index 7100d43..2190fca 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer.ts
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+import {Rect} from 'common/geometry_utils';
+
export class CanvasDrawer {
private canvas!: HTMLCanvasElement;
private ctx!: CanvasRenderingContext2D;
@@ -27,23 +29,22 @@
this.ctx = ctx;
}
- drawRect(drawParams: {x: number; y: number; w: number; h: number; color: string; alpha: number}) {
- const {x, y, w, h, color, alpha} = drawParams;
+ drawRect(rect: Rect, color: string, alpha: number) {
const rgbColor = this.hexToRgb(color);
if (rgbColor === undefined) {
throw new Error('Failed to parse provided hex color');
}
const {r, g, b} = rgbColor;
- this.defineRectPath(x, y, w, h);
+ this.defineRectPath(rect);
this.ctx.fillStyle = `rgba(${r},${g},${b},${alpha})`;
this.ctx.fill();
this.ctx.restore();
}
- drawRectBorder(x: number, y: number, w: number, h: number) {
- this.defineRectPath(x, y, w, h);
+ drawRectBorder(rect: Rect) {
+ this.defineRectPath(rect);
this.highlightPath();
this.ctx.restore();
}
@@ -79,13 +80,13 @@
this.ctx.stroke();
}
- private defineRectPath(x: number, y: number, w: number, h: number) {
+ private defineRectPath(rect: Rect) {
this.ctx.beginPath();
- this.ctx.moveTo(x, y);
- this.ctx.lineTo(x + w, y);
- this.ctx.lineTo(x + w, y + h);
- this.ctx.lineTo(x, y + h);
- this.ctx.lineTo(x, y);
+ this.ctx.moveTo(rect.x, rect.y);
+ this.ctx.lineTo(rect.x + rect.w, rect.y);
+ this.ctx.lineTo(rect.x + rect.w, rect.y + rect.h);
+ this.ctx.lineTo(rect.x, rect.y + rect.h);
+ this.ctx.lineTo(rect.x, rect.y);
this.ctx.closePath();
}
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer_test.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer_test.ts
index 61ecafe..b759cec 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer_test.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/canvas_drawer_test.ts
@@ -24,7 +24,7 @@
const canvasDrawer = new CanvasDrawer();
canvasDrawer.setCanvas(actualCanvas);
- canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10, color: '#333333', alpha: 1.0});
+ canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10}, '#333333', 1.0);
expect(pixelsAllMatch(actualCanvas, expectedCanvas)).toBeFalse();
@@ -39,7 +39,7 @@
const canvasDrawer = new CanvasDrawer();
canvasDrawer.setCanvas(actualCanvas);
- canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10, color: '#333333', alpha: 1.0});
+ canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10}, '#333333', 1.0);
const expectedCtx = assertDefined(expectedCanvas.getContext('2d'));
expectedCtx.fillStyle = '#333333';
@@ -55,7 +55,7 @@
const canvasDrawer = new CanvasDrawer();
canvasDrawer.setCanvas(actualCanvas);
- canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10, color: '#333333', alpha: 0.5});
+ canvasDrawer.drawRect({x: 10, y: 10, w: 10, h: 10}, '#333333', 0.5);
const expectedCtx = assertDefined(expectedCanvas.getContext('2d'));
expectedCtx.fillStyle = 'rgba(51,51,51,0.5)';
@@ -71,7 +71,7 @@
const canvasDrawer = new CanvasDrawer();
canvasDrawer.setCanvas(actualCanvas);
- canvasDrawer.drawRectBorder(10, 10, 10, 10);
+ canvasDrawer.drawRectBorder({x: 10, y: 10, w: 10, h: 10});
const expectedCtx = assertDefined(expectedCanvas.getContext('2d'));
@@ -93,8 +93,8 @@
const canvasDrawer = new CanvasDrawer();
canvasDrawer.setCanvas(actualCanvas);
- canvasDrawer.drawRect({x: 200, y: 200, w: 10, h: 10, color: '#333333', alpha: 1.0});
- canvasDrawer.drawRect({x: 95, y: 95, w: 50, h: 50, color: '#333333', alpha: 1.0});
+ canvasDrawer.drawRect({x: 200, y: 200, w: 10, h: 10}, '#333333', 1.0);
+ canvasDrawer.drawRect({x: 95, y: 95, w: 50, h: 50}, '#333333', 1.0);
const expectedCtx = assertDefined(expectedCanvas.getContext('2d'));
expectedCtx.fillStyle = '#333333';
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
index 3eb5093..4686def 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
@@ -15,7 +15,7 @@
*/
import {Component, ElementRef, EventEmitter, Input, Output, ViewChild} from '@angular/core';
-import {isPointInRect} from 'common/geometry_utils';
+import {isPointInRect, Point, Rect} from 'common/geometry_utils';
import {TimeRange, Timestamp} from 'common/time';
import {Trace, TraceEntry} from 'trace/trace';
import {TracePosition} from 'trace/trace_position';
@@ -57,8 +57,8 @@
}
}
- override onHover(mouseX: number, mouseY: number) {
- this.drawEntryHover(mouseX, mouseY);
+ override onHover(mousePoint: Point) {
+ this.drawEntryHover(mousePoint);
}
override handleMouseOut(e: MouseEvent) {
@@ -70,8 +70,8 @@
this.hoveringSegment = undefined;
}
- private async drawEntryHover(mouseX: number, mouseY: number) {
- const currentHoverEntry = (await this.getEntryAt(mouseX, mouseY))?.getTimestamp();
+ private async drawEntryHover(mousePoint: Point) {
+ const currentHoverEntry = (await this.getEntryAt(mousePoint))?.getTimestamp();
if (this.hoveringEntry === currentHoverEntry) {
return;
@@ -89,23 +89,20 @@
return;
}
- const {x, y, w, h} = this.entryRect(this.hoveringEntry);
+ const rect = this.entryRect(this.hoveringEntry);
- this.canvasDrawer.drawRect({x, y, w, h, color: this.color, alpha: 1.0});
- this.canvasDrawer.drawRectBorder(x, y, w, h);
+ this.canvasDrawer.drawRect(rect, this.color, 1.0);
+ this.canvasDrawer.drawRectBorder(rect);
}
- protected override async getEntryAt(
- mouseX: number,
- mouseY: number
- ): Promise<TraceEntry<{}> | undefined> {
- const timestampOfClick = this.getTimestampOf(mouseX);
+ protected override async getEntryAt(mousePoint: Point): Promise<TraceEntry<{}> | undefined> {
+ const timestampOfClick = this.getTimestampOf(mousePoint.x);
const candidateEntry = this.trace.findLastLowerOrEqualEntry(timestampOfClick);
if (candidateEntry !== undefined) {
const timestamp = candidateEntry.getTimestamp();
- const {x, y, w, h} = this.entryRect(timestamp);
- if (isPointInRect({x: mouseX, y: mouseY}, {x, y, w, h})) {
+ const rect = this.entryRect(timestamp);
+ if (isPointInRect(mousePoint, rect)) {
return candidateEntry;
}
}
@@ -121,7 +118,7 @@
return Math.floor(this.canvasDrawer.getScaledCanvasWidth() - this.entryWidth);
}
- private entryRect(entry: Timestamp, padding = 0) {
+ private entryRect(entry: Timestamp, padding = 0): Rect {
const xPos = this.getXPosOf(entry);
return {
@@ -156,9 +153,9 @@
}
private drawEntry(entry: Timestamp) {
- const {x, y, w, h} = this.entryRect(entry);
+ const rect = this.entryRect(entry);
- this.canvasDrawer.drawRect({x, y, w, h, color: this.color, alpha: 0.2});
+ this.canvasDrawer.drawRect(rect, this.color, 0.2);
}
private drawSelectedEntry() {
@@ -166,8 +163,8 @@
return;
}
- const {x, y, w, h} = this.entryRect(this.selectedEntry.getTimestamp(), 1);
- this.canvasDrawer.drawRect({x, y, w, h, color: this.color, alpha: 1.0});
- this.canvasDrawer.drawRectBorder(x, y, w, h);
+ const rect = this.entryRect(this.selectedEntry.getTimestamp(), 1);
+ this.canvasDrawer.drawRect(rect, this.color, 1.0);
+ this.canvasDrawer.drawRectBorder(rect);
}
}
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component_test.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component_test.ts
index 98b751b..6b3fd40 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component_test.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component_test.ts
@@ -81,38 +81,46 @@
const canvasWidth = component.canvasDrawer.getScaledCanvasWidth() - width;
expect(drawRectSpy).toHaveBeenCalledTimes(4);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: 0,
- y: 0,
- w: width,
- h: height,
- color: component.color,
- alpha,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor((canvasWidth * 2) / 100),
- y: 0,
- w: width,
- h: height,
- color: component.color,
- alpha,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor((canvasWidth * 5) / 100),
- y: 0,
- w: width,
- h: height,
- color: component.color,
- alpha,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor((canvasWidth * 60) / 100),
- y: 0,
- w: width,
- h: height,
- color: component.color,
- alpha,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: 0,
+ y: 0,
+ w: width,
+ h: height,
+ },
+ component.color,
+ alpha
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor((canvasWidth * 2) / 100),
+ y: 0,
+ w: width,
+ h: height,
+ },
+ component.color,
+ alpha
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor((canvasWidth * 5) / 100),
+ y: 0,
+ w: width,
+ h: height,
+ },
+ component.color,
+ alpha
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor((canvasWidth * 60) / 100),
+ y: 0,
+ w: width,
+ h: height,
+ },
+ component.color,
+ alpha
+ );
});
it('can draw entries zoomed in', async () => {
@@ -132,14 +140,16 @@
const canvasWidth = component.canvasDrawer.getScaledCanvasWidth() - width;
expect(drawRectSpy).toHaveBeenCalledTimes(1);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor((canvasWidth * 10) / 25),
- y: 0,
- w: width,
- h: height,
- color: component.color,
- alpha,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor((canvasWidth * 10) / 25),
+ y: 0,
+ w: width,
+ h: height,
+ },
+ component.color,
+ alpha
+ );
});
it('can draw hovering entry', async () => {
@@ -167,17 +177,24 @@
expect(assertDefined(component.hoveringEntry).getValueNs()).toBe(10n);
expect(drawRectSpy).toHaveBeenCalledTimes(1);
- expect(drawRectSpy).toHaveBeenCalledWith({
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: 0,
+ y: 0,
+ w: 32,
+ h: 32,
+ },
+ component.color,
+ 1.0
+ );
+
+ expect(drawRectBorderSpy).toHaveBeenCalledTimes(1);
+ expect(drawRectBorderSpy).toHaveBeenCalledWith({
x: 0,
y: 0,
w: 32,
h: 32,
- color: component.color,
- alpha: 1.0,
});
-
- expect(drawRectBorderSpy).toHaveBeenCalledTimes(1);
- expect(drawRectBorderSpy).toHaveBeenCalledWith(0, 0, 32, 32);
});
it('can draw correct entry on click of first entry', async () => {
@@ -272,17 +289,17 @@
expectedTimestampNs
);
- expect(drawRectSpy).toHaveBeenCalledTimes(rectSpyCalls);
- expect(drawRectSpy).toHaveBeenCalledWith({
+ const expectedRect = {
x: xPos + 1,
y: 1,
w: 30,
h: 30,
- color: component.color,
- alpha: 1.0,
- });
+ };
+
+ expect(drawRectSpy).toHaveBeenCalledTimes(rectSpyCalls);
+ expect(drawRectSpy).toHaveBeenCalledWith(expectedRect, component.color, 1.0);
expect(drawRectBorderSpy).toHaveBeenCalledTimes(1);
- expect(drawRectBorderSpy).toHaveBeenCalledWith(xPos + 1, 1, 30, 30);
+ expect(drawRectBorderSpy).toHaveBeenCalledWith(expectedRect);
}
});
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
index 262669c..c2eb07f 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
@@ -15,7 +15,7 @@
*/
import {Component, ElementRef, EventEmitter, Input, Output, ViewChild} from '@angular/core';
-import {isPointInRect} from 'common/geometry_utils';
+import {isPointInRect, Point, Rect} from 'common/geometry_utils';
import {ElapsedTimestamp, RealTimestamp, TimeRange, Timestamp, TimestampType} from 'common/time';
import {Transition} from 'flickerlib/common';
import {Trace, TraceEntry} from 'trace/trace';
@@ -101,8 +101,8 @@
return rowToUse;
}
- override onHover(mouseX: number, mouseY: number) {
- this.drawSegmentHover(mouseX, mouseY);
+ override onHover(mousePoint: Point) {
+ this.drawSegmentHover(mousePoint);
}
override handleMouseOut(e: MouseEvent) {
@@ -113,8 +113,8 @@
this.hoveringEntry = undefined;
}
- private async drawSegmentHover(mouseX: number, mouseY: number) {
- const currentHoverEntry = await this.getEntryAt(mouseX, mouseY);
+ private async drawSegmentHover(mousePoint: Point) {
+ const currentHoverEntry = await this.getEntryAt(mousePoint);
if (this.hoveringEntry) {
this.canvasDrawer.clear();
@@ -129,13 +129,12 @@
const hoveringSegment = await this.getSegmentForTransition(this.hoveringEntry);
const rowToUse = this.getRowToUseFor(this.hoveringEntry);
- const {x, y, w, h} = this.getSegmentRect(hoveringSegment.from, hoveringSegment.to, rowToUse);
- this.canvasDrawer.drawRectBorder(x, y, w, h);
+ const rect = this.getSegmentRect(hoveringSegment.from, hoveringSegment.to, rowToUse);
+ this.canvasDrawer.drawRectBorder(rect);
}
protected override async getEntryAt(
- mouseX: number,
- mouseY: number
+ mousePoint: Point
): Promise<TraceEntry<Transition> | undefined> {
if (this.trace.type !== TraceType.TRANSITION) {
return undefined;
@@ -150,12 +149,8 @@
}
const transitionSegment = await this.getSegmentForTransition(entry);
const rowToUse = this.getRowToUseFor(entry);
- const {x, y, w, h} = this.getSegmentRect(
- transitionSegment.from,
- transitionSegment.to,
- rowToUse
- );
- if (isPointInRect({x: mouseX, y: mouseY}, {x, y, w, h})) {
+ const rect = this.getSegmentRect(transitionSegment.from, transitionSegment.to, rowToUse);
+ if (isPointInRect(mousePoint, rect)) {
return entry;
}
return undefined;
@@ -188,7 +183,7 @@
return Number((BigInt(this.availableWidth) * (entry.getValueNs() - start)) / (end - start));
}
- private getSegmentRect(start: Timestamp, end: Timestamp, rowToUse: number) {
+ private getSegmentRect(start: Timestamp, end: Timestamp, rowToUse: number): Rect {
const xPosStart = this.getXPosOf(start);
const selectionStart = this.selectionRange.from.getValueNs();
const selectionEnd = this.selectionRange.to.getValueNs();
@@ -248,9 +243,9 @@
}
private drawSegment(start: Timestamp, end: Timestamp, rowToUse: number, aborted: boolean) {
- const {x, y, w, h} = this.getSegmentRect(start, end, rowToUse);
+ const rect = this.getSegmentRect(start, end, rowToUse);
const alpha = aborted ? 0.25 : 1.0;
- this.canvasDrawer.drawRect({x, y, w, h, color: this.color, alpha});
+ this.canvasDrawer.drawRect(rect, this.color, alpha);
}
private async drawSelectedTransitionEntry() {
@@ -262,14 +257,10 @@
const transition = await this.selectedEntry.getValue();
const rowIndex = this.getRowToUseFor(this.selectedEntry);
- const {x, y, w, h} = this.getSegmentRect(
- transitionSegment.from,
- transitionSegment.to,
- rowIndex
- );
+ const rect = this.getSegmentRect(transitionSegment.from, transitionSegment.to, rowIndex);
const alpha = transition.aborted ? 0.25 : 1.0;
- this.canvasDrawer.drawRect({x, y, w, h, color: this.color, alpha});
- this.canvasDrawer.drawRectBorder(x, y, w, h);
+ this.canvasDrawer.drawRect(rect, this.color, alpha);
+ this.canvasDrawer.drawRectBorder(rect);
}
private shouldNotRenderEntry(entry: TraceEntry<Transition>): boolean {
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component_test.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component_test.ts
index 4db18ee..a5bbd3e 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component_test.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component_test.ts
@@ -95,22 +95,26 @@
const width = component.canvasDrawer.getScaledCanvasWidth();
expect(drawRectSpy).toHaveBeenCalledTimes(2);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: 0,
- y: padding,
- w: Math.floor(width / 5),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor(width / 2),
- y: padding,
- w: Math.floor(width / 2),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: 0,
+ y: padding,
+ w: Math.floor(width / 5),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor(width / 2),
+ y: padding,
+ w: Math.floor(width / 2),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
});
it('can draw transitions zoomed in', async () => {
@@ -142,22 +146,26 @@
const width = component.canvasDrawer.getScaledCanvasWidth();
expect(drawRectSpy).toHaveBeenCalledTimes(2);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: -Math.floor(width / 10),
- y: padding,
- w: Math.floor(width / 5),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor(width / 2),
- y: padding,
- w: Math.floor(width),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: -Math.floor(width / 10),
+ y: padding,
+ w: Math.floor(width / 5),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor(width / 2),
+ y: padding,
+ w: Math.floor(width),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
});
it('can draw selected entry', async () => {
@@ -189,23 +197,17 @@
const oneRowHeight = oneRowTotalHeight - padding;
const width = component.canvasDrawer.getScaledCanvasWidth();
- expect(drawRectSpy).toHaveBeenCalledTimes(2); // once drawn as a normal entry another time with rect border
- expect(drawRectSpy).toHaveBeenCalledWith({
+ const expectedRect = {
x: Math.floor((width * 1) / 4),
y: padding,
w: Math.floor(width / 2),
h: oneRowHeight,
- color: component.color,
- alpha: 0.25,
- });
+ };
+ expect(drawRectSpy).toHaveBeenCalledTimes(2); // once drawn as a normal entry another time with rect border
+ expect(drawRectSpy).toHaveBeenCalledWith(expectedRect, component.color, 0.25);
expect(drawRectBorderSpy).toHaveBeenCalledTimes(1);
- expect(drawRectBorderSpy).toHaveBeenCalledWith(
- Math.floor((width * 1) / 4),
- padding,
- Math.floor(width / 2),
- oneRowHeight
- );
+ expect(drawRectBorderSpy).toHaveBeenCalledWith(expectedRect);
});
it('can draw hovering entry', async () => {
@@ -242,23 +244,17 @@
await waitToBeCalled(drawRectSpy, 1);
await waitToBeCalled(drawRectBorderSpy, 1);
- expect(drawRectSpy).toHaveBeenCalledTimes(1);
- expect(drawRectSpy).toHaveBeenCalledWith({
+ const expectedRect = {
x: Math.floor((width * 1) / 4),
y: padding,
w: Math.floor(width / 2),
h: oneRowHeight,
- color: component.color,
- alpha: 0.25,
- });
+ };
+ expect(drawRectSpy).toHaveBeenCalledTimes(1);
+ expect(drawRectSpy).toHaveBeenCalledWith(expectedRect, component.color, 0.25);
expect(drawRectBorderSpy).toHaveBeenCalledTimes(1);
- expect(drawRectBorderSpy).toHaveBeenCalledWith(
- Math.floor((width * 1) / 4),
- padding,
- Math.floor(width / 2),
- oneRowHeight
- );
+ expect(drawRectBorderSpy).toHaveBeenCalledWith(expectedRect);
});
it('can draw overlapping transitions (default)', async () => {
@@ -291,22 +287,26 @@
const width = component.canvasDrawer.getScaledCanvasWidth();
expect(drawRectSpy).toHaveBeenCalledTimes(2);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: 0,
- y: padding,
- w: Math.floor((width * 3) / 4),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor(width / 2),
- y: padding + oneRowTotalHeight,
- w: Math.floor(width / 2),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: 0,
+ y: padding,
+ w: Math.floor((width * 3) / 4),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor(width / 2),
+ y: padding + oneRowTotalHeight,
+ w: Math.floor(width / 2),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
});
it('can draw overlapping transitions (contained)', async () => {
@@ -339,22 +339,26 @@
const width = component.canvasDrawer.getScaledCanvasWidth();
expect(drawRectSpy).toHaveBeenCalledTimes(2);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: 0,
- y: padding,
- w: Math.floor((width * 3) / 4),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor(width / 4),
- y: padding + oneRowTotalHeight,
- w: Math.floor(width / 4),
- h: oneRowHeight,
- color: component.color,
- alpha: 1,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: 0,
+ y: padding,
+ w: Math.floor((width * 3) / 4),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor(width / 4),
+ y: padding + oneRowTotalHeight,
+ w: Math.floor(width / 4),
+ h: oneRowHeight,
+ },
+ component.color,
+ 1
+ );
});
it('can draw aborted transitions', async () => {
@@ -383,14 +387,16 @@
const width = component.canvasDrawer.getScaledCanvasWidth();
expect(drawRectSpy).toHaveBeenCalledTimes(1);
- expect(drawRectSpy).toHaveBeenCalledWith({
- x: Math.floor((width * 1) / 4),
- y: padding,
- w: Math.floor(width / 2),
- h: oneRowHeight,
- color: component.color,
- alpha: 0.25,
- });
+ expect(drawRectSpy).toHaveBeenCalledWith(
+ {
+ x: Math.floor((width * 1) / 4),
+ y: padding,
+ w: Math.floor(width / 2),
+ h: oneRowHeight,
+ },
+ component.color,
+ 0.25
+ );
});
it('does not render transition with min creation time', async () => {
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/drawer/canvas_mouse_handler_impl.ts b/tools/winscope/src/app/components/timeline/mini-timeline/drawer/canvas_mouse_handler_impl.ts
index 18e4cd2..dccdd8d 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/drawer/canvas_mouse_handler_impl.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/drawer/canvas_mouse_handler_impl.ts
@@ -15,6 +15,7 @@
*/
import {assertDefined} from 'common/assert_utils';
+import {Point} from 'common/geometry_utils';
import {CanvasMouseHandler, DragListener, DropListener} from './canvas_mouse_handler';
import {DraggableCanvasObject} from './draggable_canvas_object';
import {MiniTimelineDrawer} from './mini_timeline_drawer';
@@ -30,7 +31,7 @@
constructor(
private drawer: MiniTimelineDrawer,
private defaultCursor: string = 'auto',
- private onUnhandledMouseDown: (x: number, y: number) => void = (x, y) => {}
+ private onUnhandledMouseDown: (point: Point) => void = (point) => {}
) {
this.drawer.canvas.addEventListener('mousemove', (event) => {
this.handleMouseMove(event);
@@ -66,49 +67,49 @@
private handleMouseDown(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
- const {mouseX, mouseY} = this.getPos(e);
+ const mousePoint = this.getPos(e);
- const clickedObject = this.objectAt(mouseX, mouseY);
+ const clickedObject = this.objectAt(mousePoint);
if (clickedObject !== undefined) {
this.draggingObject = clickedObject;
} else {
- this.onUnhandledMouseDown(mouseX, mouseY);
+ this.onUnhandledMouseDown(mousePoint);
}
- this.updateCursor(mouseX, mouseY);
+ this.updateCursor(mousePoint);
}
private handleMouseMove(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
- const {mouseX, mouseY} = this.getPos(e);
+ const mousePoint = this.getPos(e);
if (this.draggingObject !== undefined) {
const onDragCallback = this.onDrag.get(this.draggingObject);
if (onDragCallback !== undefined) {
- onDragCallback(mouseX, mouseY);
+ onDragCallback(mousePoint.x, mousePoint.y);
}
}
- this.updateCursor(mouseX, mouseY);
+ this.updateCursor(mousePoint);
}
private handleMouseUp(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
- const {mouseX, mouseY} = this.getPos(e);
+ const mousePoint = this.getPos(e);
if (this.draggingObject !== undefined) {
const onDropCallback = this.onDrop.get(this.draggingObject);
if (onDropCallback !== undefined) {
- onDropCallback(mouseX, mouseY);
+ onDropCallback(mousePoint.x, mousePoint.y);
}
}
this.draggingObject = undefined;
- this.updateCursor(mouseX, mouseY);
+ this.updateCursor(mousePoint);
}
- private getPos(e: MouseEvent) {
+ private getPos(e: MouseEvent): Point {
let mouseX = e.offsetX;
const mouseY = e.offsetY;
@@ -120,11 +121,11 @@
mouseX = this.drawer.getWidth() - this.drawer.padding.right;
}
- return {mouseX, mouseY};
+ return {x: mouseX, y: mouseY};
}
- private updateCursor(mouseX: number, mouseY: number) {
- const hoverObject = this.objectAt(mouseX, mouseY);
+ private updateCursor(mousePoint: Point) {
+ const hoverObject = this.objectAt(mousePoint);
if (hoverObject !== undefined) {
if (hoverObject === this.draggingObject) {
this.drawer.canvas.style.cursor = 'grabbing';
@@ -136,11 +137,11 @@
}
}
- private objectAt(mouseX: number, mouseY: number): DraggableCanvasObject | undefined {
+ private objectAt(mousePoint: Point): DraggableCanvasObject | undefined {
for (const object of this.draggableObjects) {
const ctx = assertDefined(this.drawer.canvas.getContext('2d'));
object.definePath(ctx);
- if (ctx.isPointInPath(mouseX, mouseY)) {
+ if (ctx.isPointInPath(mousePoint.x, mousePoint.y)) {
return object;
}
}
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/drawer/mini_timeline_drawer_impl.ts b/tools/winscope/src/app/components/timeline/mini-timeline/drawer/mini_timeline_drawer_impl.ts
index fda8db7..e739128 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/drawer/mini_timeline_drawer_impl.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/drawer/mini_timeline_drawer_impl.ts
@@ -16,6 +16,7 @@
import {Color} from 'app/colors';
import {TRACE_INFO} from 'app/trace_info';
+import {Point} from 'common/geometry_utils';
import {Padding} from 'common/padding';
import {Timestamp} from 'common/time';
import {CanvasMouseHandler} from './canvas_mouse_handler';
@@ -78,8 +79,8 @@
this.ctx = ctx;
- const onUnhandledClickInternal = async (x: number, y: number) => {
- this.onUnhandledClick(this.input.transformer.untransform(x));
+ const onUnhandledClickInternal = async (mousePoint: Point) => {
+ this.onUnhandledClick(this.input.transformer.untransform(mousePoint.x));
};
this.handler = new CanvasMouseHandlerImpl(this, 'pointer', onUnhandledClickInternal);
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
index 82dc303..5badc62 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
@@ -28,6 +28,7 @@
} from '@angular/core';
import {Color} from 'app/colors';
import {assertDefined} from 'common/assert_utils';
+import {Point} from 'common/geometry_utils';
import {TimeRange, Timestamp} from 'common/time';
import {TracePosition} from 'trace/trace_position';
import {Transformer} from './transformer';
@@ -126,7 +127,7 @@
dragging = false;
sliderWidth = 0;
- dragPosition = {x: 0, y: 0};
+ dragPosition: Point = {x: 0, y: 0};
viewInitialized = false;
cursorOffset = 0;
diff --git a/tools/winscope/src/common/geometry_utils.ts b/tools/winscope/src/common/geometry_utils.ts
index 2abeefc..14f2aea 100644
--- a/tools/winscope/src/common/geometry_utils.ts
+++ b/tools/winscope/src/common/geometry_utils.ts
@@ -14,15 +14,7 @@
* limitations under the License.
*/
-export function isPointInRect(
- point: {x: number; y: number},
- rect: {
- x: number;
- y: number;
- w: number;
- h: number;
- }
-): boolean {
+export function isPointInRect(point: Point, rect: Rect): boolean {
return (
rect.x <= point.x &&
point.x <= rect.x + rect.w &&
@@ -30,3 +22,26 @@
point.y <= rect.y + rect.h
);
}
+
+export interface Point {
+ x: number;
+ y: number;
+}
+
+export interface Rect {
+ x: number;
+ y: number;
+ w: number;
+ h: number;
+}
+
+export interface TransformMatrix {
+ dsdx: number;
+ dtdx: number;
+ tx: number;
+ dsdy: number;
+ dtdy: number;
+ ty: number;
+}
+
+export const IDENTITY_MATRIX = {dsdx: 1, dtdx: 0, tx: 0, dsdy: 0, dtdy: 1, ty: 0};
diff --git a/tools/winscope/src/common/tree_utils.ts b/tools/winscope/src/common/tree_utils.ts
index f94dad9..5047551 100644
--- a/tools/winscope/src/common/tree_utils.ts
+++ b/tools/winscope/src/common/tree_utils.ts
@@ -14,16 +14,19 @@
* limitations under the License.
*/
-interface TreeNode {
+interface TreeUtilsNode {
name: string;
- parent?: TreeNode;
- children?: TreeNode[];
+ parent?: TreeUtilsNode;
+ children?: TreeUtilsNode[];
}
-type FilterType = (node: TreeNode | undefined | null) => boolean;
+type FilterType = (node: TreeUtilsNode | undefined | null) => boolean;
class TreeUtils {
- static findDescendantNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
+ static findDescendantNode(
+ node: TreeUtilsNode,
+ isTargetNode: FilterType
+ ): TreeUtilsNode | undefined {
if (isTargetNode(node)) {
return node;
}
@@ -42,7 +45,10 @@
return undefined;
}
- static findAncestorNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
+ static findAncestorNode(
+ node: TreeUtilsNode,
+ isTargetNode: FilterType
+ ): TreeUtilsNode | undefined {
let ancestor = node.parent;
while (ancestor && !isTargetNode(ancestor)) {
@@ -53,7 +59,7 @@
}
static makeNodeFilter(filterString: string): FilterType {
- const filter = (item: TreeNode | undefined | null) => {
+ const filter = (item: TreeUtilsNode | undefined | null) => {
if (item) {
const regex = new RegExp(filterString, 'i');
return filterString.length === 0 || regex.test(`${item.name}`);
@@ -64,4 +70,4 @@
}
}
-export {TreeNode, TreeUtils, FilterType};
+export {TreeUtilsNode, TreeUtils, FilterType};
diff --git a/tools/winscope/src/parsers/transform_utils.ts b/tools/winscope/src/parsers/transform_utils.ts
new file mode 100644
index 0000000..6a98c7e
--- /dev/null
+++ b/tools/winscope/src/parsers/transform_utils.ts
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {IDENTITY_MATRIX, TransformMatrix} from 'common/geometry_utils';
+
+export class Transform {
+ constructor(public type: TransformType, public matrix: TransformMatrix) {}
+}
+
+export enum TransformType {
+ EMPTY = 0x0,
+ TRANSLATE_VAL = 0x0001,
+ ROTATE_VAL = 0x0002,
+ SCALE_VAL = 0x0004,
+ FLIP_H_VAL = 0x0100,
+ FLIP_V_VAL = 0x0200,
+ ROT_90_VAL = 0x0400,
+ ROT_INVALID_VAL = 0x8000,
+}
+
+export const EMPTY_TRANSFORM = new Transform(TransformType.EMPTY, IDENTITY_MATRIX);
+
+export class TransformUtils {
+ static isValidTransform(transform: any): boolean {
+ if (!transform) return false;
+ return transform.dsdx * transform.dtdy !== transform.dtdx * transform.dsdy;
+ }
+
+ static getTransform(transform: any, position: any): Transform {
+ const transformType = transform?.type ?? 0;
+ const x = position?.x ?? 0;
+ const y = position?.y ?? 0;
+
+ if (!transform || TransformUtils.isSimpleTransform(transformType)) {
+ return TransformUtils.getDefaultTransform(transformType, x, y);
+ }
+
+ return new Transform(transformType, {
+ dsdx: transform?.matrix.dsdx ?? 0,
+ dtdx: transform?.matrix.dtdx ?? 0,
+ tx: x,
+ dsdy: transform?.matrix.dsdy ?? 0,
+ dtdy: transform?.matrix.dtdy ?? 0,
+ ty: y,
+ });
+ }
+
+ static isSimpleRotation(transform: any): boolean {
+ return !(transform?.type
+ ? TransformUtils.isFlagSet(transform.type, TransformType.ROT_INVALID_VAL)
+ : false);
+ }
+
+ private static getDefaultTransform(type: TransformType, x: number, y: number): Transform {
+ // IDENTITY
+ if (!type) {
+ return new Transform(type, {dsdx: 1, dtdx: 0, tx: x, dsdy: 0, dtdy: 1, ty: y});
+ }
+
+ // ROT_270 = ROT_90|FLIP_H|FLIP_V
+ if (
+ TransformUtils.isFlagSet(
+ type,
+ TransformType.ROT_90_VAL | TransformType.FLIP_V_VAL | TransformType.FLIP_H_VAL
+ )
+ ) {
+ return new Transform(type, {dsdx: 0, dtdx: -1, tx: x, dsdy: 1, dtdy: 0, ty: y});
+ }
+
+ // ROT_180 = FLIP_H|FLIP_V
+ if (TransformUtils.isFlagSet(type, TransformType.FLIP_V_VAL | TransformType.FLIP_H_VAL)) {
+ return new Transform(type, {dsdx: -1, dtdx: 0, tx: x, dsdy: 0, dtdy: -1, ty: y});
+ }
+
+ // ROT_90
+ if (TransformUtils.isFlagSet(type, TransformType.ROT_90_VAL)) {
+ return new Transform(type, {dsdx: 0, dtdx: 1, tx: x, dsdy: -1, dtdy: 0, ty: y});
+ }
+
+ // IDENTITY
+ if (TransformUtils.isFlagClear(type, TransformType.SCALE_VAL | TransformType.ROTATE_VAL)) {
+ return new Transform(type, {dsdx: 1, dtdx: 0, tx: x, dsdy: 0, dtdy: 1, ty: y});
+ }
+
+ throw new Error(`Unknown transform type ${type}`);
+ }
+
+ private static isFlagSet(type: number, bits: number): boolean {
+ type = type || 0;
+ return (type & bits) === bits;
+ }
+
+ private static isFlagClear(type: number, bits: number): boolean {
+ return (type & bits) === 0;
+ }
+
+ private static isSimpleTransform(type: number): boolean {
+ return TransformUtils.isFlagClear(
+ type,
+ TransformType.ROT_INVALID_VAL | TransformType.SCALE_VAL
+ );
+ }
+}
diff --git a/tools/winscope/src/trace/trace_data_utils.ts b/tools/winscope/src/trace/trace_data_utils.ts
new file mode 100644
index 0000000..273f427
--- /dev/null
+++ b/tools/winscope/src/trace/trace_data_utils.ts
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Rect} from 'common/geometry_utils';
+import {Transform} from 'parsers/transform_utils';
+
+/* DATA INTERFACES */
+class Item {
+ constructor(public id: string, public label: string) {}
+}
+
+class TreeNode<T> extends Item {
+ constructor(id: string, label: string, public children: Array<TreeNode<T> & T> = []) {
+ super(id, label);
+ }
+}
+
+class TraceRect extends Item implements Rect {
+ constructor(
+ id: string,
+ label: string,
+ public x: number,
+ public y: number,
+ public w: number,
+ public h: number,
+ public cornerRadius: number,
+ public transform: Transform,
+ public zAbs: number,
+ public groupId: number,
+ public isVisible: boolean,
+ public isDisplay: boolean,
+ public isVirtual: boolean
+ ) {
+ super(id, label);
+ }
+}
+
+type Proto = any;
+
+/* GET PROPERTIES TYPES */
+type GetPropertiesFromProtoType = (proto: Proto) => PropertyTreeNode;
+type GetPropertiesType = () => PropertyTreeNode;
+
+/* MIXINS */
+interface PropertiesGetter {
+ getProperties: GetPropertiesType;
+}
+
+enum PropertySource {
+ PROTO,
+ DEFAULT,
+ CALCULATED,
+}
+
+interface PropertyDetails {
+ value: string;
+ source: PropertySource;
+}
+
+interface AssociatedProperty {
+ property: null | PropertyDetails;
+}
+
+interface Constructor<T = {}> {
+ new (...args: any[]): T;
+}
+
+function mixin<T, U>(a: T, b: U): T & U {
+ const ret = {};
+ Object.assign(ret, a);
+ Object.assign(ret, b);
+ return ret as T & U;
+}
+
+type PropertyTreeNode = TreeNode<AssociatedProperty> & AssociatedProperty;
+type HierarchyTreeNode = TreeNode<PropertiesGetter> & PropertiesGetter;
+
+const EMPTY_OBJ_STRING = '{empty}';
+const EMPTY_ARRAY_STRING = '[empty]';
+
+export {
+ Item,
+ TreeNode,
+ TraceRect,
+ Proto,
+ GetPropertiesType,
+ GetPropertiesFromProtoType,
+ PropertiesGetter,
+ PropertySource,
+ PropertyDetails,
+ AssociatedProperty,
+ Constructor,
+ mixin,
+ PropertyTreeNode,
+ HierarchyTreeNode,
+ EMPTY_OBJ_STRING,
+ EMPTY_ARRAY_STRING,
+};
diff --git a/tools/winscope/src/trace/trace_type.ts b/tools/winscope/src/trace/trace_type.ts
index cd4081f..fff5de5 100644
--- a/tools/winscope/src/trace/trace_type.ts
+++ b/tools/winscope/src/trace/trace_type.ts
@@ -16,6 +16,7 @@
import {Cuj, Event, Transition} from 'flickerlib/common';
import {LayerTraceEntry} from 'flickerlib/layers/LayerTraceEntry';
import {WindowManagerState} from 'flickerlib/windows/WindowManagerState';
+import {HierarchyTreeNode, TraceRect, TreeNode} from 'trace/trace_data_utils';
import {LogMessage} from './protolog';
import {ScreenRecordingTraceEntry} from './screen_recording';
@@ -52,32 +53,46 @@
export type FrameData = any;
export type WindowData = any;
+export interface TreeAndRects {
+ tree: HierarchyTreeNode;
+ rects: TraceRect[];
+}
+
export interface TraceEntryTypeMap {
- [TraceType.PROTO_LOG]: LogMessage;
- [TraceType.SURFACE_FLINGER]: LayerTraceEntry;
- [TraceType.SCREEN_RECORDING]: ScreenRecordingTraceEntry;
- [TraceType.SYSTEM_UI]: object;
- [TraceType.TRANSACTIONS]: object;
- [TraceType.TRANSACTIONS_LEGACY]: object;
- [TraceType.WAYLAND]: object;
- [TraceType.WAYLAND_DUMP]: object;
- [TraceType.WINDOW_MANAGER]: WindowManagerState;
- [TraceType.INPUT_METHOD_CLIENTS]: object;
- [TraceType.INPUT_METHOD_MANAGER_SERVICE]: object;
- [TraceType.INPUT_METHOD_SERVICE]: object;
- [TraceType.EVENT_LOG]: Event;
- [TraceType.WM_TRANSITION]: object;
- [TraceType.SHELL_TRANSITION]: object;
- [TraceType.TRANSITION]: Transition;
- [TraceType.CUJS]: Cuj;
- [TraceType.TAG]: object;
- [TraceType.ERROR]: object;
- [TraceType.TEST_TRACE_STRING]: string;
- [TraceType.TEST_TRACE_NUMBER]: number;
- [TraceType.VIEW_CAPTURE]: object;
- [TraceType.VIEW_CAPTURE_LAUNCHER_ACTIVITY]: FrameData;
- [TraceType.VIEW_CAPTURE_TASKBAR_DRAG_LAYER]: FrameData;
- [TraceType.VIEW_CAPTURE_TASKBAR_OVERLAY_DRAG_LAYER]: FrameData;
+ [TraceType.PROTO_LOG]: {new: LogMessage; legacy: LogMessage};
+ [TraceType.SURFACE_FLINGER]: {new: TreeAndRects; legacy: LayerTraceEntry};
+ [TraceType.SCREEN_RECORDING]: {new: ScreenRecordingTraceEntry; legacy: ScreenRecordingTraceEntry};
+ [TraceType.SYSTEM_UI]: {new: object; legacy: object};
+ [TraceType.TRANSACTIONS]: {new: TreeNode<any>; legacy: object};
+ [TraceType.TRANSACTIONS_LEGACY]: {new: TreeNode<any>; legacy: object};
+ [TraceType.WAYLAND]: {new: object; legacy: object};
+ [TraceType.WAYLAND_DUMP]: {new: object; legacy: object};
+ [TraceType.WINDOW_MANAGER]: {new: TreeAndRects; legacy: WindowManagerState};
+ [TraceType.INPUT_METHOD_CLIENTS]: {new: TreeNode<any>; legacy: object};
+ [TraceType.INPUT_METHOD_MANAGER_SERVICE]: {new: TreeNode<any>; legacy: object};
+ [TraceType.INPUT_METHOD_SERVICE]: {new: TreeNode<any>; legacy: object};
+ [TraceType.EVENT_LOG]: {new: TreeNode<any>; legacy: Event};
+ [TraceType.WM_TRANSITION]: {new: TreeNode<any>; legacy: object};
+ [TraceType.SHELL_TRANSITION]: {new: TreeNode<any>; legacy: object};
+ [TraceType.TRANSITION]: {new: TreeNode<any>; legacy: Transition};
+ [TraceType.CUJS]: {new: TreeNode<any>; legacy: Cuj};
+ [TraceType.TAG]: {new: object; legacy: object};
+ [TraceType.ERROR]: {new: object; legacy: object};
+ [TraceType.TEST_TRACE_STRING]: {new: string; legacy: string};
+ [TraceType.TEST_TRACE_NUMBER]: {new: number; legacy: number};
+ [TraceType.VIEW_CAPTURE]: {new: TreeNode<any>; legacy: object};
+ [TraceType.VIEW_CAPTURE_LAUNCHER_ACTIVITY]: {
+ new: TreeAndRects;
+ legacy: FrameData;
+ };
+ [TraceType.VIEW_CAPTURE_TASKBAR_DRAG_LAYER]: {
+ new: TreeAndRects;
+ legacy: FrameData;
+ };
+ [TraceType.VIEW_CAPTURE_TASKBAR_OVERLAY_DRAG_LAYER]: {
+ new: TreeAndRects;
+ legacy: FrameData;
+ };
}
export class TraceTypeUtils {
diff --git a/tools/winscope/src/trace/traces.ts b/tools/winscope/src/trace/traces.ts
index 5161e7c..20f2cdd 100644
--- a/tools/winscope/src/trace/traces.ts
+++ b/tools/winscope/src/trace/traces.ts
@@ -22,12 +22,12 @@
export class Traces {
private traces = new Map<TraceType, Trace<{}>>();
- setTrace<T extends TraceType>(type: T, trace: Trace<TraceEntryTypeMap[T]>) {
+ setTrace<T extends TraceType>(type: T, trace: Trace<TraceEntryTypeMap[T]['legacy']>) {
this.traces.set(type, trace);
}
- getTrace<T extends TraceType>(type: T): Trace<TraceEntryTypeMap[T]> | undefined {
- return this.traces.get(type) as Trace<TraceEntryTypeMap[T]> | undefined;
+ getTrace<T extends TraceType>(type: T): Trace<TraceEntryTypeMap[T]['legacy']> | undefined {
+ return this.traces.get(type) as Trace<TraceEntryTypeMap[T]['legacy']> | undefined;
}
deleteTrace<T extends TraceType>(type: T) {
diff --git a/tools/winscope/src/viewers/common/surface_flinger_utils.ts b/tools/winscope/src/viewers/common/surface_flinger_utils.ts
index 413c585..1bca894 100644
--- a/tools/winscope/src/viewers/common/surface_flinger_utils.ts
+++ b/tools/winscope/src/viewers/common/surface_flinger_utils.ts
@@ -14,8 +14,9 @@
* limitations under the License.
*/
+import {TransformMatrix} from 'common/geometry_utils';
import {Layer, LayerTraceEntry} from 'flickerlib/common';
-import {Rectangle, TransformMatrix} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
import {UserOptions} from './user_options';
export class SurfaceFlingerUtils {
@@ -23,7 +24,7 @@
entry: LayerTraceEntry,
viewCapturePackageNames: string[],
hierarchyUserOptions: UserOptions
- ): Rectangle[] {
+ ): UiRect[] {
const layerRects = SurfaceFlingerUtils.makeLayerRects(
entry,
viewCapturePackageNames,
@@ -37,7 +38,7 @@
entry: LayerTraceEntry,
viewCapturePackageNames: string[],
hierarchyUserOptions: UserOptions
- ): Rectangle[] {
+ ): UiRect[] {
return entry.flattenedLayers
.filter((layer: Layer) => {
return SurfaceFlingerUtils.isLayerToRenderInRectsComponent(layer, hierarchyUserOptions);
@@ -45,9 +46,11 @@
.sort(SurfaceFlingerUtils.compareLayerZ)
.map((it: Layer) => {
const transform: TransformMatrix = it.rect.transform?.matrix ?? it.rect.transform;
- const rect: Rectangle = {
- topLeft: {x: it.rect.left, y: it.rect.top},
- bottomRight: {x: it.rect.right, y: it.rect.bottom},
+ const rect: UiRect = {
+ x: it.rect.left,
+ y: it.rect.top,
+ w: it.rect.right - it.rect.left,
+ h: it.rect.bottom - it.rect.top,
label: it.rect.label,
transform,
isVisible: it.isVisible,
@@ -65,16 +68,18 @@
});
}
- private static makeDisplayRects(entry: LayerTraceEntry): Rectangle[] {
+ private static makeDisplayRects(entry: LayerTraceEntry): UiRect[] {
if (!entry.displays) {
return [];
}
return entry.displays?.map((display: any) => {
const transform: TransformMatrix = display.transform?.matrix ?? display.transform;
- const rect: Rectangle = {
- topLeft: {x: 0, y: 0},
- bottomRight: {x: display.size.width, y: display.size.height},
+ const rect: UiRect = {
+ x: 0,
+ y: 0,
+ w: display.size.width,
+ h: display.size.height,
label: 'Display',
transform,
isVisible: false,
diff --git a/tools/winscope/src/viewers/common/tree_generator.ts b/tools/winscope/src/viewers/common/tree_generator.ts
index e5d2fc3..244353d 100644
--- a/tools/winscope/src/viewers/common/tree_generator.ts
+++ b/tools/winscope/src/viewers/common/tree_generator.ts
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {FilterType, TreeNode} from 'common/tree_utils';
+import {FilterType, TreeUtilsNode} from 'common/tree_utils';
import {ObjectFormatter} from 'flickerlib/ObjectFormatter';
import {TraceTreeNode} from 'trace/trace_tree_node';
import {
@@ -155,7 +155,7 @@
}
}
- private filterMatches(item?: TreeNode | null): boolean {
+ private filterMatches(item?: TreeUtilsNode | null): boolean {
return this.filter(item) ?? false;
}
diff --git a/tools/winscope/src/viewers/common/tree_transformer.ts b/tools/winscope/src/viewers/common/tree_transformer.ts
index 15b7640..86218bd 100644
--- a/tools/winscope/src/viewers/common/tree_transformer.ts
+++ b/tools/winscope/src/viewers/common/tree_transformer.ts
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {FilterType, TreeNode} from 'common/tree_utils';
+import {FilterType, TreeUtilsNode} from 'common/tree_utils';
import {ObjectFormatter} from 'flickerlib/ObjectFormatter';
import {TraceTreeNode} from 'trace/trace_tree_node';
@@ -343,7 +343,7 @@
private filterMatches(item: PropertiesDump | null): boolean {
//TODO: fix PropertiesDump type. What is it? Why does it declare only a "key" property and yet it is used as a TreeNode?
- return this.filter(item as TreeNode) ?? false;
+ return this.filter(item as TreeUtilsNode) ?? false;
}
private transformProperties(
diff --git a/tools/winscope/src/viewers/components/rects/canvas.ts b/tools/winscope/src/viewers/components/rects/canvas.ts
index b106768..e0436f8 100644
--- a/tools/winscope/src/viewers/components/rects/canvas.ts
+++ b/tools/winscope/src/viewers/components/rects/canvas.ts
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import {TransformMatrix} from 'common/geometry_utils';
import * as THREE from 'three';
import {CSS2DObject, CSS2DRenderer} from 'three/examples/jsm/renderers/CSS2DRenderer';
import {ViewerEvents} from 'viewers/common/viewer_events';
-import {Circle3D, ColorType, Label3D, Point3D, Rect3D, Scene3D, TransformMatrix} from './types3d';
+import {Circle3D, ColorType, Label3D, Point3D, Rect3D, Scene3D} from './types3d';
export class Canvas {
static readonly TARGET_SCENE_DIAGONAL = 4;
diff --git a/tools/winscope/src/viewers/components/rects/mapper3d.ts b/tools/winscope/src/viewers/components/rects/mapper3d.ts
index ad47dae..0643669 100644
--- a/tools/winscope/src/viewers/components/rects/mapper3d.ts
+++ b/tools/winscope/src/viewers/components/rects/mapper3d.ts
@@ -14,17 +14,9 @@
* limitations under the License.
*/
-import {Rectangle, Size} from 'viewers/components/rects/types2d';
-import {
- Box3D,
- ColorType,
- Distance2D,
- Label3D,
- Point3D,
- Rect3D,
- Scene3D,
- TransformMatrix,
-} from './types3d';
+import {IDENTITY_MATRIX, TransformMatrix} from 'common/geometry_utils';
+import {Size, UiRect} from 'viewers/components/rects/types2d';
+import {Box3D, ColorType, Distance2D, Label3D, Point3D, Rect3D, Scene3D} from './types3d';
class Mapper3D {
private static readonly CAMERA_ROTATION_FACTOR_INIT = 1;
@@ -38,16 +30,8 @@
private static readonly ZOOM_FACTOR_MIN = 0.1;
private static readonly ZOOM_FACTOR_MAX = 8.5;
private static readonly ZOOM_FACTOR_STEP = 0.2;
- private static readonly IDENTITY_TRANSFORM: TransformMatrix = {
- dsdx: 1,
- dsdy: 0,
- tx: 0,
- dtdx: 0,
- dtdy: 1,
- ty: 0,
- };
- private rects: Rectangle[] = [];
+ private rects: UiRect[] = [];
private highlightedRectId: string = '';
private cameraRotationFactor = Mapper3D.CAMERA_ROTATION_FACTOR_INIT;
private zSpacingFactor = Mapper3D.Z_SPACING_FACTOR_INIT;
@@ -57,7 +41,7 @@
private showVirtualMode = false; // by default don't show virtual displays
private currentDisplayId = 0; // default stack id is usually 0
- setRects(rects: Rectangle[]) {
+ setRects(rects: UiRect[]) {
this.rects = rects;
}
@@ -148,7 +132,7 @@
return scene;
}
- private selectRectsToDraw(rects: Rectangle[]): Rectangle[] {
+ private selectRectsToDraw(rects: UiRect[]): UiRect[] {
rects = rects.filter((rect) => rect.displayId === this.currentDisplayId);
if (this.showOnlyVisibleMode) {
@@ -162,7 +146,7 @@
return rects;
}
- private computeRects(rects2d: Rectangle[]): Rect3D[] {
+ private computeRects(rects2d: UiRect[]): Rect3D[] {
let visibleRectsSoFar = 0;
let visibleRectsTotal = 0;
let nonVisibleRectsSoFar = 0;
@@ -206,13 +190,13 @@
const rect = {
id: rect2d.id,
topLeft: {
- x: rect2d.topLeft.x,
- y: rect2d.topLeft.y,
+ x: rect2d.x,
+ y: rect2d.y,
z,
},
bottomRight: {
- x: rect2d.bottomRight.x,
- y: rect2d.bottomRight.y,
+ x: rect2d.x + rect2d.w,
+ y: rect2d.y + rect2d.h,
z,
},
isOversized: false,
@@ -220,7 +204,7 @@
darkFactor,
colorType: this.getColorType(rect2d),
isClickable: rect2d.isClickable,
- transform: rect2d.transform ?? Mapper3D.IDENTITY_TRANSFORM,
+ transform: rect2d.transform ?? IDENTITY_MATRIX,
};
return this.cropOversizedRect(rect, maxDisplaySize);
});
@@ -228,7 +212,7 @@
return rects3d;
}
- private getColorType(rect2d: Rectangle): ColorType {
+ private getColorType(rect2d: UiRect): ColorType {
let colorType: ColorType;
if (this.highlightedRectId === rect2d.id) {
colorType = ColorType.HIGHLIGHTED;
@@ -242,19 +226,15 @@
return colorType;
}
- private getMaxDisplaySize(rects2d: Rectangle[]): Size {
+ private getMaxDisplaySize(rects2d: UiRect[]): Size {
const displays = rects2d.filter((rect2d) => rect2d.isDisplay);
let maxWidth = 0;
let maxHeight = 0;
if (displays.length > 0) {
- maxWidth = Math.max(
- ...displays.map((rect2d): number => Math.abs(rect2d.topLeft.x - rect2d.bottomRight.x))
- );
+ maxWidth = Math.max(...displays.map((rect2d): number => Math.abs(rect2d.w)));
- maxHeight = Math.max(
- ...displays.map((rect2d): number => Math.abs(rect2d.topLeft.y - rect2d.bottomRight.y))
- );
+ maxHeight = Math.max(...displays.map((rect2d): number => Math.abs(rect2d.h)));
}
return {
width: maxWidth,
@@ -286,7 +266,7 @@
return rect3d;
}
- private computeLabels(rects2d: Rectangle[], rects3d: Rect3D[]): Label3D[] {
+ private computeLabels(rects2d: UiRect[], rects3d: Rect3D[]): Label3D[] {
const labels3d: Label3D[] = [];
let labelY =
@@ -305,12 +285,12 @@
const bottomLeft: Point3D = {
x: rect3d.topLeft.x,
- y: rect3d.bottomRight.y,
+ y: rect3d.topLeft.y,
z: rect3d.topLeft.z,
};
const topRight: Point3D = {
x: rect3d.bottomRight.x,
- y: rect3d.topLeft.y,
+ y: rect3d.bottomRight.y,
z: rect3d.bottomRight.z,
};
const lineStarts = [
diff --git a/tools/winscope/src/viewers/components/rects/rects_component.ts b/tools/winscope/src/viewers/components/rects/rects_component.ts
index 0c43ad5..4781592 100644
--- a/tools/winscope/src/viewers/components/rects/rects_component.ts
+++ b/tools/winscope/src/viewers/components/rects/rects_component.ts
@@ -15,7 +15,7 @@
*/
import {Component, ElementRef, HostListener, Inject, Input, OnDestroy, OnInit} from '@angular/core';
import {RectDblClickDetail, ViewerEvents} from 'viewers/common/viewer_events';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
import {Canvas} from './canvas';
import {Mapper3D} from './mapper3d';
import {Distance2D} from './types3d';
@@ -185,11 +185,11 @@
@Input() title = 'title';
@Input() enableShowVirtualButton: boolean = true;
@Input() zoomFactor: number = 1;
- @Input() set rects(rects: Rectangle[]) {
+ @Input() set rects(rects: UiRect[]) {
this.internalRects = rects;
this.drawLargeRectsAndLabels();
}
- @Input() set miniRects(rects: Rectangle[] | undefined) {
+ @Input() set miniRects(rects: UiRect[] | undefined) {
this.internalMiniRects = rects;
this.drawMiniRects();
}
@@ -208,8 +208,8 @@
this.drawLargeRectsAndLabels();
}
- private internalRects: Rectangle[] = [];
- private internalMiniRects?: Rectangle[];
+ private internalRects: UiRect[] = [];
+ private internalMiniRects?: UiRect[];
private internalDisplayIds: number[] = [];
private internalHighlightedItem: string = '';
diff --git a/tools/winscope/src/viewers/components/rects/rects_component_test.ts b/tools/winscope/src/viewers/components/rects/rects_component_test.ts
index feda1dd..09e87ef 100644
--- a/tools/winscope/src/viewers/components/rects/rects_component_test.ts
+++ b/tools/winscope/src/viewers/components/rects/rects_component_test.ts
@@ -21,7 +21,7 @@
import {MatRadioModule} from '@angular/material/radio';
import {MatSliderModule} from '@angular/material/slider';
import {RectsComponent} from 'viewers/components/rects/rects_component';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
import {Canvas} from './canvas';
describe('RectsComponent', () => {
@@ -64,9 +64,11 @@
it('draws scene when input data changes', async () => {
spyOn(Canvas.prototype, 'draw').and.callThrough();
- const inputRect: Rectangle = {
- topLeft: {x: 0, y: 0},
- bottomRight: {x: 1, y: -1},
+ const inputRect: UiRect = {
+ x: 0,
+ y: 0,
+ w: 1,
+ h: 1,
label: 'rectangle1',
transform: {
dsdx: 1,
diff --git a/tools/winscope/src/viewers/components/rects/types2d.ts b/tools/winscope/src/viewers/components/rects/types2d.ts
index badb59c..fe34955 100644
--- a/tools/winscope/src/viewers/components/rects/types2d.ts
+++ b/tools/winscope/src/viewers/components/rects/types2d.ts
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-export interface Rectangle {
- topLeft: Point;
- bottomRight: Point;
+import {Rect, TransformMatrix} from 'common/geometry_utils';
+
+export interface UiRect extends Rect {
label: string;
transform?: TransformMatrix;
isVisible: boolean;
@@ -30,21 +30,7 @@
hasContent?: boolean;
}
-export interface Point {
- x: number;
- y: number;
-}
-
export interface Size {
width: number;
height: number;
}
-
-export interface TransformMatrix {
- dsdx: number;
- dsdy: number;
- dtdx: number;
- dtdy: number;
- tx: number;
- ty: number;
-}
diff --git a/tools/winscope/src/viewers/components/rects/types3d.ts b/tools/winscope/src/viewers/components/rects/types3d.ts
index efb239c..fa06e00 100644
--- a/tools/winscope/src/viewers/components/rects/types3d.ts
+++ b/tools/winscope/src/viewers/components/rects/types3d.ts
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-import {TransformMatrix} from 'viewers/components/rects/types2d';
-
-export {TransformMatrix};
+import {TransformMatrix} from 'common/geometry_utils';
export enum ColorType {
VISIBLE,
diff --git a/tools/winscope/src/viewers/viewer_surface_flinger/presenter_test.ts b/tools/winscope/src/viewers/viewer_surface_flinger/presenter_test.ts
index 5b3627e..0264ad8 100644
--- a/tools/winscope/src/viewers/viewer_surface_flinger/presenter_test.ts
+++ b/tools/winscope/src/viewers/viewer_surface_flinger/presenter_test.ts
@@ -107,8 +107,10 @@
it('creates input data for rects view', async () => {
await presenter.onAppEvent(positionUpdate);
expect(uiData.rects.length).toBeGreaterThan(0);
- expect(uiData.rects[0].topLeft).toEqual({x: 0, y: 0});
- expect(uiData.rects[0].bottomRight).toEqual({x: 1080, y: 74});
+ expect(uiData.rects[0].x).toEqual(0);
+ expect(uiData.rects[0].y).toEqual(0);
+ expect(uiData.rects[0].w).toEqual(1080);
+ expect(uiData.rects[0].h).toEqual(74);
});
it('updates pinned items', () => {
diff --git a/tools/winscope/src/viewers/viewer_surface_flinger/ui_data.ts b/tools/winscope/src/viewers/viewer_surface_flinger/ui_data.ts
index bc65e63..36fe0ae 100644
--- a/tools/winscope/src/viewers/viewer_surface_flinger/ui_data.ts
+++ b/tools/winscope/src/viewers/viewer_surface_flinger/ui_data.ts
@@ -17,11 +17,11 @@
import {TraceType} from 'trace/trace_type';
import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_utils';
import {UserOptions} from 'viewers/common/user_options';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
export class UiData {
dependencies: TraceType[];
- rects: Rectangle[] = [];
+ rects: UiRect[] = [];
displayIds: number[] = [];
highlightedItem: string = '';
highlightedProperty: string = '';
diff --git a/tools/winscope/src/viewers/viewer_view_capture/presenter.ts b/tools/winscope/src/viewers/viewer_view_capture/presenter.ts
index a21287e..579f626 100644
--- a/tools/winscope/src/viewers/viewer_view_capture/presenter.ts
+++ b/tools/winscope/src/viewers/viewer_view_capture/presenter.ts
@@ -28,7 +28,7 @@
import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_utils';
import {UserOptions} from 'viewers/common/user_options';
import {ViewCaptureUtils} from 'viewers/common/view_capture_utils';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
import {UiData} from './ui_data';
export class Presenter {
@@ -153,7 +153,7 @@
}
this.uiData = new UiData(
- this.generateViewCaptureRectangles(),
+ this.generateViewCaptureUiRects(),
this.uiData?.sfRects,
tree,
this.hierarchyUserOptions,
@@ -167,19 +167,15 @@
this.notifyUiDataCallback(this.uiData);
}
- private generateViewCaptureRectangles(): Rectangle[] {
- const rectangles: Rectangle[] = [];
+ private generateViewCaptureUiRects(): UiRect[] {
+ const rectangles: UiRect[] = [];
function inner(node: any /* ViewNode */) {
- const aRectangle: Rectangle = {
- topLeft: {
- x: node.boxPos.left,
- y: node.boxPos.top,
- },
- bottomRight: {
- x: node.boxPos.left + node.boxPos.width,
- y: node.boxPos.top + node.boxPos.height,
- },
+ const aUiRect: UiRect = {
+ x: node.boxPos.left,
+ y: node.boxPos.top,
+ w: node.boxPos.width,
+ h: node.boxPos.height,
label: '',
transform: undefined,
isVisible: node.isVisible,
@@ -192,7 +188,7 @@
depth: node.depth,
hasContent: node.isVisible,
};
- rectangles.push(aRectangle);
+ rectangles.push(aUiRect);
node.children.forEach((it: any) /* ViewNode */ => inner(it));
}
if (this.selectedFrameData?.node) {
diff --git a/tools/winscope/src/viewers/viewer_view_capture/presenter_test.ts b/tools/winscope/src/viewers/viewer_view_capture/presenter_test.ts
index bdf9bd4..a57f9b5 100644
--- a/tools/winscope/src/viewers/viewer_view_capture/presenter_test.ts
+++ b/tools/winscope/src/viewers/viewer_view_capture/presenter_test.ts
@@ -91,8 +91,10 @@
it('creates input data for rects view', async () => {
await presenter.onAppEvent(positionUpdate);
expect(uiData.rects.length).toBeGreaterThan(0);
- expect(uiData.rects[0].topLeft).toEqual({x: 0, y: 0});
- expect(uiData.rects[0].bottomRight).toEqual({x: 1080, y: 249});
+ expect(uiData.rects[0].x).toEqual(0);
+ expect(uiData.rects[0].y).toEqual(0);
+ expect(uiData.rects[0].w).toEqual(1080);
+ expect(uiData.rects[0].h).toEqual(249);
});
it('updates pinned items', async () => {
diff --git a/tools/winscope/src/viewers/viewer_view_capture/ui_data.ts b/tools/winscope/src/viewers/viewer_view_capture/ui_data.ts
index 744f6ea..2b39050 100644
--- a/tools/winscope/src/viewers/viewer_view_capture/ui_data.ts
+++ b/tools/winscope/src/viewers/viewer_view_capture/ui_data.ts
@@ -17,15 +17,15 @@
import {TraceType, ViewNode} from 'trace/trace_type';
import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_utils';
import {UserOptions} from 'viewers/common/user_options';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
export class UiData {
readonly dependencies: TraceType[] = [TraceType.VIEW_CAPTURE];
readonly displayPropertyGroups = false;
constructor(
- readonly rects: Rectangle[],
- public sfRects: Rectangle[] | undefined,
+ readonly rects: UiRect[],
+ public sfRects: UiRect[] | undefined,
public tree: HierarchyTreeNode | null,
public hierarchyUserOptions: UserOptions,
public propertiesUserOptions: UserOptions,
diff --git a/tools/winscope/src/viewers/viewer_window_manager/presenter.ts b/tools/winscope/src/viewers/viewer_window_manager/presenter.ts
index ffed296..4ac0faa 100644
--- a/tools/winscope/src/viewers/viewer_window_manager/presenter.ts
+++ b/tools/winscope/src/viewers/viewer_window_manager/presenter.ts
@@ -16,6 +16,7 @@
import {AppEvent, AppEventType} from 'app/app_event';
import {assertDefined} from 'common/assert_utils';
+import {TransformMatrix} from 'common/geometry_utils';
import {PersistentStoreProxy} from 'common/persistent_store_proxy';
import {FilterType, TreeUtils} from 'common/tree_utils';
import {DisplayContent} from 'flickerlib/windows/DisplayContent';
@@ -29,7 +30,7 @@
import {TreeTransformer} from 'viewers/common/tree_transformer';
import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_utils';
import {UserOptions} from 'viewers/common/user_options';
-import {Rectangle, TransformMatrix} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
import {UiData} from './ui_data';
type NotifyViewCallbackType = (uiData: UiData) => void;
@@ -194,7 +195,7 @@
});
}
- private generateRects(entry: TraceTreeNode): Rectangle[] {
+ private generateRects(entry: TraceTreeNode): UiRect[] {
const identityMatrix: TransformMatrix = {
dsdx: 1,
dsdy: 0,
@@ -203,11 +204,13 @@
dtdy: 1,
ty: 0,
};
- const displayRects: Rectangle[] =
+ const displayRects: UiRect[] =
entry.displays?.map((display: DisplayContent) => {
- const rect: Rectangle = {
- topLeft: {x: display.displayRect.left, y: display.displayRect.top},
- bottomRight: {x: display.displayRect.right, y: display.displayRect.bottom},
+ const rect: UiRect = {
+ x: display.displayRect.left,
+ y: display.displayRect.top,
+ w: display.displayRect.right - display.displayRect.left,
+ h: display.displayRect.bottom - display.displayRect.top,
label: `Display - ${display.title}`,
transform: identityMatrix,
isVisible: false, //TODO: check if displayRect.ref.isVisible exists
@@ -221,13 +224,15 @@
return rect;
}) ?? [];
- const windowRects: Rectangle[] =
+ const windowRects: UiRect[] =
entry.windowStates
?.sort((a: any, b: any) => b.computedZ - a.computedZ)
.map((it: any) => {
- const rect: Rectangle = {
- topLeft: {x: it.rect.left, y: it.rect.top},
- bottomRight: {x: it.rect.right, y: it.rect.bottom},
+ const rect: UiRect = {
+ x: it.rect.left,
+ y: it.rect.top,
+ w: it.rect.right - it.rect.left,
+ h: it.rect.bottom - it.rect.top,
label: it.rect.label,
transform: identityMatrix,
isVisible: it.isVisible,
diff --git a/tools/winscope/src/viewers/viewer_window_manager/presenter_test.ts b/tools/winscope/src/viewers/viewer_window_manager/presenter_test.ts
index aecc7e5..4ed8f0f 100644
--- a/tools/winscope/src/viewers/viewer_window_manager/presenter_test.ts
+++ b/tools/winscope/src/viewers/viewer_window_manager/presenter_test.ts
@@ -113,8 +113,10 @@
it('creates input data for rects view', async () => {
await presenter.onAppEvent(positionUpdate);
expect(uiData.rects.length).toBeGreaterThan(0);
- expect(uiData.rects[0].topLeft).toEqual({x: 0, y: 2326});
- expect(uiData.rects[0].bottomRight).toEqual({x: 1080, y: 2400});
+ expect(uiData.rects[0].x).toEqual(0);
+ expect(uiData.rects[0].y).toEqual(2326);
+ expect(uiData.rects[0].w).toEqual(1080);
+ expect(uiData.rects[0].h).toEqual(74);
});
it('updates pinned items', async () => {
diff --git a/tools/winscope/src/viewers/viewer_window_manager/ui_data.ts b/tools/winscope/src/viewers/viewer_window_manager/ui_data.ts
index ee9ad3c..320615e 100644
--- a/tools/winscope/src/viewers/viewer_window_manager/ui_data.ts
+++ b/tools/winscope/src/viewers/viewer_window_manager/ui_data.ts
@@ -16,11 +16,11 @@
import {TraceType} from 'trace/trace_type';
import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_utils';
import {UserOptions} from 'viewers/common/user_options';
-import {Rectangle} from 'viewers/components/rects/types2d';
+import {UiRect} from 'viewers/components/rects/types2d';
export class UiData {
dependencies: TraceType[];
- rects: Rectangle[] = [];
+ rects: UiRect[] = [];
displayIds: number[] = [];
highlightedItem: string = '';
highlightedProperty: string = '';