Fix tslint errors
Test: npm run build:all && npm run test:all Change-Id: I0eb35399afc4156b93a9b1d5213c70c4baa63316
This commit is contained in:
@@ -138,13 +138,13 @@ export class AdbProxyComponent {
|
||||
readonly downloadProxyUrl: string =
|
||||
'https://android.googlesource.com/platform/development/+/master/tools/winscope/adb_proxy/winscope_proxy.py';
|
||||
|
||||
public restart() {
|
||||
restart() {
|
||||
this.addKey.emit(this.proxyKeyItem);
|
||||
this.proxy.setState(this.states.CONNECTING);
|
||||
this.proxyChange.emit(this.proxy);
|
||||
}
|
||||
|
||||
public downloadFromAosp() {
|
||||
downloadFromAosp() {
|
||||
window.open(this.downloadProxyUrl, '_blank')?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ export class AppComponent implements TraceDataListener {
|
||||
|
||||
const storeDarkMode = this.store.get('dark-mode');
|
||||
const prefersDarkQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
|
||||
this.setDarkMode(storeDarkMode != null ? storeDarkMode == 'true' : prefersDarkQuery.matches);
|
||||
this.setDarkMode(storeDarkMode ? storeDarkMode === 'true' : prefersDarkQuery.matches);
|
||||
|
||||
if (!customElements.get('viewer-input-method')) {
|
||||
customElements.define(
|
||||
@@ -283,19 +283,19 @@ export class AppComponent implements TraceDataListener {
|
||||
return this.timelineData.getScreenRecordingVideo();
|
||||
}
|
||||
|
||||
public onTraceDataLoaded(viewers: Viewer[]) {
|
||||
onTraceDataLoaded(viewers: Viewer[]) {
|
||||
this.viewers = viewers;
|
||||
this.dataLoaded = true;
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
public onTraceDataUnloaded() {
|
||||
onTraceDataUnloaded() {
|
||||
proxyClient.adbData = [];
|
||||
this.dataLoaded = false;
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
public setDarkMode(enabled: boolean) {
|
||||
setDarkMode(enabled: boolean) {
|
||||
document.body.classList.toggle('dark-mode', enabled);
|
||||
this.store.add('dark-mode', `${enabled}`);
|
||||
this.isDarkModeOn = enabled;
|
||||
|
||||
@@ -114,7 +114,7 @@ export class MatDrawer {
|
||||
@Input() mode: 'push' | 'overlay' = 'overlay';
|
||||
@Input() baseHeight = 0;
|
||||
|
||||
public getBaseHeight() {
|
||||
getBaseHeight() {
|
||||
return this.baseHeight;
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ export class MatDrawerContent /*extends MatDrawerContentBase*/ {
|
||||
});
|
||||
}
|
||||
|
||||
public setMargins(margins: {top: number | null; bottom: number | null}) {
|
||||
setMargins(margins: {top: number | null; bottom: number | null}) {
|
||||
this.contentMargins = margins;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
|
||||
import {CanvasMouseHandler} from './canvas_mouse_handler';
|
||||
|
||||
export type padding = {left: number; top: number; right: number; bottom: number};
|
||||
export interface Padding {
|
||||
left: number;
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
}
|
||||
|
||||
export interface CanvasDrawer {
|
||||
draw(): void;
|
||||
handler: CanvasMouseHandler;
|
||||
canvas: HTMLCanvasElement;
|
||||
ctx: CanvasRenderingContext2D;
|
||||
padding: padding;
|
||||
padding: Padding;
|
||||
getXScale(): number;
|
||||
getYScale(): number;
|
||||
getWidth(): number;
|
||||
|
||||
@@ -22,7 +22,7 @@ export type DropListener = DragListener;
|
||||
|
||||
export class CanvasMouseHandler {
|
||||
// Ordered top most element to bottom most
|
||||
private draggableObjects = new Array<DraggableCanvasObject>();
|
||||
private draggableObjects: DraggableCanvasObject[] = [];
|
||||
private draggingObject: DraggableCanvasObject | undefined = undefined;
|
||||
|
||||
private onDrag = new Map<DraggableCanvasObject, DragListener>();
|
||||
@@ -47,7 +47,7 @@ export class CanvasMouseHandler {
|
||||
});
|
||||
}
|
||||
|
||||
public registerDraggableObject(
|
||||
registerDraggableObject(
|
||||
draggableObject: DraggableCanvasObject,
|
||||
onDrag: DragListener,
|
||||
onDrop: DropListener
|
||||
@@ -56,7 +56,7 @@ export class CanvasMouseHandler {
|
||||
this.onDrop.set(draggableObject, onDrop);
|
||||
}
|
||||
|
||||
public notifyDrawnOnTop(draggableObject: DraggableCanvasObject) {
|
||||
notifyDrawnOnTop(draggableObject: DraggableCanvasObject) {
|
||||
const foundIndex = this.draggableObjects.indexOf(draggableObject);
|
||||
if (foundIndex !== -1) {
|
||||
this.draggableObjects.splice(foundIndex, 1);
|
||||
|
||||
@@ -18,10 +18,10 @@ import {MathUtils} from 'three/src/Three';
|
||||
import {Segment} from '../timeline/utils';
|
||||
import {CanvasDrawer} from './canvas_drawer';
|
||||
|
||||
export type drawConfig = {
|
||||
export interface DrawConfig {
|
||||
fillStyle: string;
|
||||
fill: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export class DraggableCanvasObject {
|
||||
private draggingPosition: number | undefined;
|
||||
@@ -30,7 +30,7 @@ export class DraggableCanvasObject {
|
||||
private drawer: CanvasDrawer,
|
||||
private positionGetter: () => number,
|
||||
private definePathFunc: (ctx: CanvasRenderingContext2D, position: number) => void,
|
||||
private drawConfig: drawConfig,
|
||||
private drawConfig: DrawConfig,
|
||||
private onDrag: (x: number) => void,
|
||||
private onDrop: (x: number) => void,
|
||||
private rangeGetter: () => Segment
|
||||
@@ -58,11 +58,11 @@ export class DraggableCanvasObject {
|
||||
return this.draggingPosition !== undefined ? this.draggingPosition : this.positionGetter();
|
||||
}
|
||||
|
||||
public definePath(ctx: CanvasRenderingContext2D) {
|
||||
definePath(ctx: CanvasRenderingContext2D) {
|
||||
this.definePathFunc(ctx, this.position);
|
||||
}
|
||||
|
||||
public draw(ctx: CanvasRenderingContext2D) {
|
||||
draw(ctx: CanvasRenderingContext2D) {
|
||||
this.doDraw(ctx);
|
||||
this.drawer.handler.notifyDrawnOnTop(this);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import {Connection} from 'trace_collection/connection';
|
||||
import {ProxyState} from 'trace_collection/proxy_client';
|
||||
import {ProxyConnection} from 'trace_collection/proxy_connection';
|
||||
import {
|
||||
configMap,
|
||||
ConfigMap,
|
||||
EnableConfiguration,
|
||||
SelectionConfiguration,
|
||||
traceConfigurations,
|
||||
@@ -406,14 +406,14 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
this.connect.proxy?.removeOnProxyChange(this.onProxyChange);
|
||||
}
|
||||
|
||||
public onAddKey(key: string) {
|
||||
onAddKey(key: string) {
|
||||
if (this.connect.setProxyKey) {
|
||||
this.connect.setProxyKey(key);
|
||||
}
|
||||
this.connect.restart();
|
||||
}
|
||||
|
||||
public displayAdbProxyTab() {
|
||||
displayAdbProxyTab() {
|
||||
this.isAdbProxy = true;
|
||||
this.connect = new ProxyConnection(
|
||||
(newState) => this.changeDetectorRef.detectChanges(),
|
||||
@@ -421,7 +421,7 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
public displayWebAdbTab() {
|
||||
displayWebAdbTab() {
|
||||
this.isAdbProxy = false;
|
||||
//TODO: change to WebAdbConnection
|
||||
this.connect = new ProxyConnection(
|
||||
@@ -430,7 +430,7 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
public startTracing() {
|
||||
startTracing() {
|
||||
console.log('begin tracing');
|
||||
this.tracingConfig.requestedTraces = this.requestedTraces();
|
||||
const reqEnableConfig = this.requestedEnableConfig();
|
||||
@@ -443,7 +443,7 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
this.connect.startTrace(reqEnableConfig, reqSelectedSfConfig, reqSelectedWmConfig);
|
||||
}
|
||||
|
||||
public async dumpState() {
|
||||
async dumpState() {
|
||||
console.log('begin dump');
|
||||
this.tracingConfig.requestedDumps = this.requestedDumps();
|
||||
const dumpSuccessful = await this.connect.dumpState();
|
||||
@@ -454,13 +454,13 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public async endTrace() {
|
||||
async endTrace() {
|
||||
console.log('end tracing');
|
||||
await this.connect.endTrace();
|
||||
await this.loadFiles();
|
||||
}
|
||||
|
||||
public tabClass(adbTab: boolean) {
|
||||
tabClass(adbTab: boolean) {
|
||||
let isActive: string;
|
||||
if (adbTab) {
|
||||
isActive = this.isAdbProxy ? 'active' : 'inactive';
|
||||
@@ -475,7 +475,7 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private requestedTraces() {
|
||||
const tracesFromCollection: Array<string> = [];
|
||||
const tracesFromCollection: string[] = [];
|
||||
const tracingConfig = this.tracingConfig.getTracingConfig();
|
||||
const req = Object.keys(tracingConfig).filter((traceKey: string) => {
|
||||
const traceConfig = tracingConfig[traceKey];
|
||||
@@ -499,8 +499,8 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private requestedEnableConfig(): Array<string> {
|
||||
const req: Array<string> = [];
|
||||
private requestedEnableConfig(): string[] {
|
||||
const req: string[] = [];
|
||||
const tracingConfig = this.tracingConfig.getTracingConfig();
|
||||
Object.keys(tracingConfig).forEach((traceKey: string) => {
|
||||
const trace = tracingConfig[traceKey];
|
||||
@@ -515,12 +515,12 @@ export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
return req;
|
||||
}
|
||||
|
||||
private requestedSelection(traceType: string): configMap | undefined {
|
||||
private requestedSelection(traceType: string): ConfigMap | undefined {
|
||||
const tracingConfig = this.tracingConfig.getTracingConfig();
|
||||
if (!tracingConfig[traceType].run) {
|
||||
return undefined;
|
||||
}
|
||||
const selected: configMap = {};
|
||||
const selected: ConfigMap = {};
|
||||
tracingConfig[traceType].config?.selectionConfigs.forEach((con: SelectionConfiguration) => {
|
||||
selected[con.key] = con.value;
|
||||
});
|
||||
|
||||
@@ -49,7 +49,7 @@ export class ParserErrorSnackBarComponent {
|
||||
) {}
|
||||
|
||||
static showIfNeeded(ngZone: NgZone, snackBar: MatSnackBar, errors: ParserError[]) {
|
||||
const messages = this.convertErrorsToMessages(errors);
|
||||
const messages = ParserErrorSnackBarComponent.convertErrorsToMessages(errors);
|
||||
|
||||
if (messages.length === 0) {
|
||||
return;
|
||||
@@ -67,7 +67,7 @@ export class ParserErrorSnackBarComponent {
|
||||
|
||||
private static convertErrorsToMessages(errors: ParserError[]): string[] {
|
||||
const messages: string[] = [];
|
||||
const groups = this.groupErrorsByType(errors);
|
||||
const groups = ParserErrorSnackBarComponent.groupErrorsByType(errors);
|
||||
|
||||
for (const [type, groupedErrors] of groups) {
|
||||
const CROP_THRESHOLD = 5;
|
||||
@@ -75,11 +75,11 @@ export class ParserErrorSnackBarComponent {
|
||||
const countCropped = groupedErrors.length - countUsed;
|
||||
|
||||
groupedErrors.slice(0, countUsed).forEach((error) => {
|
||||
messages.push(this.convertErrorToMessage(error));
|
||||
messages.push(ParserErrorSnackBarComponent.convertErrorToMessage(error));
|
||||
});
|
||||
|
||||
if (countCropped > 0) {
|
||||
messages.push(this.makeCroppedMessage(type, countCropped));
|
||||
messages.push(ParserErrorSnackBarComponent.makeCroppedMessage(type, countCropped));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export class MiniCanvasDrawerInput {
|
||||
public timelineEntries: TimelineData
|
||||
) {}
|
||||
|
||||
public transform(mapToRange: Segment): MiniCanvasDrawerData {
|
||||
transform(mapToRange: Segment): MiniCanvasDrawerData {
|
||||
const transformer = new Transformer(this.fullRange, mapToRange);
|
||||
return new MiniCanvasDrawerData(
|
||||
transformer.transform(this.selectedPosition),
|
||||
@@ -74,13 +74,13 @@ export class Transformer {
|
||||
this.toOffset = Math.round(this.toRange.from);
|
||||
}
|
||||
|
||||
public transform(x: bigint): number {
|
||||
transform(x: bigint): number {
|
||||
return (
|
||||
this.toOffset + (this.targetWidth * Number(x - this.fromOffset)) / Number(this.fromWidth)
|
||||
);
|
||||
}
|
||||
|
||||
public untransform(x: number): bigint {
|
||||
untransform(x: number): bigint {
|
||||
x = Math.round(x);
|
||||
return (
|
||||
this.fromOffset + (BigInt(x - this.toOffset) * this.fromWidth) / BigInt(this.targetWidth)
|
||||
@@ -100,7 +100,7 @@ class MiniCanvasDrawerData {
|
||||
public transformer: Transformer
|
||||
) {}
|
||||
|
||||
public toOutput(): MiniCanvasDrawerOutput {
|
||||
toOutput(): MiniCanvasDrawerOutput {
|
||||
return new MiniCanvasDrawerOutput(this.transformer.untransform(this.selectedPosition), {
|
||||
from: this.transformer.untransform(this.selection.from),
|
||||
to: this.transformer.untransform(this.selection.to),
|
||||
@@ -109,8 +109,8 @@ class MiniCanvasDrawerData {
|
||||
}
|
||||
|
||||
export class MiniCanvasDrawer implements CanvasDrawer {
|
||||
public ctx: CanvasRenderingContext2D;
|
||||
public handler: CanvasMouseHandler;
|
||||
ctx: CanvasRenderingContext2D;
|
||||
handler: CanvasMouseHandler;
|
||||
|
||||
private activePointer: DraggableCanvasObject;
|
||||
private leftFocusSectionSelector: DraggableCanvasObject;
|
||||
@@ -120,19 +120,19 @@ export class MiniCanvasDrawer implements CanvasDrawer {
|
||||
return this.getHeight() / 6;
|
||||
}
|
||||
|
||||
public getXScale() {
|
||||
getXScale() {
|
||||
return this.ctx.getTransform().m11;
|
||||
}
|
||||
|
||||
public getYScale() {
|
||||
getYScale() {
|
||||
return this.ctx.getTransform().m22;
|
||||
}
|
||||
|
||||
public getWidth() {
|
||||
getWidth() {
|
||||
return this.canvas.width / this.getXScale();
|
||||
}
|
||||
|
||||
public getHeight() {
|
||||
getHeight() {
|
||||
return this.canvas.height / this.getYScale();
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ export class MiniCanvasDrawer implements CanvasDrawer {
|
||||
return this.getHeight() - this.padding.top - this.padding.bottom;
|
||||
}
|
||||
|
||||
public draw() {
|
||||
draw() {
|
||||
this.ctx.clearRect(0, 0, this.getWidth(), this.getHeight());
|
||||
|
||||
this.drawSelectionBackground();
|
||||
@@ -387,7 +387,7 @@ export class MiniCanvasDrawer implements CanvasDrawer {
|
||||
const spacing = (this.getWidth() - barSets * barsInSetWidth - edgeBarWidth) / bars;
|
||||
let start = edgeBarWidth + spacing;
|
||||
for (let i = 1; i < bars; i++) {
|
||||
if (i % 10 == 0) {
|
||||
if (i % 10 === 0) {
|
||||
// Draw boldbar
|
||||
this.ctx.fillStyle = Color.GUIDE_BAR;
|
||||
this.ctx.fillRect(
|
||||
|
||||
@@ -113,7 +113,7 @@ export class MiniTimelineComponent {
|
||||
}
|
||||
|
||||
private getTimelinesToShow() {
|
||||
const timelines = new Map<TraceType, bigint[]>();
|
||||
const timelines = new Map<TraceType, Array<bigint>>();
|
||||
for (const type of this.selectedTraces) {
|
||||
timelines.set(
|
||||
type,
|
||||
|
||||
@@ -48,7 +48,7 @@ export class SingleTimelineComponent {
|
||||
@Input() color = '#AF5CF7';
|
||||
@Input() start!: bigint;
|
||||
@Input() end!: bigint;
|
||||
@Input() entries!: bigint[];
|
||||
@Input() entries!: Array<bigint>;
|
||||
|
||||
@Output() onTimestampChanged = new EventEmitter<bigint>();
|
||||
|
||||
@@ -74,7 +74,7 @@ export class SingleTimelineComponent {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.start == undefined || this.end == undefined || this.entries == undefined) {
|
||||
if (this.start === undefined || this.end === undefined || this.entries === undefined) {
|
||||
throw Error('Not all required inputs have been set');
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export class SingleTimelineComponent {
|
||||
this.initializeCanvas();
|
||||
}
|
||||
|
||||
public initializeCanvas() {
|
||||
initializeCanvas() {
|
||||
// Reset any size before computing new size to avoid it interfering with size computations
|
||||
this.canvas.width = 0;
|
||||
this.canvas.height = 0;
|
||||
@@ -96,7 +96,9 @@ export class SingleTimelineComponent {
|
||||
const width = this.wrapperRef.nativeElement.offsetWidth;
|
||||
const height =
|
||||
this.wrapperRef.nativeElement.offsetHeight -
|
||||
// tslint:disable-next-line:ban
|
||||
parseFloat(computedStyle.paddingTop) -
|
||||
// tslint:disable-next-line:ban
|
||||
parseFloat(computedStyle.paddingBottom);
|
||||
|
||||
const HiPPIwidth = window.devicePixelRatio * width;
|
||||
@@ -135,7 +137,7 @@ export class SingleTimelineComponent {
|
||||
}
|
||||
|
||||
private handleMouseOut(e: MouseEvent) {
|
||||
if (this.hoveringEntry != null) {
|
||||
if (this.hoveringEntry !== null) {
|
||||
// If null there is no current hover effect so no need to clear
|
||||
this.redraw();
|
||||
}
|
||||
@@ -162,7 +164,7 @@ export class SingleTimelineComponent {
|
||||
|
||||
private drawEntryHover(mouseX: number, mouseY: number) {
|
||||
const currentHoverEntry = this.getEntryAt(mouseX, mouseY);
|
||||
if (this.hoveringEntry == currentHoverEntry) {
|
||||
if (this.hoveringEntry === currentHoverEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -212,7 +214,7 @@ export class SingleTimelineComponent {
|
||||
}
|
||||
|
||||
private updateCursor(mouseX: number, mouseY: number) {
|
||||
if (this.getEntryAt(mouseX, mouseY) != null) {
|
||||
if (this.getEntryAt(mouseX, mouseY) !== null) {
|
||||
this.canvas.style.cursor = 'pointer';
|
||||
}
|
||||
this.canvas.style.cursor = 'auto';
|
||||
@@ -227,7 +229,7 @@ export class SingleTimelineComponent {
|
||||
const clickedEntry = this.getEntryAt(mouseX, mouseY);
|
||||
|
||||
if (clickedEntry != null) {
|
||||
if (this.selected != clickedEntry) {
|
||||
if (this.selected !== clickedEntry) {
|
||||
this.selected = clickedEntry;
|
||||
this.redraw();
|
||||
this.onTimestampChanged.emit(clickedEntry);
|
||||
|
||||
@@ -287,8 +287,8 @@ import {MiniTimelineComponent} from './mini_timeline_component';
|
||||
],
|
||||
})
|
||||
export class TimelineComponent implements TimestampChangeListener {
|
||||
public readonly TOGGLE_BUTTON_CLASS: string = 'button-toggle-expansion';
|
||||
public readonly MAX_SELECTED_TRACES = 3;
|
||||
readonly TOGGLE_BUTTON_CLASS: string = 'button-toggle-expansion';
|
||||
readonly MAX_SELECTED_TRACES = 3;
|
||||
|
||||
@Input() set activeViewTraceTypes(types: TraceType[] | undefined) {
|
||||
if (!types) {
|
||||
@@ -312,7 +312,7 @@ export class TimelineComponent implements TimestampChangeListener {
|
||||
|
||||
this.selectedTracesFormControl.setValue(this.selectedTraces);
|
||||
}
|
||||
public internalActiveTrace: TraceType | undefined = undefined;
|
||||
internalActiveTrace: TraceType | undefined = undefined;
|
||||
|
||||
@Input() timelineData!: TimelineData;
|
||||
@Input() availableTraces: TraceType[] = [];
|
||||
@@ -458,15 +458,10 @@ export class TimelineComponent implements TimestampChangeListener {
|
||||
|
||||
@HostListener('document:keydown', ['$event'])
|
||||
handleKeyboardEvent(event: KeyboardEvent) {
|
||||
switch (event.key) {
|
||||
case 'ArrowLeft': {
|
||||
this.moveToPreviousEntry();
|
||||
break;
|
||||
}
|
||||
case 'ArrowRight': {
|
||||
this.moveToNextEntry();
|
||||
break;
|
||||
}
|
||||
if (event.key === 'ArrowLeft') {
|
||||
this.moveToPreviousEntry();
|
||||
} else if (event.key === 'ArrowRight') {
|
||||
this.moveToNextEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('TimelineComponent', () => {
|
||||
[
|
||||
{
|
||||
traceType: TraceType.SURFACE_FLINGER,
|
||||
timestamps: timestamps,
|
||||
timestamps,
|
||||
},
|
||||
],
|
||||
undefined
|
||||
@@ -117,7 +117,7 @@ describe('TimelineComponent', () => {
|
||||
[
|
||||
{
|
||||
traceType: TraceType.SURFACE_FLINGER,
|
||||
timestamps: timestamps,
|
||||
timestamps,
|
||||
},
|
||||
],
|
||||
undefined
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
|
||||
import {TraceType} from 'trace/trace_type';
|
||||
|
||||
export type Segment = {from: number; to: number};
|
||||
export type BigIntSegment = {from: bigint; to: bigint};
|
||||
export type TimelineData = Map<TraceType, bigint[]>;
|
||||
export interface Segment {
|
||||
from: number;
|
||||
to: number;
|
||||
}
|
||||
export interface BigIntSegment {
|
||||
from: bigint;
|
||||
to: bigint;
|
||||
}
|
||||
export type TimelineData = Map<TraceType, Array<bigint>>;
|
||||
|
||||
@@ -97,8 +97,8 @@ export class TraceConfigComponent {
|
||||
objectKeys = Object.keys;
|
||||
@Input() traces!: TraceConfigurationMap;
|
||||
|
||||
public advancedConfigTraces() {
|
||||
const advancedConfigs: Array<string> = [];
|
||||
advancedConfigTraces() {
|
||||
const advancedConfigs: string[] = [];
|
||||
Object.keys(this.traces).forEach((traceKey: string) => {
|
||||
if (this.traces[traceKey].config) {
|
||||
advancedConfigs.push(traceKey);
|
||||
@@ -107,7 +107,7 @@ export class TraceConfigComponent {
|
||||
return advancedConfigs;
|
||||
}
|
||||
|
||||
public traceEnableConfigs(trace: TraceConfiguration): Array<EnableConfiguration> {
|
||||
traceEnableConfigs(trace: TraceConfiguration): EnableConfiguration[] {
|
||||
if (trace.config) {
|
||||
return trace.config.enableConfigs;
|
||||
} else {
|
||||
@@ -115,7 +115,7 @@ export class TraceConfigComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public traceSelectionConfigs(trace: TraceConfiguration): Array<SelectionConfiguration> {
|
||||
traceSelectionConfigs(trace: TraceConfiguration): SelectionConfiguration[] {
|
||||
if (trace.config) {
|
||||
return trace.config.selectionConfigs;
|
||||
} else {
|
||||
@@ -123,18 +123,18 @@ export class TraceConfigComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public someTraces(trace: TraceConfiguration): boolean {
|
||||
someTraces(trace: TraceConfiguration): boolean {
|
||||
return this.traceEnableConfigs(trace).filter((trace) => trace.enabled).length > 0 && !trace.run;
|
||||
}
|
||||
|
||||
public changeRunTrace(run: boolean, trace: TraceConfiguration): void {
|
||||
changeRunTrace(run: boolean, trace: TraceConfiguration): void {
|
||||
trace.run = run;
|
||||
if (trace.isTraceCollection) {
|
||||
this.traceEnableConfigs(trace).forEach((c: EnableConfiguration) => (c.enabled = run));
|
||||
}
|
||||
}
|
||||
|
||||
public changeTraceCollectionConfig(trace: TraceConfiguration): void {
|
||||
changeTraceCollectionConfig(trace: TraceConfiguration): void {
|
||||
if (trace.isTraceCollection) {
|
||||
trace.run = this.traceEnableConfigs(trace).every((c: EnableConfiguration) => c.enabled);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export class TraceViewComponent {
|
||||
|
||||
private elementRef: ElementRef;
|
||||
|
||||
public tabs: Tab[] = [];
|
||||
tabs: Tab[] = [];
|
||||
private currentActiveTab: undefined | Tab;
|
||||
|
||||
constructor(@Inject(ElementRef) elementRef: ElementRef) {
|
||||
@@ -113,7 +113,7 @@ export class TraceViewComponent {
|
||||
this.renderViewsOverlay();
|
||||
}
|
||||
|
||||
public onTabClick(tab: Tab) {
|
||||
onTabClick(tab: Tab) {
|
||||
this.showTab(tab);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ export class TraceViewComponent {
|
||||
this.activeViewChanged.emit(tab);
|
||||
}
|
||||
|
||||
public isCurrentActiveTab(tab: Tab) {
|
||||
isCurrentActiveTab(tab: Tab) {
|
||||
return tab === this.currentActiveTab;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('TraceViewComponent', () => {
|
||||
const getVisibleTabContents = () => {
|
||||
const contents: HTMLElement[] = [];
|
||||
htmlElement.querySelectorAll('.trace-view-content div').forEach((content) => {
|
||||
if ((content as HTMLElement).style.display != 'none') {
|
||||
if ((content as HTMLElement).style.display !== 'none') {
|
||||
contents.push(content as HTMLElement);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -186,42 +186,42 @@ export class UploadTracesComponent implements FilesDownloadListener {
|
||||
this.traceData.clear();
|
||||
}
|
||||
|
||||
public onFilesDownloadStart() {
|
||||
onFilesDownloadStart() {
|
||||
this.isLoadingFiles = true;
|
||||
this.progressMessage = 'Downloading files...';
|
||||
this.progressPercentage = undefined;
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
public async onFilesDownloaded(files: File[]) {
|
||||
async onFilesDownloaded(files: File[]) {
|
||||
await this.processFiles(files);
|
||||
}
|
||||
|
||||
public async onInputFiles(event: Event) {
|
||||
async onInputFiles(event: Event) {
|
||||
const files = this.getInputFiles(event);
|
||||
await this.processFiles(files);
|
||||
}
|
||||
|
||||
public onViewTracesButtonClick() {
|
||||
onViewTracesButtonClick() {
|
||||
this.traceDataLoaded.emit();
|
||||
}
|
||||
|
||||
public onClearButtonClick() {
|
||||
onClearButtonClick() {
|
||||
this.traceData.clear();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
public onFileDragIn(e: DragEvent) {
|
||||
onFileDragIn(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
public onFileDragOut(e: DragEvent) {
|
||||
onFileDragOut(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
public async onHandleFileDrop(e: DragEvent) {
|
||||
async onHandleFileDrop(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const droppedFiles = e.dataTransfer?.files;
|
||||
@@ -229,7 +229,7 @@ export class UploadTracesComponent implements FilesDownloadListener {
|
||||
await this.processFiles(Array.from(droppedFiles));
|
||||
}
|
||||
|
||||
public onRemoveTrace(event: MouseEvent, trace: Trace) {
|
||||
onRemoveTrace(event: MouseEvent, trace: Trace) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.traceData.removeTrace(trace.type);
|
||||
|
||||
@@ -93,29 +93,29 @@ export class Mediator {
|
||||
);
|
||||
}
|
||||
|
||||
public setUploadTracesComponent(
|
||||
setUploadTracesComponent(
|
||||
uploadTracesComponent: UploadTracesComponentDependencyInversion | undefined
|
||||
) {
|
||||
this.uploadTracesComponent = uploadTracesComponent;
|
||||
}
|
||||
|
||||
public setTimelineComponent(timelineComponent: TimelineComponentDependencyInversion | undefined) {
|
||||
setTimelineComponent(timelineComponent: TimelineComponentDependencyInversion | undefined) {
|
||||
this.timelineComponent = timelineComponent;
|
||||
}
|
||||
|
||||
public onWinscopeInitialized() {
|
||||
onWinscopeInitialized() {
|
||||
this.abtChromeExtensionProtocol.run();
|
||||
}
|
||||
|
||||
public onWinscopeUploadNew() {
|
||||
onWinscopeUploadNew() {
|
||||
this.resetAppToInitialState();
|
||||
}
|
||||
|
||||
public onWinscopeTraceDataLoaded() {
|
||||
onWinscopeTraceDataLoaded() {
|
||||
this.processTraceData();
|
||||
}
|
||||
|
||||
public onWinscopeCurrentTimestampChanged(timestamp: Timestamp | undefined) {
|
||||
onWinscopeCurrentTimestampChanged(timestamp: Timestamp | undefined) {
|
||||
this.executeIgnoringRecursiveTimestampNotifications(() => {
|
||||
const entries = this.traceData.getTraceEntries(timestamp);
|
||||
this.viewers.forEach((viewer) => {
|
||||
|
||||
@@ -23,8 +23,14 @@ import {TraceType} from 'trace/trace_type';
|
||||
import {Timeline} from './trace_data';
|
||||
|
||||
export type TimestampCallbackType = (timestamp: Timestamp | undefined) => void;
|
||||
export type TimeRange = {from: Timestamp; to: Timestamp};
|
||||
type TimestampWithIndex = {index: number; timestamp: Timestamp};
|
||||
export interface TimeRange {
|
||||
from: Timestamp;
|
||||
to: Timestamp;
|
||||
}
|
||||
interface TimestampWithIndex {
|
||||
index: number;
|
||||
timestamp: Timestamp;
|
||||
}
|
||||
|
||||
export class TimelineData {
|
||||
private timelines = new Map<TraceType, Timestamp[]>();
|
||||
@@ -35,13 +41,13 @@ export class TimelineData {
|
||||
private activeViewTraceTypes: TraceType[] = []; // dependencies of current active view
|
||||
private onCurrentTimestampChanged: TimestampCallbackType = FunctionUtils.DO_NOTHING;
|
||||
|
||||
public initialize(timelines: Timeline[], screenRecordingVideo: Blob | undefined) {
|
||||
initialize(timelines: Timeline[], screenRecordingVideo: Blob | undefined) {
|
||||
this.clear();
|
||||
|
||||
this.screenRecordingVideo = screenRecordingVideo;
|
||||
|
||||
const allTimestamps = timelines.flatMap((timeline) => timeline.timestamps);
|
||||
if (allTimestamps.some((timestamp) => timestamp.getType() != allTimestamps[0].getType())) {
|
||||
if (allTimestamps.some((timestamp) => timestamp.getType() !== allTimestamps[0].getType())) {
|
||||
throw Error('Added timeline has inconsistent timestamps.');
|
||||
}
|
||||
|
||||
@@ -70,7 +76,7 @@ export class TimelineData {
|
||||
return this.getFirstTimestamp();
|
||||
}
|
||||
|
||||
public setCurrentTimestamp(timestamp: Timestamp | undefined) {
|
||||
setCurrentTimestamp(timestamp: Timestamp | undefined) {
|
||||
if (!this.hasTimestamps()) {
|
||||
console.warn('Attempted to set timestamp on traces with no timestamps/entries...');
|
||||
return;
|
||||
@@ -90,17 +96,17 @@ export class TimelineData {
|
||||
});
|
||||
}
|
||||
|
||||
public setActiveViewTraceTypes(types: TraceType[]) {
|
||||
setActiveViewTraceTypes(types: TraceType[]) {
|
||||
this.applyOperationAndNotifyIfCurrentTimestampChanged(() => {
|
||||
this.activeViewTraceTypes = types;
|
||||
});
|
||||
}
|
||||
|
||||
public getTimestampType(): TimestampType | undefined {
|
||||
getTimestampType(): TimestampType | undefined {
|
||||
return this.timestampType;
|
||||
}
|
||||
|
||||
public getFullRange(): TimeRange {
|
||||
getFullRange(): TimeRange {
|
||||
if (!this.hasTimestamps()) {
|
||||
throw Error('Trying to get full range when there are no timestamps');
|
||||
}
|
||||
@@ -110,7 +116,7 @@ export class TimelineData {
|
||||
};
|
||||
}
|
||||
|
||||
public getSelectionRange(): TimeRange {
|
||||
getSelectionRange(): TimeRange {
|
||||
if (this.explicitlySetSelection === undefined) {
|
||||
return this.getFullRange();
|
||||
} else {
|
||||
@@ -118,19 +124,19 @@ export class TimelineData {
|
||||
}
|
||||
}
|
||||
|
||||
public setSelectionRange(selection: TimeRange) {
|
||||
setSelectionRange(selection: TimeRange) {
|
||||
this.explicitlySetSelection = selection;
|
||||
}
|
||||
|
||||
public getTimelines(): Map<TraceType, Timestamp[]> {
|
||||
getTimelines(): Map<TraceType, Timestamp[]> {
|
||||
return this.timelines;
|
||||
}
|
||||
|
||||
public getScreenRecordingVideo(): Blob | undefined {
|
||||
getScreenRecordingVideo(): Blob | undefined {
|
||||
return this.screenRecordingVideo;
|
||||
}
|
||||
|
||||
public searchCorrespondingScreenRecordingTimeSeconds(timestamp: Timestamp): number | undefined {
|
||||
searchCorrespondingScreenRecordingTimeSeconds(timestamp: Timestamp): number | undefined {
|
||||
const timestamps = this.timelines.get(TraceType.SCREEN_RECORDING);
|
||||
if (!timestamps) {
|
||||
return undefined;
|
||||
@@ -149,19 +155,19 @@ export class TimelineData {
|
||||
return ScreenRecordingUtils.timestampToVideoTimeSeconds(firstTimestamp, correspondingTimestamp);
|
||||
}
|
||||
|
||||
public hasTimestamps(): boolean {
|
||||
hasTimestamps(): boolean {
|
||||
return Array.from(this.timelines.values()).some((timestamps) => timestamps.length > 0);
|
||||
}
|
||||
|
||||
public hasMoreThanOneDistinctTimestamp(): boolean {
|
||||
hasMoreThanOneDistinctTimestamp(): boolean {
|
||||
return this.hasTimestamps() && this.getFirstTimestamp() !== this.getLastTimestamp();
|
||||
}
|
||||
|
||||
public getCurrentTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
getCurrentTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
return this.searchCorrespondingTimestampFor(type, this.getCurrentTimestamp())?.timestamp;
|
||||
}
|
||||
|
||||
public getPreviousTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
getPreviousTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
const currentIndex = this.searchCorrespondingTimestampFor(
|
||||
type,
|
||||
this.getCurrentTimestamp()
|
||||
@@ -186,11 +192,11 @@ export class TimelineData {
|
||||
return this.timelines.get(type)?.[previousIndex];
|
||||
}
|
||||
|
||||
public getNextTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
getNextTimestampFor(type: TraceType): Timestamp | undefined {
|
||||
const currentIndex =
|
||||
this.searchCorrespondingTimestampFor(type, this.getCurrentTimestamp())?.index ?? -1;
|
||||
|
||||
if (this.timelines.get(type)?.length == 0 ?? true) {
|
||||
if (this.timelines.get(type)?.length === 0 ?? true) {
|
||||
throw Error(`Missing active timestamp for trace type ${type}`);
|
||||
}
|
||||
|
||||
@@ -206,21 +212,21 @@ export class TimelineData {
|
||||
return timestamps[nextIndex];
|
||||
}
|
||||
|
||||
public moveToPreviousTimestampFor(type: TraceType) {
|
||||
moveToPreviousTimestampFor(type: TraceType) {
|
||||
const prevTimestamp = this.getPreviousTimestampFor(type);
|
||||
if (prevTimestamp !== undefined) {
|
||||
this.setCurrentTimestamp(prevTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
public moveToNextTimestampFor(type: TraceType) {
|
||||
moveToNextTimestampFor(type: TraceType) {
|
||||
const nextTimestamp = this.getNextTimestampFor(type);
|
||||
if (nextTimestamp !== undefined) {
|
||||
this.setCurrentTimestamp(nextTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
public clear() {
|
||||
clear() {
|
||||
this.applyOperationAndNotifyIfCurrentTimestampChanged(() => {
|
||||
this.timelines.clear();
|
||||
this.explicitlySetTimestamp = undefined;
|
||||
|
||||
@@ -33,7 +33,7 @@ class TraceData {
|
||||
private parsers: Parser[] = [];
|
||||
private commonTimestampType?: TimestampType;
|
||||
|
||||
public async loadTraces(
|
||||
async loadTraces(
|
||||
traceFiles: TraceFile[],
|
||||
onLoadProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
|
||||
): Promise<ParserError[]> {
|
||||
@@ -45,15 +45,15 @@ class TraceData {
|
||||
return parserErrors;
|
||||
}
|
||||
|
||||
public removeTrace(type: TraceType) {
|
||||
removeTrace(type: TraceType) {
|
||||
this.parsers = this.parsers.filter((parser) => parser.getTraceType() !== type);
|
||||
}
|
||||
|
||||
public getLoadedTraces(): Trace[] {
|
||||
getLoadedTraces(): Trace[] {
|
||||
return this.parsers.map((parser: Parser) => parser.getTrace());
|
||||
}
|
||||
|
||||
public getTraceEntries(timestamp: Timestamp | undefined): Map<TraceType, any> {
|
||||
getTraceEntries(timestamp: Timestamp | undefined): Map<TraceType, any> {
|
||||
const traceEntries: Map<TraceType, any> = new Map<TraceType, any>();
|
||||
|
||||
if (!timestamp) {
|
||||
@@ -86,19 +86,19 @@ class TraceData {
|
||||
return traceEntries;
|
||||
}
|
||||
|
||||
public getTimelines(): Timeline[] {
|
||||
getTimelines(): Timeline[] {
|
||||
const timelines = this.parsers.map((parser): Timeline => {
|
||||
const timestamps = parser.getTimestamps(this.getCommonTimestampType());
|
||||
if (timestamps === undefined) {
|
||||
throw Error('Failed to get timestamps from parser');
|
||||
}
|
||||
return {traceType: parser.getTraceType(), timestamps: timestamps};
|
||||
return {traceType: parser.getTraceType(), timestamps};
|
||||
});
|
||||
|
||||
return timelines;
|
||||
}
|
||||
|
||||
public getScreenRecordingVideo(): undefined | Blob {
|
||||
getScreenRecordingVideo(): undefined | Blob {
|
||||
const parser = this.parsers.find(
|
||||
(parser) => parser.getTraceType() === TraceType.SCREEN_RECORDING
|
||||
);
|
||||
@@ -114,7 +114,7 @@ class TraceData {
|
||||
return (parser.getTraceEntry(timestamps[0]) as ScreenRecordingTraceEntry)?.videoData;
|
||||
}
|
||||
|
||||
public clear() {
|
||||
clear() {
|
||||
this.parserFactory = new ParserFactory();
|
||||
this.parsers = [];
|
||||
this.commonTimestampType = undefined;
|
||||
|
||||
@@ -13,11 +13,11 @@ const ACCESSIBILITY_ICON = 'filter_none';
|
||||
const TAG_ICON = 'details';
|
||||
const TRACE_ERROR_ICON = 'warning';
|
||||
|
||||
type iconMap = {
|
||||
interface IconMap {
|
||||
[key: number]: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const TRACE_ICONS: iconMap = {
|
||||
export const TRACE_ICONS: IconMap = {
|
||||
[TraceType.ACCESSIBILITY]: ACCESSIBILITY_ICON,
|
||||
[TraceType.WINDOW_MANAGER]: WINDOW_MANAGER_ICON,
|
||||
[TraceType.SURFACE_FLINGER]: SURFACE_FLINGER_ICON,
|
||||
|
||||
@@ -29,15 +29,15 @@ const ACCESSIBILITY_ICON = 'accessibility_new';
|
||||
const TAG_ICON = 'details';
|
||||
const TRACE_ERROR_ICON = 'warning';
|
||||
|
||||
type traceInfoMap = {
|
||||
interface TraceInfoMap {
|
||||
[key: number]: {
|
||||
name: string;
|
||||
icon: string;
|
||||
color: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const TRACE_INFO: traceInfoMap = {
|
||||
export const TRACE_INFO: TraceInfoMap = {
|
||||
[TraceType.ACCESSIBILITY]: {
|
||||
name: 'Accessibility',
|
||||
icon: ACCESSIBILITY_ICON,
|
||||
|
||||
@@ -31,7 +31,7 @@ class ArrayUtils {
|
||||
}
|
||||
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ class ArrayUtils {
|
||||
let match = true;
|
||||
|
||||
for (let j = 0; j < subarray.length; ++j) {
|
||||
if (array[i + j] != subarray[j]) {
|
||||
if (array[i + j] !== subarray[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class ArrayUtils {
|
||||
}
|
||||
|
||||
static binarySearchLowerOrEqual<T>(values: T[] | TypedArray, target: T): number | undefined {
|
||||
if (values.length == 0) {
|
||||
if (values.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class FileUtils {
|
||||
// Ignore directories
|
||||
continue;
|
||||
} else {
|
||||
const name = this.removeDirFromFileName(filename);
|
||||
const name = FileUtils.removeDirFromFileName(filename);
|
||||
const fileBlob = await file.async('blob');
|
||||
const unzippedFile = new File([fileBlob], name);
|
||||
unzippedFiles.push(unzippedFile);
|
||||
@@ -96,7 +96,7 @@ class FileUtils {
|
||||
}
|
||||
|
||||
static isZipFile(file: File) {
|
||||
return this.getFileExtension(file) === 'zip';
|
||||
return FileUtils.getFileExtension(file) === 'zip';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export class PersistentStore {
|
||||
public add(key: string, value: string) {
|
||||
add(key: string, value: string) {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
public get(key: string) {
|
||||
get(key: string) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,38 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type StoreObject =
|
||||
| {[key: string | number]: StoreObject | string | boolean | undefined}
|
||||
| StoreObject[]
|
||||
| string[]
|
||||
| boolean[];
|
||||
|
||||
export class PersistentStoreProxy {
|
||||
public static new<T extends StoreObject>(key: string, defaultState: T, storage: Storage): T {
|
||||
static new<T extends object>(key: string, defaultState: T, storage: Storage): T {
|
||||
const storedState = JSON.parse(storage.getItem(key) ?? '{}');
|
||||
const currentState = mergeDeep({}, deepClone(defaultState));
|
||||
const currentState = mergeDeep({}, structuredClone(defaultState));
|
||||
mergeDeepKeepingStructure(currentState, storedState);
|
||||
return wrapWithPersistentStoreProxy<T>(key, currentState, storage);
|
||||
return wrapWithPersistentStoreProxy(key, currentState, storage) as T;
|
||||
}
|
||||
}
|
||||
|
||||
function wrapWithPersistentStoreProxy<T extends StoreObject>(
|
||||
function wrapWithPersistentStoreProxy(
|
||||
storeKey: string,
|
||||
object: T,
|
||||
object: object,
|
||||
storage: Storage,
|
||||
baseObject: T = object
|
||||
): T {
|
||||
baseObject: object = object
|
||||
): object {
|
||||
const updatableProps: string[] = [];
|
||||
|
||||
let key: number | string;
|
||||
for (key in object) {
|
||||
const value = object[key];
|
||||
for (const [key, value] of Object.entries(object)) {
|
||||
if (typeof value === 'string' || typeof value === 'boolean' || value === undefined) {
|
||||
if (!Array.isArray(object)) {
|
||||
updatableProps.push(key);
|
||||
}
|
||||
} else {
|
||||
object[key] = wrapWithPersistentStoreProxy(storeKey, value, storage, baseObject);
|
||||
(object as any)[key] = wrapWithPersistentStoreProxy(storeKey, value, storage, baseObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +52,7 @@ function wrapWithPersistentStoreProxy<T extends StoreObject>(
|
||||
return true;
|
||||
}
|
||||
if (!Array.isArray(target) && updatableProps.includes(prop)) {
|
||||
target[prop] = newValue;
|
||||
(target as any)[prop] = newValue;
|
||||
storage.setItem(storeKey, JSON.stringify(baseObject));
|
||||
return true;
|
||||
}
|
||||
@@ -122,7 +114,3 @@ function mergeDeep(target: any, ...sources: any): any {
|
||||
|
||||
return mergeDeep(target, ...sources);
|
||||
}
|
||||
|
||||
function deepClone(obj: StoreObject): StoreObject {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import {MockStorage} from 'test/unit/mock_storage';
|
||||
import {PersistentStoreProxy, StoreObject} from './persistent_store_proxy';
|
||||
import {PersistentStoreProxy} from './persistent_store_proxy';
|
||||
|
||||
describe('PersistentStoreObject', () => {
|
||||
it('uses defaults when no store is available', () => {
|
||||
@@ -85,14 +85,14 @@ describe('PersistentStoreObject', () => {
|
||||
it("can't update non leaf configs", () => {
|
||||
const mockStorage = new MockStorage();
|
||||
|
||||
const defaultValues: StoreObject = {
|
||||
const defaultValues = {
|
||||
key1: 'value',
|
||||
key2: {
|
||||
key3: true,
|
||||
},
|
||||
};
|
||||
const storeObject = PersistentStoreProxy.new('storeKey', defaultValues, mockStorage);
|
||||
expect(() => (storeObject['key2'] = false)).toThrow();
|
||||
expect(() => (storeObject['key2'] = {key3: false})).toThrow();
|
||||
});
|
||||
|
||||
it('can get nested configs', () => {
|
||||
|
||||
@@ -43,7 +43,7 @@ export class TimeUtils {
|
||||
const units = TimeUtils.units;
|
||||
|
||||
let leftNanos = timestampNanos;
|
||||
const parts = units
|
||||
const parts: Array<{value: bigint; unit: string}> = units
|
||||
.slice()
|
||||
.reverse()
|
||||
.map(({nanosInUnit, unit}) => {
|
||||
@@ -52,7 +52,7 @@ export class TimeUtils {
|
||||
amountOfUnit = leftNanos / BigInt(nanosInUnit);
|
||||
}
|
||||
leftNanos = leftNanos % BigInt(nanosInUnit);
|
||||
return `${amountOfUnit}${unit}`;
|
||||
return {value: amountOfUnit, unit};
|
||||
});
|
||||
|
||||
if (hideNs) {
|
||||
@@ -60,11 +60,11 @@ export class TimeUtils {
|
||||
}
|
||||
|
||||
// Remove all 0ed units at start
|
||||
while (parts.length > 1 && parseInt(parts[0]) === 0) {
|
||||
while (parts.length > 1 && parts[0].value === 0n) {
|
||||
parts.shift();
|
||||
}
|
||||
|
||||
return parts.join('');
|
||||
return parts.map((part) => `${part.value}${part.unit}`).join('');
|
||||
}
|
||||
|
||||
private static nanosecondsToHumanReal(timestampNanos: number | bigint, hideNs = true): string {
|
||||
@@ -91,14 +91,14 @@ export class TimeUtils {
|
||||
const usedValues = timestampHuman
|
||||
.split(/[a-z]+/)
|
||||
.filter((it) => it !== '')
|
||||
.map((it) => parseInt(it));
|
||||
.map((it) => Math.floor(Number(it)));
|
||||
|
||||
let ns = BigInt(0);
|
||||
|
||||
for (let i = 0; i < usedUnits.length; i++) {
|
||||
const unit = usedUnits[i];
|
||||
const value = usedValues[i];
|
||||
const unitData = units.find((it) => it.unit == unit)!;
|
||||
const unitData = units.find((it) => it.unit === unit)!;
|
||||
ns += BigInt(unitData.nanosInUnit) * BigInt(value);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export class TimeUtils {
|
||||
}
|
||||
|
||||
// Add trailing Z if it isn't there yet
|
||||
if (timestampHuman[timestampHuman.length - 1] != 'Z') {
|
||||
if (timestampHuman[timestampHuman.length - 1] !== 'Z') {
|
||||
timestampHuman += 'Z';
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ export class TimeUtils {
|
||||
let nanoSeconds = 0;
|
||||
if (timestampHuman.includes('.')) {
|
||||
const milliseconds = timestampHuman.split('.')[1].replace('Z', '');
|
||||
nanoSeconds = parseInt(milliseconds.padEnd(9, '0').slice(3));
|
||||
nanoSeconds = Math.floor(Number(milliseconds.padEnd(9, '0').slice(3)));
|
||||
}
|
||||
|
||||
return new RealTimestamp(
|
||||
|
||||
@@ -23,7 +23,7 @@ interface TreeNode {
|
||||
type FilterType = (node: TreeNode | undefined | null) => boolean;
|
||||
|
||||
class TreeUtils {
|
||||
public static findDescendantNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
|
||||
static findDescendantNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
|
||||
if (isTargetNode(node)) {
|
||||
return node;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class TreeUtils {
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
const target = this.findDescendantNode(child, isTargetNode);
|
||||
const target = TreeUtils.findDescendantNode(child, isTargetNode);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class TreeUtils {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public static findAncestorNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
|
||||
static findAncestorNode(node: TreeNode, isTargetNode: FilterType): TreeNode | undefined {
|
||||
let ancestor = node.parent;
|
||||
|
||||
while (ancestor && !isTargetNode(ancestor)) {
|
||||
@@ -52,7 +52,7 @@ class TreeUtils {
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
public static makeNodeFilter(filterString: string): FilterType {
|
||||
static makeNodeFilter(filterString: string): FilterType {
|
||||
const filterStrings = filterString.split(',');
|
||||
const positive: any[] = [];
|
||||
const negative: any[] = [];
|
||||
|
||||
@@ -23,7 +23,7 @@ import {Message, MessageBugReport, MessagePong, MessageTimestamp, MessageType} f
|
||||
import {OriginAllowList} from './origin_allow_list';
|
||||
|
||||
class RemoteTool {
|
||||
constructor(public readonly window: Window, public readonly origin: string) {}
|
||||
constructor(readonly window: Window, readonly origin: string) {}
|
||||
}
|
||||
|
||||
export class CrossToolProtocol
|
||||
|
||||
@@ -28,7 +28,7 @@ abstract class Parser {
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
public async parse() {
|
||||
async parse() {
|
||||
const traceBuffer = new Uint8Array(await this.trace.file.arrayBuffer());
|
||||
|
||||
const magicNumber = this.getMagicNumber();
|
||||
@@ -97,28 +97,28 @@ abstract class Parser {
|
||||
return protoObj;
|
||||
}
|
||||
|
||||
public abstract getTraceType(): TraceType;
|
||||
abstract getTraceType(): TraceType;
|
||||
|
||||
public getTrace(): Trace {
|
||||
getTrace(): Trace {
|
||||
return {
|
||||
type: this.getTraceType(),
|
||||
traceFile: this.trace,
|
||||
};
|
||||
}
|
||||
|
||||
public getTimestamps(type: TimestampType): undefined | Timestamp[] {
|
||||
getTimestamps(type: TimestampType): undefined | Timestamp[] {
|
||||
return this.timestamps.get(type);
|
||||
}
|
||||
|
||||
//TODO (b/256564627): include this into the new type/abstraction passed to viewers
|
||||
public getEntriesLength(): number {
|
||||
getEntriesLength(): number {
|
||||
return this.decodedEntries.length;
|
||||
}
|
||||
|
||||
//TODO (b/256564627):
|
||||
// - factor out timestamp search policy. Receive index parameter instead.
|
||||
// - make async for possible lazy disk reads in the future
|
||||
public getTraceEntry(timestamp: Timestamp): undefined | any {
|
||||
getTraceEntry(timestamp: Timestamp): undefined | any {
|
||||
const timestamps = this.getTimestamps(timestamp.getType());
|
||||
if (timestamps === undefined) {
|
||||
throw TypeError(`Timestamps with type "${timestamp.getType()}" not available`);
|
||||
|
||||
@@ -35,7 +35,7 @@ class ParserAccessibility extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>AccessibilityTraceFileProto.decode(buffer);
|
||||
const decoded = AccessibilityTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
|
||||
@@ -38,20 +38,20 @@ class ParserInputMethodClients extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>InputMethodClientsTraceFileProto.decode(buffer);
|
||||
const decoded = InputMethodClientsTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
this.realToElapsedTimeOffsetNs = undefined;
|
||||
}
|
||||
|
||||
return (<any>InputMethodClientsTraceFileProto.decode(buffer)).entry;
|
||||
return (InputMethodClientsTraceFileProto.decode(buffer) as any).entry;
|
||||
}
|
||||
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined | Timestamp {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
} else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs != undefined) {
|
||||
} else if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(
|
||||
type,
|
||||
BigInt(entryProto.elapsedRealtimeNanos) + this.realToElapsedTimeOffsetNs
|
||||
|
||||
@@ -37,7 +37,7 @@ class ParserInputMethodManagerService extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>InputMethodManagerServiceTraceFileProto.decode(buffer);
|
||||
const decoded = InputMethodManagerServiceTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
|
||||
@@ -38,7 +38,7 @@ class ParserInputMethodService extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>InputMethodServiceTraceFileProto.decode(buffer);
|
||||
const decoded = InputMethodServiceTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
|
||||
@@ -65,10 +65,10 @@ class ParserProtoLog extends Parser {
|
||||
}
|
||||
|
||||
override getTimestamp(type: TimestampType, entryProto: any): undefined | Timestamp {
|
||||
if (type == TimestampType.ELAPSED) {
|
||||
if (type === TimestampType.ELAPSED) {
|
||||
return new Timestamp(type, BigInt(entryProto.elapsedRealtimeNanos));
|
||||
}
|
||||
if (type == TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
if (type === TimestampType.REAL && this.realToElapsedTimeOffsetNs !== undefined) {
|
||||
return new Timestamp(
|
||||
type,
|
||||
BigInt(entryProto.elapsedRealtimeNanos) + this.realToElapsedTimeOffsetNs
|
||||
@@ -93,7 +93,7 @@ class ParserProtoLog extends Parser {
|
||||
}
|
||||
|
||||
private decodeProtoLogMessage(entryProto: any, timestampType: TimestampType): LogMessage {
|
||||
const message = (<any>configJson).messages[entryProto.messageHash];
|
||||
const message = (configJson as any).messages[entryProto.messageHash];
|
||||
if (!message) {
|
||||
return new FormattedLogMessage(entryProto, timestampType, this.realToElapsedTimeOffsetNs);
|
||||
}
|
||||
|
||||
@@ -144,11 +144,15 @@ class ParserScreenRecording extends Parser {
|
||||
return [pos, count];
|
||||
}
|
||||
|
||||
private parseTimestampsElapsedNs(videoData: Uint8Array, pos: number, count: number): bigint[] {
|
||||
private parseTimestampsElapsedNs(
|
||||
videoData: Uint8Array,
|
||||
pos: number,
|
||||
count: number
|
||||
): Array<bigint> {
|
||||
if (pos + count * 8 > videoData.length) {
|
||||
throw new TypeError('Failed to parse timestamps. Video data is too short.');
|
||||
}
|
||||
const timestamps: bigint[] = [];
|
||||
const timestamps: Array<bigint> = [];
|
||||
for (let i = 0; i < count; ++i) {
|
||||
const timestamp = ArrayUtils.toUintLittleEndian(videoData, pos, pos + 8);
|
||||
pos += 8;
|
||||
|
||||
@@ -36,7 +36,7 @@ class ParserSurfaceFlinger extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>LayersTraceFileProto.decode(buffer);
|
||||
const decoded = LayersTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
|
||||
@@ -36,7 +36,7 @@ class ParserTransactions extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decodedProto = <any>TransactionsTraceFileProto.decode(buffer);
|
||||
const decodedProto = TransactionsTraceFileProto.decode(buffer) as any;
|
||||
this.decodeWhatFields(decodedProto);
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(decodedProto, 'realToElapsedTimeOffsetNanos')) {
|
||||
@@ -51,22 +51,23 @@ class ParserTransactions extends Parser {
|
||||
const decodeBitset32 = (bitset: number, EnumProto: any) => {
|
||||
return Object.keys(EnumProto).filter((key) => {
|
||||
const value = EnumProto[key];
|
||||
return (bitset & value) != 0;
|
||||
return (bitset & value) !== 0;
|
||||
});
|
||||
};
|
||||
|
||||
const concatBitsetTokens = (tokens: string[]) => {
|
||||
if (tokens.length == 0) {
|
||||
if (tokens.length === 0) {
|
||||
return '0';
|
||||
}
|
||||
return tokens.join(' | ');
|
||||
};
|
||||
|
||||
const LayerStateChangesLsbEnum = (<any>TransactionsTraceFileProto?.parent).LayerState
|
||||
const LayerStateChangesLsbEnum = (TransactionsTraceFileProto?.parent as any).LayerState
|
||||
.ChangesLsb;
|
||||
const LayerStateChangesMsbEnum = (<any>TransactionsTraceFileProto?.parent).LayerState
|
||||
const LayerStateChangesMsbEnum = (TransactionsTraceFileProto?.parent as any).LayerState
|
||||
.ChangesMsb;
|
||||
const DisplayStateChangesEnum = (<any>TransactionsTraceFileProto?.parent).DisplayState.Changes;
|
||||
const DisplayStateChangesEnum = (TransactionsTraceFileProto?.parent as any).DisplayState
|
||||
.Changes;
|
||||
|
||||
decodedProto.entry.forEach((transactionTraceEntry: any) => {
|
||||
transactionTraceEntry.transactions.forEach((transactionState: any) => {
|
||||
|
||||
@@ -35,7 +35,7 @@ class ParserWindowManager extends Parser {
|
||||
}
|
||||
|
||||
override decodeTrace(buffer: Uint8Array): any[] {
|
||||
const decoded = <any>WindowManagerTraceFileProto.decode(buffer);
|
||||
const decoded = WindowManagerTraceFileProto.decode(buffer) as any;
|
||||
if (Object.prototype.hasOwnProperty.call(decoded, 'realToElapsedTimeOffsetNanos')) {
|
||||
this.realToElapsedTimeOffsetNs = BigInt(decoded.realToElapsedTimeOffsetNanos);
|
||||
} else {
|
||||
|
||||
@@ -73,17 +73,17 @@ export class AppComponent {
|
||||
});
|
||||
}
|
||||
|
||||
public async onButtonOpenWinscopeClick() {
|
||||
async onButtonOpenWinscopeClick() {
|
||||
this.openWinscope();
|
||||
await this.waitWinscopeUp();
|
||||
}
|
||||
|
||||
public async onUploadBugreport(event: Event) {
|
||||
async onUploadBugreport(event: Event) {
|
||||
const [file, buffer] = await this.readInputFile(event);
|
||||
this.sendBugreport(file, buffer);
|
||||
}
|
||||
|
||||
public onButtonSendTimestampClick() {
|
||||
onButtonSendTimestampClick() {
|
||||
const inputTimestampElement = document.querySelector('.input-timestamp')! as HTMLInputElement;
|
||||
this.sendTimestamp(BigInt(inputTimestampElement.value));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Chip from 'viewers/common/chip';
|
||||
import {Chip} from 'viewers/common/chip';
|
||||
import {HierarchyTreeNode} from 'viewers/common/ui_tree_utils';
|
||||
|
||||
class HierarchyTreeBuilder {
|
||||
|
||||
@@ -31,11 +31,11 @@ class UnitTestUtils extends CommonTestUtils {
|
||||
}
|
||||
|
||||
static async getWindowManagerState(): Promise<WindowManagerState> {
|
||||
return this.getTraceEntry('traces/elapsed_timestamp/WindowManager.pb');
|
||||
return UnitTestUtils.getTraceEntry('traces/elapsed_timestamp/WindowManager.pb');
|
||||
}
|
||||
|
||||
static async getLayerTraceEntry(): Promise<LayerTraceEntry> {
|
||||
return await this.getTraceEntry('traces/elapsed_timestamp/SurfaceFlinger.pb');
|
||||
return await UnitTestUtils.getTraceEntry('traces/elapsed_timestamp/SurfaceFlinger.pb');
|
||||
}
|
||||
|
||||
static async getImeTraceEntries(): Promise<Map<TraceType, any>> {
|
||||
@@ -55,15 +55,15 @@ class UnitTestUtils extends CommonTestUtils {
|
||||
|
||||
const entries = new Map<TraceType, any>();
|
||||
entries.set(TraceType.INPUT_METHOD_CLIENTS, [
|
||||
await this.getTraceEntry('traces/ime/InputMethodClients.pb'),
|
||||
await UnitTestUtils.getTraceEntry('traces/ime/InputMethodClients.pb'),
|
||||
null,
|
||||
]);
|
||||
entries.set(TraceType.INPUT_METHOD_MANAGER_SERVICE, [
|
||||
await this.getTraceEntry('traces/ime/InputMethodManagerService.pb'),
|
||||
await UnitTestUtils.getTraceEntry('traces/ime/InputMethodManagerService.pb'),
|
||||
null,
|
||||
]);
|
||||
entries.set(TraceType.INPUT_METHOD_SERVICE, [
|
||||
await this.getTraceEntry('traces/ime/InputMethodService.pb'),
|
||||
await UnitTestUtils.getTraceEntry('traces/ime/InputMethodService.pb'),
|
||||
null,
|
||||
]);
|
||||
entries.set(TraceType.SURFACE_FLINGER, [surfaceFlingerEntry, null]);
|
||||
@@ -73,7 +73,7 @@ class UnitTestUtils extends CommonTestUtils {
|
||||
}
|
||||
|
||||
private static async getTraceEntry(filename: string) {
|
||||
const parser = await this.getParser(filename);
|
||||
const parser = await UnitTestUtils.getParser(filename);
|
||||
const timestamp = parser.getTimestamps(TimestampType.ELAPSED)![0];
|
||||
return parser.getTraceEntry(timestamp);
|
||||
}
|
||||
|
||||
@@ -38,13 +38,14 @@ function readIntdefMap(): Map<string, string> {
|
||||
const keys = Object.keys(config.intDefColumn);
|
||||
|
||||
keys.forEach((key) => {
|
||||
const value = config.intDefColumn[<keyof typeof config.intDefColumn>key];
|
||||
const value = config.intDefColumn[key as keyof typeof config.intDefColumn];
|
||||
map.set(key, value);
|
||||
});
|
||||
|
||||
return map;
|
||||
}
|
||||
export default class ObjectFormatter {
|
||||
|
||||
export class ObjectFormatter {
|
||||
static displayDefaults: boolean = false;
|
||||
private static INVALID_ELEMENT_PROPERTIES = config.invalidProperties;
|
||||
|
||||
@@ -77,7 +78,7 @@ export default class ObjectFormatter {
|
||||
// private kotlin variables from kotlin
|
||||
if (it.startsWith(`_`)) return false;
|
||||
// some predefined properties used only internally (e.g., children, ref, diff)
|
||||
if (this.INVALID_ELEMENT_PROPERTIES.includes(it)) return false;
|
||||
if (ObjectFormatter.INVALID_ELEMENT_PROPERTIES.includes(it)) return false;
|
||||
|
||||
const value = entry[it];
|
||||
// only non-empty arrays of non-flicker objects (otherwise they are in hierarchy)
|
||||
@@ -85,7 +86,7 @@ export default class ObjectFormatter {
|
||||
// non-flicker object
|
||||
return !value?.stableId;
|
||||
});
|
||||
properties.forEach(function (prop) {
|
||||
properties.forEach((prop) => {
|
||||
if (typeof entry[prop] !== 'function' && props.indexOf(prop) === -1) {
|
||||
props.push(prop);
|
||||
}
|
||||
@@ -103,7 +104,7 @@ export default class ObjectFormatter {
|
||||
* @return The formatted object
|
||||
*/
|
||||
static format(obj: any): PropertiesDump {
|
||||
const properties = this.getProperties(obj);
|
||||
const properties = ObjectFormatter.getProperties(obj);
|
||||
const sortedProperties = properties.sort();
|
||||
|
||||
const result: PropertiesDump = {};
|
||||
@@ -112,25 +113,25 @@ export default class ObjectFormatter {
|
||||
const value: any = obj[key];
|
||||
|
||||
if (value === null || value === undefined) {
|
||||
if (this.displayDefaults) {
|
||||
if (ObjectFormatter.displayDefaults) {
|
||||
result[key] = value;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (value || this.displayDefaults) {
|
||||
if (value || ObjectFormatter.displayDefaults) {
|
||||
// raw values (e.g., false or 0)
|
||||
if (!value) {
|
||||
result[key] = value;
|
||||
// flicker obj
|
||||
} else if (value.prettyPrint) {
|
||||
const isEmpty = value.isEmpty === true;
|
||||
if (!isEmpty || this.displayDefaults) {
|
||||
if (!isEmpty || ObjectFormatter.displayDefaults) {
|
||||
result[key] = value.prettyPrint();
|
||||
}
|
||||
} else {
|
||||
// converted proto to flicker
|
||||
const translatedObject = this.translateObject(key, value);
|
||||
const translatedObject = ObjectFormatter.translateObject(key, value);
|
||||
if (translatedObject) {
|
||||
if (translatedObject.prettyPrint) {
|
||||
result[key] = translatedObject.prettyPrint();
|
||||
@@ -138,15 +139,15 @@ export default class ObjectFormatter {
|
||||
result[key] = translatedObject;
|
||||
}
|
||||
// objects - recursive call
|
||||
} else if (value && typeof value == `object`) {
|
||||
const childObj = this.format(value) as any;
|
||||
const isEmpty = Object.entries(childObj).length == 0 || childObj.isEmpty;
|
||||
if (!isEmpty || this.displayDefaults) {
|
||||
} else if (value && typeof value === `object`) {
|
||||
const childObj = ObjectFormatter.format(value) as any;
|
||||
const isEmpty = Object.entries(childObj).length === 0 || childObj.isEmpty;
|
||||
if (!isEmpty || ObjectFormatter.displayDefaults) {
|
||||
result[key] = childObj;
|
||||
}
|
||||
} else {
|
||||
// values
|
||||
result[key] = this.translateIntDef(obj, key, value);
|
||||
result[key] = ObjectFormatter.translateIntDef(obj, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,9 +193,11 @@ export default class ObjectFormatter {
|
||||
case `TransformProto`:
|
||||
return toTransform(obj);
|
||||
case 'ColorTransformProto': {
|
||||
const formatted = this.formatColorTransform(obj.val);
|
||||
const formatted = ObjectFormatter.formatColorTransform(obj.val);
|
||||
return `${formatted}`;
|
||||
}
|
||||
default:
|
||||
// handle other cases below
|
||||
}
|
||||
|
||||
// Raw long number (no type name, no constructor name, no useful toString() method)
|
||||
@@ -256,16 +259,16 @@ export default class ObjectFormatter {
|
||||
|
||||
let translatedValue: string = value;
|
||||
// Parse Flicker objects (no intdef annotation supported)
|
||||
if (this.FLICKER_INTDEF_MAP.has(propertyPath)) {
|
||||
translatedValue = this.getIntFlagsAsStrings(
|
||||
if (ObjectFormatter.FLICKER_INTDEF_MAP.has(propertyPath)) {
|
||||
translatedValue = ObjectFormatter.getIntFlagsAsStrings(
|
||||
value,
|
||||
<string>this.FLICKER_INTDEF_MAP.get(propertyPath)
|
||||
ObjectFormatter.FLICKER_INTDEF_MAP.get(propertyPath) as string
|
||||
);
|
||||
} else {
|
||||
// If it's a proto, search on the proto definition for the intdef type
|
||||
const typeDefSpec = this.getTypeDefSpec(parentObj, propertyName);
|
||||
const typeDefSpec = ObjectFormatter.getTypeDefSpec(parentObj, propertyName);
|
||||
if (typeDefSpec) {
|
||||
translatedValue = this.getIntFlagsAsStrings(value, typeDefSpec);
|
||||
translatedValue = ObjectFormatter.getIntFlagsAsStrings(value, typeDefSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,18 +284,18 @@ export default class ObjectFormatter {
|
||||
private static getIntFlagsAsStrings(intFlags: any, annotationType: string): string {
|
||||
const flags = [];
|
||||
|
||||
const mapping = intDefMapping[<keyof typeof intDefMapping>annotationType].values;
|
||||
const mapping = intDefMapping[annotationType as keyof typeof intDefMapping].values;
|
||||
const knownFlagValues = Object.keys(mapping)
|
||||
.reverse()
|
||||
.map((x) => parseInt(x));
|
||||
.map((x) => Math.floor(Number(x)));
|
||||
|
||||
if (knownFlagValues.length == 0) {
|
||||
if (knownFlagValues.length === 0) {
|
||||
console.warn('No mapping for type', annotationType);
|
||||
return intFlags + '';
|
||||
}
|
||||
|
||||
// Will only contain bits that have not been associated with a flag.
|
||||
const parsedIntFlags = parseInt(intFlags);
|
||||
const parsedIntFlags = Math.floor(Number(intFlags));
|
||||
let leftOver = parsedIntFlags;
|
||||
|
||||
for (const flagValue of knownFlagValues) {
|
||||
@@ -300,7 +303,7 @@ export default class ObjectFormatter {
|
||||
(leftOver & flagValue && (intFlags & flagValue) === flagValue) ||
|
||||
(parsedIntFlags === 0 && flagValue === 0)
|
||||
) {
|
||||
flags.push(mapping[<keyof typeof mapping>flagValue]);
|
||||
flags.push(mapping[flagValue as keyof typeof mapping]);
|
||||
|
||||
leftOver = leftOver & ~flagValue;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import {
|
||||
toRegion,
|
||||
} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import Transform from './Transform';
|
||||
import {Transform} from './Transform';
|
||||
|
||||
Layer.fromProto = function (proto: any, excludesCompositionState = false): Layer {
|
||||
Layer.fromProto = (proto: any, excludesCompositionState = false): Layer => {
|
||||
const visibleRegion = toRegion(proto.visibleRegion);
|
||||
const activeBuffer = toActiveBuffer(proto.activeBuffer);
|
||||
const bounds = toRectF(proto.bounds);
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
import {getPropertiesForDisplay} from '../mixin';
|
||||
import {Layer} from './Layer';
|
||||
|
||||
LayerTraceEntry.fromProto = function (
|
||||
LayerTraceEntry.fromProto = (
|
||||
protos: object[],
|
||||
displayProtos: object[],
|
||||
elapsedTimestamp: bigint,
|
||||
@@ -37,7 +37,7 @@ LayerTraceEntry.fromProto = function (
|
||||
realToElapsedTimeOffsetNs: bigint | undefined = undefined,
|
||||
useElapsedTime = false,
|
||||
excludesCompositionState = false
|
||||
): LayerTraceEntry {
|
||||
): LayerTraceEntry => {
|
||||
const layers = protos.map((it) => Layer.fromProto(it, excludesCompositionState));
|
||||
const displays = (displayProtos || []).map((it) => newDisplay(it));
|
||||
const builder = new LayerTraceEntryBuilder(
|
||||
@@ -67,7 +67,7 @@ function addAttributes(entry: LayerTraceEntry, protos: object[], useElapsedTime
|
||||
if (newObj.physicalDisplayBounds) delete newObj.physicalDisplayBounds;
|
||||
if (newObj.isVisible) delete newObj.isVisible;
|
||||
entry.proto = newObj;
|
||||
if (useElapsedTime || entry.clockTimestamp == undefined) {
|
||||
if (useElapsedTime || entry.clockTimestamp === undefined) {
|
||||
entry.name = TimeUtils.format(new ElapsedTimestamp(BigInt(entry.elapsedTimestamp)));
|
||||
entry.shortName = entry.name;
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import {Matrix33, Transform} from '../common';
|
||||
|
||||
Transform.fromProto = function (transformProto: any, positionProto: any): Transform {
|
||||
Transform.fromProto = (transformProto: any, positionProto: any): Transform => {
|
||||
const entry = new Transform(transformProto?.type ?? 0, getMatrix(transformProto, positionProto));
|
||||
|
||||
return entry;
|
||||
@@ -62,16 +62,16 @@ function getDefaultTransform(type: number, x: number, y: number): Matrix33 {
|
||||
throw new Error(`Unknown transform type ${type}`);
|
||||
}
|
||||
|
||||
export function isFlagSet(type: number, bits: number): Boolean {
|
||||
export function isFlagSet(type: number, bits: number): boolean {
|
||||
type = type || 0;
|
||||
return (type & bits) === bits;
|
||||
}
|
||||
|
||||
export function isFlagClear(type: number, bits: number): Boolean {
|
||||
export function isFlagClear(type: number, bits: number): boolean {
|
||||
return (type & bits) === 0;
|
||||
}
|
||||
|
||||
export function isSimpleTransform(type: number): Boolean {
|
||||
export function isSimpleTransform(type: number): boolean {
|
||||
return isFlagClear(type, ROT_INVALID_VAL | SCALE_VAL);
|
||||
}
|
||||
|
||||
@@ -85,4 +85,4 @@ const FLIP_V_VAL = 0x0200; // (1 << 1 << 8)
|
||||
const ROT_90_VAL = 0x0400; // (1 << 2 << 8)
|
||||
const ROT_INVALID_VAL = 0x8000; // (0x80 << 8)
|
||||
|
||||
export default Transform;
|
||||
export {Transform};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import ObjectFormatter from './ObjectFormatter';
|
||||
import {ObjectFormatter} from './ObjectFormatter';
|
||||
|
||||
/**
|
||||
* Get the properties of a WM object for display.
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
import {Activity} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
Activity.fromProto = function (proto: any, nextSeq: () => number): Activity {
|
||||
Activity.fromProto = (proto: any, nextSeq: () => number): Activity => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -52,4 +52,4 @@ function addAttributes(entry: Activity, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default Activity;
|
||||
export {Activity};
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import {DisplayArea} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
DisplayArea.fromProto = function (
|
||||
DisplayArea.fromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): DisplayArea {
|
||||
): DisplayArea => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -47,4 +47,4 @@ function addAttributes(entry: DisplayArea, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default DisplayArea;
|
||||
export {DisplayArea};
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import {DisplayContent, DisplayCutout, PlatformConsts, Rect, toInsets, toRect} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
DisplayContent.fromProto = function (
|
||||
DisplayContent.fromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): DisplayContent {
|
||||
): DisplayContent => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -88,4 +88,4 @@ function addAttributes(entry: DisplayContent, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default DisplayContent;
|
||||
export {DisplayContent};
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
import {Task, toRect} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
Task.fromProto = function (proto: any, isActivityInTree: Boolean, nextSeq: () => number): Task {
|
||||
Task.fromProto = (proto: any, isActivityInTree: boolean, nextSeq: () => number): Task => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -62,4 +62,4 @@ function addAttributes(entry: Task, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default Task;
|
||||
export {Task};
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import {TaskFragment} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
TaskFragment.fromProto = function (
|
||||
TaskFragment.fromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): TaskFragment {
|
||||
): TaskFragment => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -51,4 +51,4 @@ function addAttributes(entry: TaskFragment, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default TaskFragment;
|
||||
export {TaskFragment};
|
||||
|
||||
@@ -24,15 +24,15 @@ import {
|
||||
WindowContainer,
|
||||
} from '../common';
|
||||
|
||||
import Activity from './Activity';
|
||||
import DisplayArea from './DisplayArea';
|
||||
import DisplayContent from './DisplayContent';
|
||||
import Task from './Task';
|
||||
import TaskFragment from './TaskFragment';
|
||||
import WindowState from './WindowState';
|
||||
import WindowToken from './WindowToken';
|
||||
import {Activity} from './Activity';
|
||||
import {DisplayArea} from './DisplayArea';
|
||||
import {DisplayContent} from './DisplayContent';
|
||||
import {Task} from './Task';
|
||||
import {TaskFragment} from './TaskFragment';
|
||||
import {WindowState} from './WindowState';
|
||||
import {WindowToken} from './WindowToken';
|
||||
|
||||
WindowContainer.fromProto = function (
|
||||
WindowContainer.fromProto = (
|
||||
proto: any,
|
||||
protoChildren: any[],
|
||||
isActivityInTree: boolean,
|
||||
@@ -40,7 +40,7 @@ WindowContainer.fromProto = function (
|
||||
nameOverride: string | null = null,
|
||||
identifierOverride: string | null = null,
|
||||
tokenOverride: any = null
|
||||
): WindowContainer {
|
||||
): WindowContainer => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -87,11 +87,11 @@ type WindowContainerChildType =
|
||||
| WindowState
|
||||
| WindowContainer;
|
||||
|
||||
WindowContainer.childrenFromProto = function (
|
||||
WindowContainer.childrenFromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): WindowContainerChildType {
|
||||
): WindowContainerChildType => {
|
||||
return (
|
||||
DisplayContent.fromProto(proto.displayContent, isActivityInTree, nextSeq) ??
|
||||
DisplayArea.fromProto(proto.displayArea, isActivityInTree, nextSeq) ??
|
||||
@@ -147,4 +147,4 @@ function createWindowConfiguration(proto: any): WindowConfiguration {
|
||||
);
|
||||
}
|
||||
|
||||
export default WindowContainer;
|
||||
export {WindowContainer};
|
||||
|
||||
@@ -25,15 +25,15 @@ import {
|
||||
WindowManagerTraceEntryBuilder,
|
||||
} from '../common';
|
||||
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
WindowManagerState.fromProto = function (
|
||||
WindowManagerState.fromProto = (
|
||||
proto: any,
|
||||
elapsedTimestamp: bigint = 0n,
|
||||
where: string = '',
|
||||
realToElapsedTimeOffsetNs: bigint | undefined = undefined,
|
||||
useElapsedTime = false
|
||||
): WindowManagerState {
|
||||
): WindowManagerState => {
|
||||
const inputMethodWIndowAppToken = '';
|
||||
if (proto.inputMethodWindow != null) {
|
||||
proto.inputMethodWindow.hashCode.toString(16);
|
||||
@@ -73,7 +73,7 @@ function addAttributes(entry: WindowManagerState, proto: any, useElapsedTime = f
|
||||
entry.isIncompleteReason = entry.getIsIncompleteReason();
|
||||
}
|
||||
entry.proto = proto;
|
||||
if (useElapsedTime || entry.clockTimestamp == undefined) {
|
||||
if (useElapsedTime || entry.clockTimestamp === undefined) {
|
||||
entry.name = TimeUtils.format(new ElapsedTimestamp(BigInt(entry.elapsedTimestamp)));
|
||||
entry.shortName = entry.name;
|
||||
} else {
|
||||
@@ -122,7 +122,7 @@ function createKeyguardControllerState(proto: any): KeyguardControllerState {
|
||||
if (proto) {
|
||||
proto.keyguardOccludedStates.forEach(
|
||||
(it: any) =>
|
||||
(keyguardOccludedStates[<keyof typeof keyguardOccludedStates>it.displayId] =
|
||||
(keyguardOccludedStates[it.displayId as keyof typeof keyguardOccludedStates] =
|
||||
it.keyguardOccluded)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import {Size, toRect, WindowLayoutParams, WindowState} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
WindowState.fromProto = function (
|
||||
WindowState.fromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): WindowState {
|
||||
): WindowState => {
|
||||
if (proto == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -137,4 +137,4 @@ function addAttributes(entry: WindowState, proto: any) {
|
||||
entry.shortName = shortenName(entry.name);
|
||||
}
|
||||
|
||||
export default WindowState;
|
||||
export {WindowState};
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
import {WindowToken} from '../common';
|
||||
import {shortenName} from '../mixin';
|
||||
import WindowContainer from './WindowContainer';
|
||||
import {WindowContainer} from './WindowContainer';
|
||||
|
||||
WindowToken.fromProto = function (
|
||||
WindowToken.fromProto = (
|
||||
proto: any,
|
||||
isActivityInTree: Boolean,
|
||||
isActivityInTree: boolean,
|
||||
nextSeq: () => number
|
||||
): WindowToken {
|
||||
if (proto == null) {
|
||||
): WindowToken => {
|
||||
if (!proto) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,4 +43,4 @@ WindowToken.fromProto = function (
|
||||
return entry;
|
||||
};
|
||||
|
||||
export default WindowToken;
|
||||
export {WindowToken};
|
||||
|
||||
@@ -69,7 +69,7 @@ class FormattedLogMessage extends LogMessage {
|
||||
if (
|
||||
timestampType === TimestampType.REAL &&
|
||||
realToElapsedTimeOffsetNs !== undefined &&
|
||||
realToElapsedTimeOffsetNs != 0n
|
||||
realToElapsedTimeOffsetNs !== 0n
|
||||
) {
|
||||
timestamp = realToElapsedTimeOffsetNs + BigInt(proto.elapsedRealtimeNanos);
|
||||
time = TimeUtils.format(new RealTimestamp(timestamp));
|
||||
@@ -94,7 +94,7 @@ class UnformattedLogMessage extends LogMessage {
|
||||
if (
|
||||
timestampType === TimestampType.REAL &&
|
||||
realToElapsedTimeOffsetNs !== undefined &&
|
||||
realToElapsedTimeOffsetNs != 0n
|
||||
realToElapsedTimeOffsetNs !== 0n
|
||||
) {
|
||||
timestamp = realToElapsedTimeOffsetNs + BigInt(proto.elapsedRealtimeNanos);
|
||||
time = TimeUtils.format(
|
||||
@@ -108,7 +108,7 @@ class UnformattedLogMessage extends LogMessage {
|
||||
super(
|
||||
formatText(message.message, proto),
|
||||
time,
|
||||
(<any>configJson).groups[message.group].tag,
|
||||
(configJson as any).groups[message.group].tag,
|
||||
message.level,
|
||||
message.at,
|
||||
timestamp
|
||||
@@ -129,7 +129,7 @@ function formatText(messageFormat: any, data: any) {
|
||||
let booleanParamsIdx = 0;
|
||||
|
||||
for (let i = 0; i < messageFormat.length; ) {
|
||||
if (messageFormat[i] == '%') {
|
||||
if (messageFormat[i] === '%') {
|
||||
if (i + 1 >= messageFormat.length) {
|
||||
// Should never happen - protologtool checks for that
|
||||
throw new Error('Invalid format string');
|
||||
|
||||
@@ -43,15 +43,15 @@ export class Timestamp {
|
||||
}
|
||||
}
|
||||
|
||||
public getType(): TimestampType {
|
||||
getType(): TimestampType {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public getValueNs(): bigint {
|
||||
getValueNs(): bigint {
|
||||
return this.valueNs;
|
||||
}
|
||||
|
||||
public valueOf(): bigint {
|
||||
valueOf(): bigint {
|
||||
return this.getValueNs();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {ProxyClient} from 'trace_collection/proxy_client';
|
||||
import {configMap} from './trace_collection_utils';
|
||||
import {ConfigMap} from './trace_collection_utils';
|
||||
|
||||
export interface Device {
|
||||
[key: string]: DeviceProperties;
|
||||
@@ -44,12 +44,12 @@ export interface Connection {
|
||||
isConnectingState(): boolean;
|
||||
throwNoTargetsError(): any;
|
||||
startTrace(
|
||||
reqEnableConfig?: Array<string>,
|
||||
reqSelectedSfConfig?: configMap,
|
||||
reqSelectedWmConfig?: configMap
|
||||
reqEnableConfig?: string[],
|
||||
reqSelectedSfConfig?: ConfigMap,
|
||||
reqSelectedWmConfig?: ConfigMap
|
||||
): any;
|
||||
endTrace(): any;
|
||||
adbData(): Array<File>;
|
||||
adbData(): File[];
|
||||
dumpState(): any;
|
||||
proxy?: ProxyClient;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import {OnProgressUpdateType} from 'common/function_utils';
|
||||
import {PersistentStore} from 'common/persistent_store';
|
||||
import {Device} from './connection';
|
||||
import {configMap} from './trace_collection_utils';
|
||||
import {ConfigMap} from './trace_collection_utils';
|
||||
|
||||
export enum ProxyState {
|
||||
ERROR = 0,
|
||||
@@ -118,7 +118,7 @@ class ProxyRequest {
|
||||
await proxyRequest.call('GET', ProxyEndpoint.DEVICES, proxyRequest.onSuccessGetDevices);
|
||||
}
|
||||
|
||||
async setEnabledConfig(view: any, req: Array<string>) {
|
||||
async setEnabledConfig(view: any, req: string[]) {
|
||||
await proxyRequest.call(
|
||||
'POST',
|
||||
`${ProxyEndpoint.ENABLE_CONFIG_TRACE}${view.proxy.selectedDevice}/`,
|
||||
@@ -128,7 +128,7 @@ class ProxyRequest {
|
||||
);
|
||||
}
|
||||
|
||||
async setSelectedConfig(endpoint: ProxyEndpoint, view: any, req: configMap) {
|
||||
async setSelectedConfig(endpoint: ProxyEndpoint, view: any, req: ConfigMap) {
|
||||
await proxyRequest.call(
|
||||
'POST',
|
||||
`${endpoint}${view.proxy.selectedDevice}/`,
|
||||
@@ -192,7 +192,7 @@ class ProxyRequest {
|
||||
);
|
||||
}
|
||||
|
||||
onSuccessGetDevices = function (request: XMLHttpRequest) {
|
||||
onSuccessGetDevices = (request: XMLHttpRequest) => {
|
||||
const client = proxyClient;
|
||||
try {
|
||||
client.devices = JSON.parse(request.responseText);
|
||||
@@ -225,7 +225,7 @@ class ProxyRequest {
|
||||
const resp = enc.decode(request.response);
|
||||
const filesByType = JSON.parse(resp);
|
||||
|
||||
for (const filetype in filesByType) {
|
||||
for (const filetype of Object.keys(filesByType)) {
|
||||
const files = filesByType[filetype];
|
||||
for (const encodedFileBuffer of files) {
|
||||
const buffer = Uint8Array.from(atob(encodedFileBuffer), (c) => c.charCodeAt(0));
|
||||
@@ -246,7 +246,7 @@ class ProxyRequest {
|
||||
export const proxyRequest = new ProxyRequest();
|
||||
|
||||
interface AdbParams {
|
||||
files: Array<string>;
|
||||
files: string[];
|
||||
idx: number;
|
||||
traceType: string;
|
||||
}
|
||||
@@ -256,12 +256,12 @@ export class ProxyClient {
|
||||
readonly WINSCOPE_PROXY_URL = 'http://localhost:5544';
|
||||
readonly VERSION = '1.0';
|
||||
state: ProxyState = ProxyState.CONNECTING;
|
||||
stateChangeListeners: {(param: ProxyState, errorText: string): void}[] = [];
|
||||
stateChangeListeners: Array<{(param: ProxyState, errorText: string): void}> = [];
|
||||
refresh_worker: NodeJS.Timer | null = null;
|
||||
devices: Device = {};
|
||||
selectedDevice = '';
|
||||
errorText = '';
|
||||
adbData: Array<File> = [];
|
||||
adbData: File[] = [];
|
||||
proxyKey = '';
|
||||
lastDevice = '';
|
||||
store = new PersistentStore();
|
||||
@@ -298,11 +298,7 @@ export class ProxyClient {
|
||||
this.setState(ProxyState.START_TRACE);
|
||||
}
|
||||
|
||||
async updateAdbData(
|
||||
files: Array<string>,
|
||||
traceType: string,
|
||||
progressCallback: OnProgressUpdateType
|
||||
) {
|
||||
async updateAdbData(files: string[], traceType: string, progressCallback: OnProgressUpdateType) {
|
||||
for (let idx = 0; idx < files.length; idx++) {
|
||||
const adbParams = {
|
||||
files,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import {FunctionUtils, OnProgressUpdateType} from 'common/function_utils';
|
||||
import {proxyClient, ProxyEndpoint, proxyRequest, ProxyState} from 'trace_collection/proxy_client';
|
||||
import {Connection, DeviceProperties} from './connection';
|
||||
import {configMap} from './trace_collection_utils';
|
||||
import {ConfigMap} from './trace_collection_utils';
|
||||
import {TracingConfig} from './tracing_config';
|
||||
|
||||
export class ProxyConnection implements Connection {
|
||||
@@ -40,78 +40,78 @@ export class ProxyConnection implements Connection {
|
||||
this.proxy.getDevices();
|
||||
}
|
||||
|
||||
public devices() {
|
||||
devices() {
|
||||
return this.proxy.devices;
|
||||
}
|
||||
|
||||
public adbData() {
|
||||
adbData() {
|
||||
return this.proxy.adbData;
|
||||
}
|
||||
|
||||
public state() {
|
||||
state() {
|
||||
return this.proxy.state;
|
||||
}
|
||||
|
||||
public isDevicesState() {
|
||||
isDevicesState() {
|
||||
return this.state() === ProxyState.DEVICES;
|
||||
}
|
||||
|
||||
public isStartTraceState() {
|
||||
isStartTraceState() {
|
||||
return this.state() === ProxyState.START_TRACE;
|
||||
}
|
||||
|
||||
public isErrorState() {
|
||||
isErrorState() {
|
||||
return this.state() === ProxyState.ERROR;
|
||||
}
|
||||
|
||||
public isEndTraceState() {
|
||||
isEndTraceState() {
|
||||
return this.state() === ProxyState.END_TRACE;
|
||||
}
|
||||
|
||||
public isLoadDataState() {
|
||||
isLoadDataState() {
|
||||
return this.state() === ProxyState.LOAD_DATA;
|
||||
}
|
||||
|
||||
public isConnectingState() {
|
||||
isConnectingState() {
|
||||
return this.state() === ProxyState.CONNECTING;
|
||||
}
|
||||
|
||||
public throwNoTargetsError() {
|
||||
throwNoTargetsError() {
|
||||
this.proxy.setState(ProxyState.ERROR, 'No targets selected');
|
||||
}
|
||||
|
||||
public setProxyKey(key: string) {
|
||||
setProxyKey(key: string) {
|
||||
this.proxy.proxyKey = key;
|
||||
this.proxy.store.add('adb.proxyKey', key);
|
||||
this.restart();
|
||||
}
|
||||
|
||||
public adbSuccess() {
|
||||
adbSuccess() {
|
||||
return !this.notConnected.includes(this.proxy.state);
|
||||
}
|
||||
|
||||
public selectedDevice(): DeviceProperties {
|
||||
selectedDevice(): DeviceProperties {
|
||||
return this.proxy.devices[this.proxy.selectedDevice];
|
||||
}
|
||||
|
||||
public selectedDeviceId(): string {
|
||||
selectedDeviceId(): string {
|
||||
return this.proxy.selectedDevice;
|
||||
}
|
||||
|
||||
public restart() {
|
||||
restart() {
|
||||
this.proxy.setState(ProxyState.CONNECTING);
|
||||
}
|
||||
|
||||
public resetLastDevice() {
|
||||
resetLastDevice() {
|
||||
this.proxy.store.add('adb.lastDevice', '');
|
||||
this.restart();
|
||||
}
|
||||
|
||||
public selectDevice(id: string) {
|
||||
selectDevice(id: string) {
|
||||
this.proxy.selectDevice(id);
|
||||
}
|
||||
|
||||
public keepAliveTrace(view: ProxyConnection) {
|
||||
keepAliveTrace(view: ProxyConnection) {
|
||||
if (!view.isEndTraceState()) {
|
||||
clearInterval(view.keep_alive_worker);
|
||||
view.keep_alive_worker = null;
|
||||
@@ -120,10 +120,10 @@ export class ProxyConnection implements Connection {
|
||||
proxyRequest.keepTraceAlive(view);
|
||||
}
|
||||
|
||||
public startTrace(
|
||||
reqEnableConfig?: Array<string>,
|
||||
reqSelectedSfConfig?: configMap,
|
||||
reqSelectedWmConfig?: configMap
|
||||
startTrace(
|
||||
reqEnableConfig?: string[],
|
||||
reqSelectedSfConfig?: ConfigMap,
|
||||
reqSelectedWmConfig?: ConfigMap
|
||||
) {
|
||||
if (reqEnableConfig) {
|
||||
proxyRequest.setEnabledConfig(this, reqEnableConfig);
|
||||
@@ -146,13 +146,13 @@ export class ProxyConnection implements Connection {
|
||||
proxyRequest.startTrace(this, TracingConfig.getInstance().requestedTraces);
|
||||
}
|
||||
|
||||
public async endTrace() {
|
||||
async endTrace() {
|
||||
this.progressCallback(0);
|
||||
this.proxy.setState(ProxyState.LOAD_DATA);
|
||||
await proxyRequest.endTrace(this, this.progressCallback);
|
||||
}
|
||||
|
||||
public async dumpState(): Promise<boolean> {
|
||||
async dumpState(): Promise<boolean> {
|
||||
this.progressCallback(0);
|
||||
if (TracingConfig.getInstance().requestedDumps.length < 1) {
|
||||
console.error('No targets selected');
|
||||
@@ -168,15 +168,15 @@ export class ProxyConnection implements Connection {
|
||||
return true;
|
||||
}
|
||||
|
||||
public async isWaylandAvailable(): Promise<boolean> {
|
||||
async isWaylandAvailable(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
proxyRequest.call('GET', ProxyEndpoint.CHECK_WAYLAND, (request: XMLHttpRequest) => {
|
||||
resolve(request.responseText == 'true');
|
||||
resolve(request.responseText === 'true');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async onConnectChange(newState: ProxyState) {
|
||||
async onConnectChange(newState: ProxyState) {
|
||||
if (newState === ProxyState.CONNECTING) {
|
||||
proxyClient.getDevices();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,53 @@
|
||||
import {StoreObject} from 'common/persistent_store_proxy';
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type TraceConfiguration = {
|
||||
[key: string]: string | boolean | undefined | StoreObject;
|
||||
export interface TraceConfiguration {
|
||||
name: string | undefined;
|
||||
run: boolean | undefined;
|
||||
isTraceCollection: boolean | undefined;
|
||||
config: ConfigurationOptions | undefined;
|
||||
};
|
||||
}
|
||||
|
||||
export type TraceConfigurationMap = {
|
||||
export interface TraceConfigurationMap {
|
||||
[key: string]: TraceConfiguration;
|
||||
};
|
||||
}
|
||||
|
||||
type ConfigurationOptions = {
|
||||
[key: string]: string | boolean | undefined | StoreObject;
|
||||
interface ConfigurationOptions {
|
||||
enableConfigs: EnableConfiguration[];
|
||||
selectionConfigs: SelectionConfiguration[];
|
||||
};
|
||||
}
|
||||
|
||||
export type EnableConfiguration = {
|
||||
export interface EnableConfiguration {
|
||||
name: string;
|
||||
key: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export type SelectionConfiguration = {
|
||||
export interface SelectionConfiguration {
|
||||
key: string;
|
||||
name: string;
|
||||
options: string[];
|
||||
value: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type configMap = {
|
||||
export interface ConfigMap {
|
||||
[key: string]: string[] | string;
|
||||
};
|
||||
}
|
||||
|
||||
const wmTraceSelectionConfigs: Array<SelectionConfiguration> = [
|
||||
const wmTraceSelectionConfigs: SelectionConfiguration[] = [
|
||||
{
|
||||
key: 'wmbuffersize',
|
||||
name: 'buffer size (KB)',
|
||||
@@ -56,7 +68,7 @@ const wmTraceSelectionConfigs: Array<SelectionConfiguration> = [
|
||||
},
|
||||
];
|
||||
|
||||
const sfTraceEnableConfigs: Array<EnableConfiguration> = [
|
||||
const sfTraceEnableConfigs: EnableConfiguration[] = [
|
||||
{
|
||||
name: 'input',
|
||||
key: 'input',
|
||||
@@ -89,7 +101,7 @@ const sfTraceEnableConfigs: Array<EnableConfiguration> = [
|
||||
},
|
||||
];
|
||||
|
||||
const sfTraceSelectionConfigs: Array<SelectionConfiguration> = [
|
||||
const sfTraceSelectionConfigs: SelectionConfiguration[] = [
|
||||
{
|
||||
key: 'sfbuffersize',
|
||||
name: 'buffer size (KB)',
|
||||
|
||||
@@ -17,8 +17,8 @@ import {PersistentStoreProxy} from 'common/persistent_store_proxy';
|
||||
import {TraceConfigurationMap, TRACES} from './trace_collection_utils';
|
||||
|
||||
export class TracingConfig {
|
||||
public requestedTraces: string[] = [];
|
||||
public requestedDumps: string[] = [];
|
||||
requestedTraces: string[] = [];
|
||||
requestedDumps: string[] = [];
|
||||
|
||||
private storage: Storage | undefined;
|
||||
private tracingConfig: TraceConfigurationMap | undefined;
|
||||
@@ -28,7 +28,7 @@ export class TracingConfig {
|
||||
return setTracesInstance;
|
||||
}
|
||||
|
||||
public initialize(storage: Storage) {
|
||||
initialize(storage: Storage) {
|
||||
this.storage = storage;
|
||||
this.tracingConfig = PersistentStoreProxy.new<TraceConfigurationMap>(
|
||||
'TracingSettings',
|
||||
@@ -55,7 +55,7 @@ export class TracingConfig {
|
||||
);
|
||||
}
|
||||
|
||||
public setTracingConfigForAvailableTraces(isWaylandAvailable = false) {
|
||||
setTracingConfigForAvailableTraces(isWaylandAvailable = false) {
|
||||
const availableTracesConfig = TRACES['default'];
|
||||
if (isWaylandAvailable) {
|
||||
Object.assign(availableTracesConfig, TRACES['arc']);
|
||||
@@ -63,11 +63,11 @@ export class TracingConfig {
|
||||
this.setTracingConfig(availableTracesConfig);
|
||||
}
|
||||
|
||||
public tracingConfigIsSet(): boolean {
|
||||
tracingConfigIsSet(): boolean {
|
||||
return this.tracingConfig !== undefined;
|
||||
}
|
||||
|
||||
public getTracingConfig(): TraceConfigurationMap {
|
||||
getTracingConfig(): TraceConfigurationMap {
|
||||
if (this.tracingConfig === undefined) {
|
||||
throw Error('Tracing config not initialized yet');
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export class TracingConfig {
|
||||
);
|
||||
}
|
||||
|
||||
public getDumpConfig(): TraceConfigurationMap {
|
||||
getDumpConfig(): TraceConfigurationMap {
|
||||
if (this.dumpConfig === undefined) {
|
||||
throw Error('Dump config not initialized yet');
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export default class Chip {
|
||||
export class Chip {
|
||||
short: string;
|
||||
long: string;
|
||||
type: string;
|
||||
|
||||
@@ -20,9 +20,9 @@ import {HierarchyTreeNode, PropertiesTreeNode} from 'viewers/common/ui_tree_util
|
||||
import {UserOptions} from 'viewers/common/user_options';
|
||||
|
||||
export class ImeUiData {
|
||||
dependencies: Array<TraceType>;
|
||||
highlightedItems: Array<string> = [];
|
||||
pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
dependencies: TraceType[];
|
||||
highlightedItems: string[] = [];
|
||||
pinnedItems: HierarchyTreeNode[] = [];
|
||||
hierarchyUserOptions: UserOptions = {};
|
||||
propertiesUserOptions: UserOptions = {};
|
||||
tree: HierarchyTreeNode | null = null;
|
||||
@@ -30,7 +30,7 @@ export class ImeUiData {
|
||||
hierarchyTableProperties: TableProperties | null = null;
|
||||
additionalProperties: ImeAdditionalProperties | null = null;
|
||||
|
||||
constructor(dependencies?: Array<TraceType>) {
|
||||
constructor(dependencies?: TraceType[]) {
|
||||
this.dependencies = dependencies ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ import {FilterType, TreeUtils} from 'common/tree_utils';
|
||||
import {WindowContainer} from 'trace/flickerlib/common';
|
||||
import {Layer} from 'trace/flickerlib/layers/Layer';
|
||||
import {LayerTraceEntry} from 'trace/flickerlib/layers/LayerTraceEntry';
|
||||
import Activity from 'trace/flickerlib/windows/Activity';
|
||||
import {Activity} from 'trace/flickerlib/windows/Activity';
|
||||
import {WindowManagerState} from 'trace/flickerlib/windows/WindowManagerState';
|
||||
import WindowState from 'trace/flickerlib/windows/WindowState';
|
||||
import {WindowState} from 'trace/flickerlib/windows/WindowState';
|
||||
|
||||
class ProcessedWindowManagerState {
|
||||
constructor(
|
||||
@@ -49,9 +49,7 @@ class ImeLayers {
|
||||
}
|
||||
|
||||
class ImeUtils {
|
||||
public static processWindowManagerTraceEntry(
|
||||
entry: WindowManagerState
|
||||
): ProcessedWindowManagerState {
|
||||
static processWindowManagerTraceEntry(entry: WindowManagerState): ProcessedWindowManagerState {
|
||||
const displayContent = entry.root.children[0];
|
||||
|
||||
return new ProcessedWindowManagerState(
|
||||
@@ -60,16 +58,16 @@ class ImeUtils {
|
||||
entry.focusedApp,
|
||||
entry.focusedWindow,
|
||||
entry.focusedActivity,
|
||||
this.isInputMethodVisible(displayContent),
|
||||
this.getImeControlTargetProperty(displayContent.proto),
|
||||
this.getImeInputTargetProperty(displayContent.proto),
|
||||
this.getImeLayeringTargetProperty(displayContent.proto),
|
||||
ImeUtils.isInputMethodVisible(displayContent),
|
||||
ImeUtils.getImeControlTargetProperty(displayContent.proto),
|
||||
ImeUtils.getImeInputTargetProperty(displayContent.proto),
|
||||
ImeUtils.getImeLayeringTargetProperty(displayContent.proto),
|
||||
displayContent.proto.imeInsetsSourceProvider,
|
||||
entry.proto
|
||||
);
|
||||
}
|
||||
|
||||
public static getImeLayers(
|
||||
static getImeLayers(
|
||||
entry: LayerTraceEntry,
|
||||
processedWindowManagerState: ProcessedWindowManagerState
|
||||
): ImeLayers | undefined {
|
||||
@@ -91,12 +89,12 @@ class ImeUtils {
|
||||
|
||||
// we want to see both ImeContainer and IME-snapshot if there are
|
||||
// cases where both exist
|
||||
const taskLayerOfImeContainer = this.findAncestorTaskLayerOfImeLayer(
|
||||
const taskLayerOfImeContainer = ImeUtils.findAncestorTaskLayerOfImeLayer(
|
||||
entry,
|
||||
TreeUtils.makeNodeFilter('ImeContainer')
|
||||
);
|
||||
|
||||
const taskLayerOfImeSnapshot = this.findAncestorTaskLayerOfImeLayer(
|
||||
const taskLayerOfImeSnapshot = ImeUtils.findAncestorTaskLayerOfImeLayer(
|
||||
entry,
|
||||
TreeUtils.makeNodeFilter('IME-snapshot')
|
||||
);
|
||||
@@ -111,7 +109,7 @@ class ImeUtils {
|
||||
);
|
||||
}
|
||||
|
||||
public static transformInputConnectionCall(entry: any) {
|
||||
static transformInputConnectionCall(entry: any) {
|
||||
const obj = Object.assign({}, entry);
|
||||
if (obj.inputConnectionCall) {
|
||||
Object.getOwnPropertyNames(obj.inputConnectionCall).forEach((name) => {
|
||||
@@ -132,7 +130,7 @@ class ImeUtils {
|
||||
}
|
||||
|
||||
const isTaskLayer = TreeUtils.makeNodeFilter('Task, ImePlaceholder');
|
||||
const taskLayer = <Layer>TreeUtils.findAncestorNode(imeLayer, isTaskLayer);
|
||||
const taskLayer = TreeUtils.findAncestorNode(imeLayer, isTaskLayer) as Layer;
|
||||
if (!taskLayer) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -143,17 +141,17 @@ class ImeUtils {
|
||||
|
||||
private static getImeControlTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ['inputMethodControlTarget', 'imeControlTarget'];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
return ImeUtils.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static getImeInputTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ['inputMethodInputTarget', 'imeInputTarget'];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
return ImeUtils.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static getImeLayeringTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ['inputMethodTarget', 'imeLayeringTarget'];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
return ImeUtils.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static findAnyPropertyWithMatchingName(object: any, possible_names: string[]): any {
|
||||
@@ -163,10 +161,11 @@ class ImeUtils {
|
||||
|
||||
private static isInputMethodVisible(displayContent: WindowContainer): boolean {
|
||||
const isInputMethod = TreeUtils.makeNodeFilter('InputMethod');
|
||||
const inputMethodWindowOrLayer = <WindowContainer>(
|
||||
TreeUtils.findDescendantNode(displayContent, isInputMethod)
|
||||
);
|
||||
return inputMethodWindowOrLayer?.isVisible == true;
|
||||
const inputMethodWindowOrLayer = TreeUtils.findDescendantNode(
|
||||
displayContent,
|
||||
isInputMethod
|
||||
) as WindowContainer;
|
||||
return inputMethodWindowOrLayer?.isVisible === true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ type NotifyImeViewCallbackType = (uiData: ImeUiData) => void;
|
||||
export abstract class PresenterInputMethod {
|
||||
constructor(
|
||||
notifyViewCallback: NotifyImeViewCallbackType,
|
||||
dependencies: Array<TraceType>,
|
||||
dependencies: TraceType[],
|
||||
private storage: Storage
|
||||
) {
|
||||
this.notifyViewCallback = notifyViewCallback;
|
||||
@@ -40,10 +40,10 @@ export abstract class PresenterInputMethod {
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updatePinnedItems(pinnedItem: HierarchyTreeNode) {
|
||||
updatePinnedItems(pinnedItem: HierarchyTreeNode) {
|
||||
const pinnedId = `${pinnedItem.id}`;
|
||||
if (this.pinnedItems.map((item) => `${item.id}`).includes(pinnedId)) {
|
||||
this.pinnedItems = this.pinnedItems.filter((pinned) => `${pinned.id}` != pinnedId);
|
||||
this.pinnedItems = this.pinnedItems.filter((pinned) => `${pinned.id}` !== pinnedId);
|
||||
} else {
|
||||
this.pinnedItems.push(pinnedItem);
|
||||
}
|
||||
@@ -52,9 +52,9 @@ export abstract class PresenterInputMethod {
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updateHighlightedItems(id: string) {
|
||||
updateHighlightedItems(id: string) {
|
||||
if (this.highlightedItems.includes(id)) {
|
||||
this.highlightedItems = this.highlightedItems.filter((hl) => hl != id);
|
||||
this.highlightedItems = this.highlightedItems.filter((hl) => hl !== id);
|
||||
} else {
|
||||
this.highlightedItems = []; //if multi-select surfaces implemented, remove this line
|
||||
this.highlightedItems.push(id);
|
||||
@@ -63,37 +63,37 @@ export abstract class PresenterInputMethod {
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updateHierarchyTree(userOptions: UserOptions) {
|
||||
updateHierarchyTree(userOptions: UserOptions) {
|
||||
this.hierarchyUserOptions = userOptions;
|
||||
this.uiData.hierarchyUserOptions = this.hierarchyUserOptions;
|
||||
this.uiData.tree = this.generateTree();
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public filterHierarchyTree(filterString: string) {
|
||||
filterHierarchyTree(filterString: string) {
|
||||
this.hierarchyFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.uiData.tree = this.generateTree();
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updatePropertiesTree(userOptions: UserOptions) {
|
||||
updatePropertiesTree(userOptions: UserOptions) {
|
||||
this.propertiesUserOptions = userOptions;
|
||||
this.uiData.propertiesUserOptions = this.propertiesUserOptions;
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public filterPropertiesTree(filterString: string) {
|
||||
filterPropertiesTree(filterString: string) {
|
||||
this.propertiesFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public newPropertiesTree(selectedItem: HierarchyTreeNode) {
|
||||
newPropertiesTree(selectedItem: HierarchyTreeNode) {
|
||||
this.additionalPropertyEntry = null;
|
||||
this.selectedHierarchyTree = selectedItem;
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public newAdditionalPropertiesTree(selectedItem: any) {
|
||||
newAdditionalPropertiesTree(selectedItem: any) {
|
||||
this.selectedHierarchyTree = new HierarchyTreeNode(
|
||||
selectedItem.name,
|
||||
'AdditionalProperty',
|
||||
@@ -109,7 +109,7 @@ export abstract class PresenterInputMethod {
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public notifyCurrentTraceEntries(entries: Map<TraceType, [any, any]>) {
|
||||
notifyCurrentTraceEntries(entries: Map<TraceType, [any, any]>) {
|
||||
this.uiData = new ImeUiData(this.dependencies);
|
||||
this.uiData.hierarchyUserOptions = this.hierarchyUserOptions;
|
||||
this.uiData.propertiesUserOptions = this.propertiesUserOptions;
|
||||
@@ -185,7 +185,7 @@ export abstract class PresenterInputMethod {
|
||||
}
|
||||
private updatePinnedIds(newId: string) {
|
||||
if (this.pinnedIds.includes(newId)) {
|
||||
this.pinnedIds = this.pinnedIds.filter((pinned) => pinned != newId);
|
||||
this.pinnedIds = this.pinnedIds.filter((pinned) => pinned !== newId);
|
||||
} else {
|
||||
this.pinnedIds.push(newId);
|
||||
}
|
||||
@@ -203,14 +203,14 @@ export abstract class PresenterInputMethod {
|
||||
|
||||
private hierarchyFilter: FilterType = TreeUtils.makeNodeFilter('');
|
||||
private propertiesFilter: FilterType = TreeUtils.makeNodeFilter('');
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private pinnedIds: Array<string> = [];
|
||||
private pinnedItems: HierarchyTreeNode[] = [];
|
||||
private pinnedIds: string[] = [];
|
||||
private selectedHierarchyTree: HierarchyTreeNode | null = null;
|
||||
|
||||
readonly notifyViewCallback: NotifyImeViewCallbackType;
|
||||
protected readonly dependencies: Array<TraceType>;
|
||||
protected readonly dependencies: TraceType[];
|
||||
protected uiData: ImeUiData;
|
||||
protected highlightedItems: Array<string> = [];
|
||||
protected highlightedItems: string[] = [];
|
||||
protected entry: TraceTreeNode | null = null;
|
||||
protected additionalPropertyEntry: TraceTreeNode | null = null;
|
||||
protected hierarchyUserOptions: UserOptions = PersistentStoreProxy.new<UserOptions>(
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import {PropertiesTreeNode} from './ui_tree_utils';
|
||||
|
||||
class PropertiesTreeGenerator {
|
||||
public generate(key: string, value: any): PropertiesTreeNode {
|
||||
generate(key: string, value: any): PropertiesTreeNode {
|
||||
if (this.isLeaf(value)) {
|
||||
return {
|
||||
propertyKey: key,
|
||||
@@ -35,7 +35,7 @@ class PropertiesTreeGenerator {
|
||||
|
||||
return {
|
||||
propertyKey: key,
|
||||
children: children,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export type TableProperties = {
|
||||
export interface TableProperties {
|
||||
[key: string]: string | boolean | undefined;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {FilterType, TreeNode} from 'common/tree_utils';
|
||||
import ObjectFormatter from 'trace/flickerlib/ObjectFormatter';
|
||||
import {ObjectFormatter} from 'trace/flickerlib/ObjectFormatter';
|
||||
import {TraceTreeNode} from 'trace/trace_tree_node';
|
||||
import {
|
||||
GPU_CHIP,
|
||||
@@ -49,42 +49,42 @@ export class TreeGenerator {
|
||||
private isModified?: IsModifiedCallbackType;
|
||||
private newMapping: Map<string, TraceTreeNode> | null = null;
|
||||
private oldMapping: Map<string, TraceTreeNode> | null = null;
|
||||
private readonly pinnedIds: Array<string>;
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private relZParentIds: Array<string> = [];
|
||||
private flattenedChildren: Array<HierarchyTreeNode> = [];
|
||||
private readonly pinnedIds: string[];
|
||||
private pinnedItems: HierarchyTreeNode[] = [];
|
||||
private relZParentIds: string[] = [];
|
||||
private flattenedChildren: HierarchyTreeNode[] = [];
|
||||
|
||||
constructor(inputEntry: TraceTreeNode, filter: FilterType, pinnedIds?: Array<string>) {
|
||||
constructor(inputEntry: TraceTreeNode, filter: FilterType, pinnedIds?: string[]) {
|
||||
this.inputEntry = inputEntry;
|
||||
this.filter = filter;
|
||||
this.pinnedIds = pinnedIds ?? [];
|
||||
}
|
||||
|
||||
public setIsOnlyVisibleView(enabled: boolean): TreeGenerator {
|
||||
setIsOnlyVisibleView(enabled: boolean): TreeGenerator {
|
||||
this.isOnlyVisibleView = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setIsSimplifyNames(enabled: boolean): TreeGenerator {
|
||||
setIsSimplifyNames(enabled: boolean): TreeGenerator {
|
||||
this.isSimplifyNames = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setIsFlatView(enabled: boolean): TreeGenerator {
|
||||
setIsFlatView(enabled: boolean): TreeGenerator {
|
||||
this.isFlatView = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public generateTree(): HierarchyTreeNode | null {
|
||||
generateTree(): HierarchyTreeNode | null {
|
||||
return this.getCustomizedTree(this.inputEntry);
|
||||
}
|
||||
|
||||
public compareWith(previousEntry: TraceTreeNode | null): TreeGenerator {
|
||||
compareWith(previousEntry: TraceTreeNode | null): TreeGenerator {
|
||||
this.previousEntry = previousEntry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withUniqueNodeId(getNodeId?: GetNodeIdCallbackType): TreeGenerator {
|
||||
withUniqueNodeId(getNodeId?: GetNodeIdCallbackType): TreeGenerator {
|
||||
this.getNodeId = (node: TraceTreeNode | null) => {
|
||||
const id = getNodeId ? getNodeId(node) : this.defaultNodeIdCallback(node);
|
||||
if (id === null || id === undefined) {
|
||||
@@ -96,12 +96,12 @@ export class TreeGenerator {
|
||||
return this;
|
||||
}
|
||||
|
||||
public withModifiedCheck(isModified?: IsModifiedCallbackType): TreeGenerator {
|
||||
withModifiedCheck(isModified?: IsModifiedCallbackType): TreeGenerator {
|
||||
this.isModified = isModified ?? this.defaultModifiedCheck;
|
||||
return this;
|
||||
}
|
||||
|
||||
public generateFinalTreeWithDiff(): HierarchyTreeNode | null {
|
||||
generateFinalTreeWithDiff(): HierarchyTreeNode | null {
|
||||
this.newMapping = this.generateIdToNodeMapping(this.inputEntry);
|
||||
this.oldMapping = this.previousEntry ? this.generateIdToNodeMapping(this.previousEntry) : null;
|
||||
|
||||
@@ -135,11 +135,11 @@ export class TreeGenerator {
|
||||
return Object.freeze(newTree);
|
||||
}
|
||||
|
||||
public getPinnedItems(): Array<HierarchyTreeNode> {
|
||||
getPinnedItems(): HierarchyTreeNode[] {
|
||||
return this.pinnedItems;
|
||||
}
|
||||
|
||||
private flattenChildren(children: Array<HierarchyTreeNode>) {
|
||||
private flattenChildren(children: HierarchyTreeNode[]) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
const childIsVisibleNode =
|
||||
@@ -184,11 +184,11 @@ export class TreeGenerator {
|
||||
}
|
||||
|
||||
private addChips(tree: HierarchyTreeNode): HierarchyTreeNode {
|
||||
if (tree.hwcCompositionType == HwcCompositionType.CLIENT) {
|
||||
if (tree.hwcCompositionType === HwcCompositionType.CLIENT) {
|
||||
tree.chips.push(GPU_CHIP);
|
||||
} else if (
|
||||
tree.hwcCompositionType == HwcCompositionType.DEVICE ||
|
||||
tree.hwcCompositionType == HwcCompositionType.SOLID_COLOR
|
||||
tree.hwcCompositionType === HwcCompositionType.DEVICE ||
|
||||
tree.hwcCompositionType === HwcCompositionType.SOLID_COLOR
|
||||
) {
|
||||
tree.chips.push(HWC_CHIP);
|
||||
}
|
||||
@@ -323,7 +323,7 @@ export class TreeGenerator {
|
||||
oldTree: TraceTreeNode | null,
|
||||
newTreeSiblings: Array<TraceTreeNode | null>,
|
||||
oldTreeSiblings: Array<TraceTreeNode | null>
|
||||
): Array<TraceTreeNode> {
|
||||
): TraceTreeNode[] {
|
||||
const diffTrees = [];
|
||||
// NOTE: A null ID represents a non existent node.
|
||||
if (!this.getNodeId) {
|
||||
@@ -417,7 +417,7 @@ export class TreeGenerator {
|
||||
private visitChildren(
|
||||
newTree: TraceTreeNode | null,
|
||||
oldTree: TraceTreeNode | null
|
||||
): Array<TraceTreeNode> {
|
||||
): TraceTreeNode[] {
|
||||
// Recursively traverse all children of new and old tree.
|
||||
const diffChildren = [];
|
||||
const numOfChildren = Math.max(newTree?.children?.length ?? 0, oldTree?.children?.length ?? 0);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {FilterType, TreeNode} from 'common/tree_utils';
|
||||
import ObjectFormatter from 'trace/flickerlib/ObjectFormatter';
|
||||
import {ObjectFormatter} from 'trace/flickerlib/ObjectFormatter';
|
||||
import {TraceTreeNode} from 'trace/trace_tree_node';
|
||||
|
||||
import {
|
||||
@@ -58,22 +58,22 @@ export class TreeTransformer {
|
||||
this.setTransformerOptions({});
|
||||
}
|
||||
|
||||
public setOnlyProtoDump(onlyProto: boolean): TreeTransformer {
|
||||
setOnlyProtoDump(onlyProto: boolean): TreeTransformer {
|
||||
this.onlyProtoDump = onlyProto;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setIsShowDefaults(enabled: boolean): TreeTransformer {
|
||||
setIsShowDefaults(enabled: boolean): TreeTransformer {
|
||||
this.isShowDefaults = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setIsShowDiff(enabled: boolean): TreeTransformer {
|
||||
setIsShowDiff(enabled: boolean): TreeTransformer {
|
||||
this.isShowDiff = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setTransformerOptions(options: TreeTransformerOptions): TreeTransformer {
|
||||
setTransformerOptions(options: TreeTransformerOptions): TreeTransformer {
|
||||
this.options = options;
|
||||
if (!this.options.formatter) {
|
||||
this.options.formatter = this.formatProto;
|
||||
@@ -81,7 +81,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setProperties(currentEntry: TraceTreeNode | null): TreeTransformer {
|
||||
setProperties(currentEntry: TraceTreeNode | null): TreeTransformer {
|
||||
const currFlickerItem = this.getOriginalFlickerItem(currentEntry, this.stableId);
|
||||
const target = currFlickerItem ? currFlickerItem.obj ?? currFlickerItem : null;
|
||||
ObjectFormatter.displayDefaults = this.isShowDefaults;
|
||||
@@ -91,7 +91,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setDiffProperties(previousEntry: TraceTreeNode | null): TreeTransformer {
|
||||
setDiffProperties(previousEntry: TraceTreeNode | null): TreeTransformer {
|
||||
if (this.isShowDiff) {
|
||||
const prevFlickerItem = this.findFlickerItem(previousEntry, this.stableId);
|
||||
const target = prevFlickerItem ? prevFlickerItem.obj ?? prevFlickerItem : null;
|
||||
@@ -102,10 +102,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public getOriginalFlickerItem(
|
||||
entry: TraceTreeNode | null,
|
||||
stableId: string
|
||||
): TraceTreeNode | null {
|
||||
getOriginalFlickerItem(entry: TraceTreeNode | null, stableId: string): TraceTreeNode | null {
|
||||
return this.findFlickerItem(entry, stableId);
|
||||
}
|
||||
|
||||
@@ -151,7 +148,7 @@ export class TreeTransformer {
|
||||
return null;
|
||||
}
|
||||
|
||||
public transform(): PropertiesTreeNode {
|
||||
transform(): PropertiesTreeNode {
|
||||
const {formatter} = this.options!;
|
||||
if (!formatter) {
|
||||
throw new Error('Missing formatter, please set with setOptions()');
|
||||
@@ -249,7 +246,7 @@ export class TreeTransformer {
|
||||
}
|
||||
|
||||
let transformedProperties: any;
|
||||
if (children.length == 1 && children[0].children?.length == 0 && !children[0].combined) {
|
||||
if (children.length === 1 && children[0].children?.length === 0 && !children[0].combined) {
|
||||
// Merge leaf key value pairs.
|
||||
const child = children[0];
|
||||
|
||||
@@ -276,7 +273,7 @@ export class TreeTransformer {
|
||||
const diffType = this.getDiff(name, compareWithName);
|
||||
transformedProperties.diffType = diffType;
|
||||
|
||||
if (diffType == DiffType.DELETED) {
|
||||
if (diffType === DiffType.DELETED) {
|
||||
transformedProperties.name = compareWithName;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +343,7 @@ export class TreeTransformer {
|
||||
|
||||
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(<TreeNode>item) ?? false;
|
||||
return this.filter(item as TreeNode) ?? false;
|
||||
}
|
||||
|
||||
private transformProperties(
|
||||
@@ -357,27 +354,29 @@ export class TreeTransformer {
|
||||
const transformedProperties: PropertiesTreeNode = {
|
||||
properties: {},
|
||||
};
|
||||
let formatted = undefined;
|
||||
|
||||
if (skip && skip.includes(properties)) {
|
||||
// skip
|
||||
} else if ((formatted = formatter(properties))) {
|
||||
return transformedProperties; // skip
|
||||
}
|
||||
|
||||
const formatted = formatter(properties);
|
||||
if (formatted) {
|
||||
// Obj has been formatted into a terminal node — has no children.
|
||||
transformedProperties.properties[formatted] = new Terminal();
|
||||
} else if (Array.isArray(properties)) {
|
||||
properties.forEach((e, i) => {
|
||||
transformedProperties.properties['' + i] = e;
|
||||
});
|
||||
} else if (typeof properties == 'string') {
|
||||
} else if (typeof properties === 'string') {
|
||||
// Object is a primitive type — has no children. Set to terminal
|
||||
// to differentiate between null object and Terminal element.
|
||||
transformedProperties.properties[properties] = new Terminal();
|
||||
} else if (typeof properties == 'number' || typeof properties == 'boolean') {
|
||||
} else if (typeof properties === 'number' || typeof properties === 'boolean') {
|
||||
// Similar to above — primitive type node has no children.
|
||||
transformedProperties.properties['' + properties] = new Terminal();
|
||||
} else if (properties && typeof properties == 'object') {
|
||||
} else if (properties && typeof properties === 'object') {
|
||||
// Empty objects
|
||||
if (Object.keys(properties).length == 0) {
|
||||
if (Object.keys(properties).length === 0) {
|
||||
transformedProperties.properties['[empty]'] = new Terminal();
|
||||
} else {
|
||||
// Non empty objects
|
||||
@@ -400,7 +399,7 @@ export class TreeTransformer {
|
||||
return DiffType.ADDED;
|
||||
} else if (this.isTerminal(val) && compareVal) {
|
||||
return DiffType.DELETED;
|
||||
} else if (compareVal != val) {
|
||||
} else if (compareVal !== val) {
|
||||
return DiffType.MODIFIED;
|
||||
} else {
|
||||
return DiffType.NONE;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Chip from './chip';
|
||||
import {Chip} from './chip';
|
||||
|
||||
export type UiTreeNode = HierarchyTreeNode | PropertiesTreeNode;
|
||||
|
||||
@@ -78,21 +78,21 @@ export const DiffType = {
|
||||
export class Terminal {}
|
||||
|
||||
export class UiTreeUtils {
|
||||
public static diffClass(item: UiTreeNode): string {
|
||||
static diffClass(item: UiTreeNode): string {
|
||||
const diffType = item.diffType;
|
||||
return diffType ?? '';
|
||||
}
|
||||
|
||||
public static isHighlighted(item: UiTreeNode, highlightedItems: Array<string>) {
|
||||
static isHighlighted(item: UiTreeNode, highlightedItems: string[]) {
|
||||
return item instanceof HierarchyTreeNode && highlightedItems.includes(`${item.stableId}`);
|
||||
}
|
||||
|
||||
public static isVisibleNode(kind: string, type?: string) {
|
||||
static isVisibleNode(kind: string, type?: string) {
|
||||
return kind === 'WindowState' || kind === 'Activity' || type?.includes('Layer');
|
||||
}
|
||||
|
||||
public static isParentNode(kind: string) {
|
||||
return this.PARENT_NODE_KINDS.includes(kind);
|
||||
static isParentNode(kind: string) {
|
||||
return UiTreeUtils.PARENT_NODE_KINDS.includes(kind);
|
||||
}
|
||||
|
||||
private static readonly PARENT_NODE_KINDS = [
|
||||
|
||||
@@ -26,12 +26,12 @@ abstract class ViewerInputMethod implements Viewer {
|
||||
this.addViewerEventListeners();
|
||||
}
|
||||
|
||||
public notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
this.presenter.notifyCurrentTraceEntries(entries);
|
||||
}
|
||||
|
||||
public abstract getViews(): View[];
|
||||
public abstract getDependencies(): TraceType[];
|
||||
abstract getViews(): View[];
|
||||
abstract getDependencies(): TraceType[];
|
||||
|
||||
protected imeUiCallback = (uiData: ImeUiData) => {
|
||||
// Angular does not deep watch @Input properties. Clearing inputData to null before repopulating
|
||||
|
||||
@@ -129,19 +129,19 @@ export class HierarchyComponent {
|
||||
|
||||
@Input() tree!: HierarchyTreeNode | null;
|
||||
@Input() tableProperties?: TableProperties | null;
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
@Input() pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
@Input() dependencies: TraceType[] = [];
|
||||
@Input() highlightedItems: string[] = [];
|
||||
@Input() pinnedItems: HierarchyTreeNode[] = [];
|
||||
@Input() store!: PersistentStore;
|
||||
@Input() userOptions: UserOptions = {};
|
||||
|
||||
constructor(@Inject(ElementRef) private elementRef: ElementRef) {}
|
||||
|
||||
public isFlattened() {
|
||||
isFlattened() {
|
||||
return this.userOptions['flat']?.enabled;
|
||||
}
|
||||
|
||||
public onPinnedNodeClick(event: MouseEvent, pinnedItem: HierarchyTreeNode) {
|
||||
onPinnedNodeClick(event: MouseEvent, pinnedItem: HierarchyTreeNode) {
|
||||
event.preventDefault();
|
||||
if (window.getSelection()?.type === 'range') {
|
||||
return;
|
||||
@@ -150,7 +150,7 @@ export class HierarchyComponent {
|
||||
this.selectedTreeChange(pinnedItem);
|
||||
}
|
||||
|
||||
public updateTree() {
|
||||
updateTree() {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.HierarchyUserOptionsChange, {
|
||||
bubbles: true,
|
||||
detail: {userOptions: this.userOptions},
|
||||
@@ -158,7 +158,7 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public filterTree() {
|
||||
filterTree() {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.HierarchyFilterChange, {
|
||||
bubbles: true,
|
||||
detail: {filterString: this.filterString},
|
||||
@@ -166,7 +166,7 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public highlightedItemChange(newId: string) {
|
||||
highlightedItemChange(newId: string) {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.HighlightedChange, {
|
||||
bubbles: true,
|
||||
detail: {id: newId},
|
||||
@@ -174,7 +174,7 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public selectedTreeChange(item: UiTreeNode) {
|
||||
selectedTreeChange(item: UiTreeNode) {
|
||||
if (!(item instanceof HierarchyTreeNode)) {
|
||||
return;
|
||||
}
|
||||
@@ -185,7 +185,7 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public pinnedItemChange(item: UiTreeNode) {
|
||||
pinnedItemChange(item: UiTreeNode) {
|
||||
if (!(item instanceof HierarchyTreeNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,25 +321,25 @@ import {ViewerEvents} from 'viewers/common/viewer_events';
|
||||
export class ImeAdditionalPropertiesComponent {
|
||||
@Input() additionalProperties!: ImeAdditionalProperties;
|
||||
@Input() isImeManagerService?: boolean;
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
@Input() highlightedItems: string[] = [];
|
||||
|
||||
constructor(@Inject(ElementRef) private elementRef: ElementRef) {}
|
||||
|
||||
public isHighlighted(item: any) {
|
||||
isHighlighted(item: any) {
|
||||
return UiTreeUtils.isHighlighted(item, this.highlightedItems);
|
||||
}
|
||||
|
||||
public formatProto(item: any) {
|
||||
formatProto(item: any) {
|
||||
if (item?.prettyPrint) {
|
||||
return item.prettyPrint();
|
||||
}
|
||||
}
|
||||
|
||||
public wmProtoOrNull() {
|
||||
wmProtoOrNull() {
|
||||
return this.additionalProperties.wm?.proto;
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderOrNull() {
|
||||
wmInsetsSourceProviderOrNull() {
|
||||
return this.additionalProperties.wm?.protoImeInsetsSourceProvider
|
||||
? Object.assign(
|
||||
{name: 'Ime Insets Source Provider'},
|
||||
@@ -348,56 +348,56 @@ export class ImeAdditionalPropertiesComponent {
|
||||
: null;
|
||||
}
|
||||
|
||||
public wmControlTargetFrameOrNull() {
|
||||
wmControlTargetFrameOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider
|
||||
?.controlTarget?.windowFrames?.frame || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderPositionOrNull() {
|
||||
wmInsetsSourceProviderPositionOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider?.control
|
||||
?.position || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderIsLeashReadyOrNull() {
|
||||
wmInsetsSourceProviderIsLeashReadyOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider
|
||||
?.isLeashReadyForDispatching || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderControllableOrNull() {
|
||||
wmInsetsSourceProviderControllableOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider
|
||||
?.controllable || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderSourceFrameOrNull() {
|
||||
wmInsetsSourceProviderSourceFrameOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider?.source
|
||||
?.frame || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderSourceVisibleOrNull() {
|
||||
wmInsetsSourceProviderSourceVisibleOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider?.source
|
||||
?.visible || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmInsetsSourceProviderSourceVisibleFrameOrNull() {
|
||||
wmInsetsSourceProviderSourceVisibleFrameOrNull() {
|
||||
return (
|
||||
this.additionalProperties.wm?.protoImeInsetsSourceProvider?.insetsSourceProvider?.source
|
||||
?.visibleFrame || 'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmImeControlTargetOrNull() {
|
||||
wmImeControlTargetOrNull() {
|
||||
return this.additionalProperties?.wm?.protoImeControlTarget
|
||||
? Object.assign(
|
||||
{name: 'IME Control Target'},
|
||||
@@ -406,26 +406,26 @@ export class ImeAdditionalPropertiesComponent {
|
||||
: null;
|
||||
}
|
||||
|
||||
public wmImeControlTargetTitleOrNull() {
|
||||
wmImeControlTargetTitleOrNull() {
|
||||
return (
|
||||
this.additionalProperties?.wm?.protoImeControlTarget?.windowContainer?.identifier?.title ||
|
||||
'null'
|
||||
);
|
||||
}
|
||||
|
||||
public wmImeInputTargetOrNull() {
|
||||
wmImeInputTargetOrNull() {
|
||||
return this.additionalProperties?.wm?.protoImeInputTarget
|
||||
? Object.assign({name: 'IME Input Target'}, this.additionalProperties.wm.protoImeInputTarget)
|
||||
: null;
|
||||
}
|
||||
|
||||
public wmImeInputTargetTitleOrNull() {
|
||||
wmImeInputTargetTitleOrNull() {
|
||||
return (
|
||||
this.additionalProperties?.wm?.protoImeInputTarget?.windowContainer?.identifier?.title ||
|
||||
'null'
|
||||
);
|
||||
}
|
||||
public wmImeLayeringTargetOrNull() {
|
||||
wmImeLayeringTargetOrNull() {
|
||||
return this.additionalProperties?.wm?.protoImeLayeringTarget
|
||||
? Object.assign(
|
||||
{name: 'IME Layering Target'},
|
||||
@@ -434,22 +434,22 @@ export class ImeAdditionalPropertiesComponent {
|
||||
: null;
|
||||
}
|
||||
|
||||
public wmImeLayeringTargetTitleOrNull() {
|
||||
wmImeLayeringTargetTitleOrNull() {
|
||||
return (
|
||||
this.additionalProperties?.wm?.protoImeLayeringTarget?.windowContainer?.identifier?.title ||
|
||||
'null'
|
||||
);
|
||||
}
|
||||
|
||||
public sfImeContainerScreenBoundsOrNull() {
|
||||
sfImeContainerScreenBoundsOrNull() {
|
||||
return this.additionalProperties.sf?.inputMethodSurface?.screenBounds || 'null';
|
||||
}
|
||||
|
||||
public sfImeContainerRectOrNull() {
|
||||
sfImeContainerRectOrNull() {
|
||||
return this.additionalProperties.sf?.inputMethodSurface?.rect || 'null';
|
||||
}
|
||||
|
||||
public isAllPropertiesNull() {
|
||||
isAllPropertiesNull() {
|
||||
if (this.isImeManagerService) {
|
||||
return !this.additionalProperties.wm;
|
||||
} else {
|
||||
@@ -457,7 +457,7 @@ export class ImeAdditionalPropertiesComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public onClickShowInPropertiesPanel(item: any, name?: string) {
|
||||
onClickShowInPropertiesPanel(item: any, name?: string) {
|
||||
if (item.id) {
|
||||
this.updateHighlightedItems(item.id);
|
||||
} else {
|
||||
@@ -475,7 +475,7 @@ export class ImeAdditionalPropertiesComponent {
|
||||
|
||||
private updateAdditionalPropertySelected(item: any, name?: string) {
|
||||
const itemWrapper = {
|
||||
name: name,
|
||||
name,
|
||||
proto: item,
|
||||
};
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.AdditionalPropertySelected, {
|
||||
|
||||
@@ -127,7 +127,7 @@ export class PropertiesComponent {
|
||||
|
||||
constructor(@Inject(ElementRef) private elementRef: ElementRef) {}
|
||||
|
||||
public filterTree() {
|
||||
filterTree() {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.PropertiesFilterChange, {
|
||||
bubbles: true,
|
||||
detail: {filterString: this.filterString},
|
||||
@@ -135,7 +135,7 @@ export class PropertiesComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public updateTree() {
|
||||
updateTree() {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.PropertiesUserOptionsChange, {
|
||||
bubbles: true,
|
||||
detail: {userOptions: this.userOptions},
|
||||
@@ -143,7 +143,7 @@ export class PropertiesComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public showNode(item: any) {
|
||||
showNode(item: any) {
|
||||
return (
|
||||
!(item instanceof Terminal) &&
|
||||
!(item.name instanceof Terminal) &&
|
||||
@@ -151,7 +151,7 @@ export class PropertiesComponent {
|
||||
);
|
||||
}
|
||||
|
||||
public isLeaf(item: any) {
|
||||
isLeaf(item: any) {
|
||||
return (
|
||||
!item.children ||
|
||||
item.children.length === 0 ||
|
||||
@@ -159,7 +159,7 @@ export class PropertiesComponent {
|
||||
);
|
||||
}
|
||||
|
||||
public itemIsSelected() {
|
||||
itemIsSelected() {
|
||||
return this.selectedFlickerItem && Object.keys(this.selectedFlickerItem).length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,26 +280,26 @@ import {Layer} from 'trace/flickerlib/common';
|
||||
export class PropertyGroupsComponent {
|
||||
@Input() item!: Layer;
|
||||
|
||||
public hasInputChannel() {
|
||||
hasInputChannel() {
|
||||
return this.item.proto?.inputWindowInfo;
|
||||
}
|
||||
|
||||
public getDestinationFrame() {
|
||||
getDestinationFrame() {
|
||||
const frame = this.item.proto?.destinationFrame;
|
||||
if (frame) {
|
||||
return ` left: ${frame.left}, top: ${frame.top}, right: ${frame.right}, bottom: ${frame.bottom}`;
|
||||
} else return '';
|
||||
}
|
||||
|
||||
public hasIgnoreDestinationFrame() {
|
||||
hasIgnoreDestinationFrame() {
|
||||
return (this.item.flags & 0x400) === 0x400;
|
||||
}
|
||||
|
||||
public formatFloat(num: number) {
|
||||
formatFloat(num: number) {
|
||||
return Math.round(num * 100) / 100;
|
||||
}
|
||||
|
||||
public summary(): TreeSummary {
|
||||
summary(): TreeSummary {
|
||||
const summary = [];
|
||||
|
||||
if (this.item?.visibilityReason?.length > 0) {
|
||||
|
||||
@@ -114,7 +114,7 @@ export class Canvas {
|
||||
this.labelRenderer.render(this.scene, this.camera);
|
||||
}
|
||||
|
||||
public getClickedRectId(x: number, y: number, z: number): undefined | string {
|
||||
getClickedRectId(x: number, y: number, z: number): undefined | string {
|
||||
const clickPosition = new THREE.Vector3(x, y, z);
|
||||
const raycaster = new THREE.Raycaster();
|
||||
raycaster.setFromCamera(clickPosition, this.camera!);
|
||||
@@ -231,7 +231,7 @@ export class Canvas {
|
||||
rectGeometry,
|
||||
new THREE.MeshBasicMaterial({
|
||||
color: this.getColor(rect),
|
||||
opacity: opacity,
|
||||
opacity,
|
||||
transparent: true,
|
||||
})
|
||||
);
|
||||
@@ -279,30 +279,28 @@ export class Canvas {
|
||||
}
|
||||
|
||||
private getColor(rect: Rect3D): THREE.Color {
|
||||
let color: THREE.Color = Canvas.RECT_COLOR_HIGHLIGHTED;
|
||||
switch (rect.colorType) {
|
||||
case ColorType.VISIBLE: {
|
||||
// green (darkness depends on z order)
|
||||
const red = ((200 - 45) * rect.darkFactor + 45) / 255;
|
||||
const green = ((232 - 182) * rect.darkFactor + 182) / 255;
|
||||
const blue = ((183 - 44) * rect.darkFactor + 44) / 255;
|
||||
color = new THREE.Color(red, green, blue);
|
||||
break;
|
||||
return new THREE.Color(red, green, blue);
|
||||
}
|
||||
case ColorType.NOT_VISIBLE: {
|
||||
// gray (darkness depends on z order)
|
||||
const lower = 120;
|
||||
const upper = 220;
|
||||
const darkness = ((upper - lower) * rect.darkFactor + lower) / 255;
|
||||
color = new THREE.Color(darkness, darkness, darkness);
|
||||
break;
|
||||
return new THREE.Color(darkness, darkness, darkness);
|
||||
}
|
||||
case ColorType.HIGHLIGHTED: {
|
||||
color = Canvas.RECT_COLOR_HIGHLIGHTED;
|
||||
break;
|
||||
return Canvas.RECT_COLOR_HIGHLIGHTED;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unexpected color type: ${rect.colorType}`);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private createRectBorders(rect: Rect3D, rectGeometry: THREE.ShapeGeometry): THREE.LineSegments {
|
||||
|
||||
@@ -134,7 +134,7 @@ class Mapper3D {
|
||||
const boundingBox = this.computeBoundingBox(rects3d, labels3d);
|
||||
|
||||
const scene: Scene3D = {
|
||||
boundingBox: boundingBox,
|
||||
boundingBox,
|
||||
camera: {
|
||||
rotationFactor: this.cameraRotationFactor,
|
||||
zoomFactor: this.zoomFactor,
|
||||
@@ -148,7 +148,7 @@ class Mapper3D {
|
||||
}
|
||||
|
||||
private selectRectsToDraw(rects: Rectangle[]): Rectangle[] {
|
||||
rects = rects.filter((rect) => rect.displayId == this.currentDisplayId);
|
||||
rects = rects.filter((rect) => rect.displayId === this.currentDisplayId);
|
||||
|
||||
if (this.showOnlyVisibleMode) {
|
||||
rects = rects.filter((rect) => rect.isVisible || rect.isDisplay);
|
||||
@@ -191,16 +191,16 @@ class Mapper3D {
|
||||
topLeft: {
|
||||
x: rect2d.topLeft.x,
|
||||
y: rect2d.topLeft.y,
|
||||
z: z,
|
||||
z,
|
||||
},
|
||||
bottomRight: {
|
||||
x: rect2d.bottomRight.x,
|
||||
y: rect2d.bottomRight.y,
|
||||
z: z,
|
||||
z,
|
||||
},
|
||||
isOversized: false,
|
||||
cornerRadius: rect2d.cornerRadius,
|
||||
darkFactor: darkFactor,
|
||||
darkFactor,
|
||||
colorType: this.getColorType(rect2d),
|
||||
isClickable: rect2d.isClickable,
|
||||
transform: this.getTransform(rect2d),
|
||||
@@ -346,7 +346,7 @@ class Mapper3D {
|
||||
linePoints: [lineStart, lineEnd],
|
||||
textCenter: lineEnd,
|
||||
text: rect2d.label,
|
||||
isHighlighted: isHighlighted,
|
||||
isHighlighted,
|
||||
rectId: rect2d.id,
|
||||
};
|
||||
labels3d.push(label3d);
|
||||
@@ -366,7 +366,7 @@ class Mapper3D {
|
||||
}
|
||||
|
||||
private computeBoundingBox(rects: Rect3D[], labels: Label3D[]): Box3D {
|
||||
if (rects.length == 0) {
|
||||
if (rects.length === 0) {
|
||||
return {
|
||||
width: 1,
|
||||
height: 1,
|
||||
@@ -424,10 +424,10 @@ class Mapper3D {
|
||||
const depth = maxZ - minZ;
|
||||
|
||||
return {
|
||||
width: width,
|
||||
height: height,
|
||||
depth: depth,
|
||||
center: center,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
center,
|
||||
diagonal: Math.sqrt(width * width + height * height + depth * depth),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -222,23 +222,23 @@ export class RectsComponent implements OnInit, OnDestroy {
|
||||
this.resizeObserver?.disconnect();
|
||||
}
|
||||
|
||||
public onSeparationSliderChange(factor: number) {
|
||||
onSeparationSliderChange(factor: number) {
|
||||
this.mapper3d.setZSpacingFactor(factor);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public onRotationSliderChange(factor: number) {
|
||||
onRotationSliderChange(factor: number) {
|
||||
this.mapper3d.setCameraRotationFactor(factor);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public resetCamera() {
|
||||
resetCamera() {
|
||||
this.mapper3d.resetCamera();
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
@HostListener('wheel', ['$event'])
|
||||
public onScroll(event: WheelEvent) {
|
||||
onScroll(event: WheelEvent) {
|
||||
if (event.deltaY > 0) {
|
||||
this.doZoomOut();
|
||||
} else {
|
||||
@@ -246,46 +246,46 @@ export class RectsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public onCanvasMouseDown(event: MouseEvent) {
|
||||
onCanvasMouseDown(event: MouseEvent) {
|
||||
document.addEventListener('mousemove', this.mouseMoveListener);
|
||||
document.addEventListener('mouseup', this.mouseUpListener);
|
||||
}
|
||||
|
||||
public onMouseMove(event: MouseEvent) {
|
||||
onMouseMove(event: MouseEvent) {
|
||||
const distance = new Distance2D(event.movementX, event.movementY);
|
||||
this.mapper3d.addPanScreenDistance(distance);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public onMouseUp(event: MouseEvent) {
|
||||
onMouseUp(event: MouseEvent) {
|
||||
document.removeEventListener('mousemove', this.mouseMoveListener);
|
||||
document.removeEventListener('mouseup', this.mouseUpListener);
|
||||
}
|
||||
|
||||
public onZoomInClick() {
|
||||
onZoomInClick() {
|
||||
this.doZoomIn();
|
||||
}
|
||||
|
||||
public onZoomOutClick() {
|
||||
onZoomOutClick() {
|
||||
this.doZoomOut();
|
||||
}
|
||||
|
||||
public onShowOnlyVisibleModeChange(enabled: boolean) {
|
||||
onShowOnlyVisibleModeChange(enabled: boolean) {
|
||||
this.mapper3d.setShowOnlyVisibleMode(enabled);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public onShowVirtualModeChange(enabled: boolean) {
|
||||
onShowVirtualModeChange(enabled: boolean) {
|
||||
this.mapper3d.setShowVirtualMode(enabled);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public onDisplayIdChange(id: number) {
|
||||
onDisplayIdChange(id: number) {
|
||||
this.mapper3d.setCurrentDisplayId(id);
|
||||
this.drawScene();
|
||||
}
|
||||
|
||||
public onRectClick(event: MouseEvent) {
|
||||
onRectClick(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
|
||||
const canvas = event.target as Element;
|
||||
@@ -323,7 +323,7 @@ export class RectsComponent implements OnInit, OnDestroy {
|
||||
private notifyHighlightedItem(id: string) {
|
||||
const event: CustomEvent = new CustomEvent(ViewerEvents.HighlightedChange, {
|
||||
bubbles: true,
|
||||
detail: {id: id},
|
||||
detail: {id},
|
||||
});
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
@@ -88,14 +88,14 @@ export class TreeComponent {
|
||||
// TODO (b/263779536): this array is passed down from viewers/presenters and is used to generate
|
||||
// an identifier supposed to be unique for each viewer. Let's just use a proper identifier
|
||||
// instead. Each viewer/presenter could pass down a random magic number, an UUID, ...
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
@Input() dependencies: TraceType[] = [];
|
||||
|
||||
@Input() item?: UiTreeNode;
|
||||
@Input() store!: PersistentStore;
|
||||
@Input() isFlattened? = false;
|
||||
@Input() initialDepth = 0;
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
@Input() pinnedItems?: Array<HierarchyTreeNode> = [];
|
||||
@Input() highlightedItems: string[] = [];
|
||||
@Input() pinnedItems?: HierarchyTreeNode[] = [];
|
||||
@Input() itemsClickable?: boolean;
|
||||
@Input() useGlobalCollapsedState?: boolean;
|
||||
@Input() isAlwaysCollapsed?: boolean;
|
||||
@@ -117,7 +117,7 @@ export class TreeComponent {
|
||||
readonly levelOffset = 24;
|
||||
nodeElement: HTMLElement;
|
||||
|
||||
public childTrackById(index: number, child: UiTreeNode): string {
|
||||
childTrackById(index: number, child: UiTreeNode): string {
|
||||
if (child.stableId !== undefined) {
|
||||
return child.stableId;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ export class TreeComponent {
|
||||
this.nodeElement?.removeEventListener('mouseleave', this.nodeMouseLeaveEventListener);
|
||||
}
|
||||
|
||||
public onNodeClick(event: MouseEvent) {
|
||||
onNodeClick(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
if (window.getSelection()?.type === 'range') {
|
||||
return;
|
||||
@@ -171,7 +171,7 @@ export class TreeComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public nodeOffsetStyle() {
|
||||
nodeOffsetStyle() {
|
||||
const offset = this.levelOffset * this.initialDepth + 'px';
|
||||
|
||||
return {
|
||||
@@ -186,38 +186,38 @@ export class TreeComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public isPinned() {
|
||||
isPinned() {
|
||||
if (this.item instanceof HierarchyTreeNode) {
|
||||
return this.pinnedItems?.map((item) => `${item.stableId}`).includes(`${this.item.stableId}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public propagateNewHighlightedItem(newId: string) {
|
||||
propagateNewHighlightedItem(newId: string) {
|
||||
this.highlightedItemChange.emit(newId);
|
||||
}
|
||||
|
||||
public propagateNewPinnedItem(newPinnedItem: UiTreeNode) {
|
||||
propagateNewPinnedItem(newPinnedItem: UiTreeNode) {
|
||||
this.pinnedItemChange.emit(newPinnedItem);
|
||||
}
|
||||
|
||||
public propagateNewSelectedTree(newTree: UiTreeNode) {
|
||||
propagateNewSelectedTree(newTree: UiTreeNode) {
|
||||
this.selectedTreeChange.emit(newTree);
|
||||
}
|
||||
|
||||
public isClickable() {
|
||||
isClickable() {
|
||||
return !this.isLeaf(this.item) || this.itemsClickable;
|
||||
}
|
||||
|
||||
public toggleTree() {
|
||||
toggleTree() {
|
||||
this.setCollapseValue(!this.isCollapsed());
|
||||
}
|
||||
|
||||
public expandTree() {
|
||||
expandTree() {
|
||||
this.setCollapseValue(true);
|
||||
}
|
||||
|
||||
public isCollapsed() {
|
||||
isCollapsed() {
|
||||
if (this.isAlwaysCollapsed || this.isLeaf(this.item)) {
|
||||
return true;
|
||||
}
|
||||
@@ -231,11 +231,11 @@ export class TreeComponent {
|
||||
return this.localCollapsedState;
|
||||
}
|
||||
|
||||
public children(): UiTreeNode[] {
|
||||
children(): UiTreeNode[] {
|
||||
return this.item?.children ?? [];
|
||||
}
|
||||
|
||||
public hasChildren() {
|
||||
hasChildren() {
|
||||
if (!this.item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,6 @@ describe('TreeComponent', () => {
|
||||
hasChildren = jasmine.createSpy().and.returnValue(true);
|
||||
|
||||
@ViewChild(TreeComponent)
|
||||
public treeComponent!: TreeComponent;
|
||||
treeComponent!: TreeComponent;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -73,42 +73,42 @@ export class TreeNodeComponent {
|
||||
this.collapseDiffClass = this.updateCollapseDiffClass();
|
||||
}
|
||||
|
||||
public isPropertiesTreeNode() {
|
||||
isPropertiesTreeNode() {
|
||||
return !(this.item instanceof HierarchyTreeNode);
|
||||
}
|
||||
|
||||
public showPinNodeIcon() {
|
||||
showPinNodeIcon() {
|
||||
return (
|
||||
(!this.isPropertiesTreeNode() && !UiTreeUtils.isParentNode(this.item.kind ?? '')) ?? false
|
||||
);
|
||||
}
|
||||
|
||||
public toggleTree(event: MouseEvent) {
|
||||
toggleTree(event: MouseEvent) {
|
||||
if (!this.isAlwaysCollapsed) {
|
||||
event.stopPropagation();
|
||||
this.toggleTreeChange.emit();
|
||||
}
|
||||
}
|
||||
|
||||
public showChevron() {
|
||||
showChevron() {
|
||||
return !this.isLeaf && !this.flattened && !this.isInPinnedSection;
|
||||
}
|
||||
|
||||
public showLeafNodeIcon() {
|
||||
showLeafNodeIcon() {
|
||||
return !this.showChevron() && !this.isInPinnedSection;
|
||||
}
|
||||
|
||||
public expandTree(event: MouseEvent) {
|
||||
expandTree(event: MouseEvent) {
|
||||
event.stopPropagation();
|
||||
this.expandTreeChange.emit();
|
||||
}
|
||||
|
||||
public pinNode(event: MouseEvent) {
|
||||
pinNode(event: MouseEvent) {
|
||||
event.stopPropagation();
|
||||
this.pinNodeChange.emit(this.item);
|
||||
}
|
||||
|
||||
public updateCollapseDiffClass() {
|
||||
updateCollapseDiffClass() {
|
||||
if (this.isCollapsed) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -62,6 +62,6 @@ describe('TreeNodeComponent', () => {
|
||||
};
|
||||
|
||||
@ViewChild(TreeNodeComponent)
|
||||
public treeNodeComponent!: TreeNodeComponent;
|
||||
treeNodeComponent!: TreeNodeComponent;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {Component, Input} from '@angular/core';
|
||||
import Chip from 'viewers/common/chip';
|
||||
import {Chip} from 'viewers/common/chip';
|
||||
import {HierarchyTreeNode, Terminal, UiTreeNode} from 'viewers/common/ui_tree_utils';
|
||||
import {treeNodeDataViewStyles} from 'viewers/components/styles/tree_node_data_view.styles';
|
||||
|
||||
@@ -36,24 +36,24 @@ import {treeNodeDataViewStyles} from 'viewers/components/styles/tree_node_data_v
|
||||
export class TreeNodeDataViewComponent {
|
||||
@Input() item!: UiTreeNode;
|
||||
|
||||
public chips() {
|
||||
chips() {
|
||||
return this.item instanceof HierarchyTreeNode ? this.item.chips : [];
|
||||
}
|
||||
|
||||
public itemShortName() {
|
||||
itemShortName() {
|
||||
return this.item instanceof HierarchyTreeNode && this.item.shortName
|
||||
? this.item.shortName
|
||||
: this.item.name;
|
||||
}
|
||||
|
||||
public itemTooltip() {
|
||||
itemTooltip() {
|
||||
if (this.item.name instanceof Terminal) {
|
||||
return '';
|
||||
}
|
||||
return this.item.name ?? '';
|
||||
}
|
||||
|
||||
public showShortName() {
|
||||
showShortName() {
|
||||
return (
|
||||
this.item instanceof HierarchyTreeNode &&
|
||||
this.item.simplifyNames &&
|
||||
@@ -62,7 +62,7 @@ export class TreeNodeDataViewComponent {
|
||||
);
|
||||
}
|
||||
|
||||
public chipClass(chip: Chip) {
|
||||
chipClass(chip: Chip) {
|
||||
return [
|
||||
'tree-view-internal-chip',
|
||||
'tree-view-chip',
|
||||
|
||||
@@ -33,20 +33,20 @@ import {treeNodePropertiesDataViewStyles} from 'viewers/components/styles/tree_n
|
||||
export class TreeNodePropertiesDataViewComponent {
|
||||
@Input() item!: PropertiesTreeNode;
|
||||
|
||||
public valueClass() {
|
||||
valueClass() {
|
||||
if (!this.item.propertyValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.item.propertyValue == 'null') {
|
||||
if (this.item.propertyValue === 'null') {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (this.item.propertyValue == 'true') {
|
||||
if (this.item.propertyValue === 'true') {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
if (this.item.propertyValue == 'false') {
|
||||
if (this.item.propertyValue === 'false') {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class ViewerFactory {
|
||||
ViewerScreenRecording,
|
||||
];
|
||||
|
||||
public createViewers(activeTraceTypes: Set<TraceType>, storage: Storage): Viewer[] {
|
||||
createViewers(activeTraceTypes: Set<TraceType>, storage: Storage): Viewer[] {
|
||||
const viewers: Viewer[] = [];
|
||||
|
||||
for (const Viewer of ViewerFactory.VIEWERS) {
|
||||
|
||||
@@ -33,7 +33,7 @@ class ViewerInputMethodClients extends ViewerInputMethod {
|
||||
return new PresenterInputMethodClients(this.imeUiCallback, this.getDependencies(), storage);
|
||||
}
|
||||
|
||||
public static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_CLIENTS];
|
||||
static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_CLIENTS];
|
||||
}
|
||||
|
||||
export {ViewerInputMethodClients};
|
||||
|
||||
@@ -42,7 +42,7 @@ class ViewerInputMethodManagerService extends ViewerInputMethod {
|
||||
);
|
||||
}
|
||||
|
||||
public static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_MANAGER_SERVICE];
|
||||
static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_MANAGER_SERVICE];
|
||||
}
|
||||
|
||||
export {ViewerInputMethodManagerService};
|
||||
|
||||
@@ -33,7 +33,7 @@ class ViewerInputMethodService extends ViewerInputMethod {
|
||||
return new PresenterInputMethodService(this.imeUiCallback, this.getDependencies(), storage);
|
||||
}
|
||||
|
||||
public static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_SERVICE];
|
||||
static readonly DEPENDENCIES: TraceType[] = [TraceType.INPUT_METHOD_SERVICE];
|
||||
}
|
||||
|
||||
export {ViewerInputMethodService};
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
class Events {
|
||||
public static LogLevelsFilterChanged = 'ViewerProtoLogEvent_LogLevelsFilterChanged';
|
||||
public static TagsFilterChanged = 'ViewerProtoLogEvent_TagsFilterChanged';
|
||||
public static SourceFilesFilterChanged = 'ViewerProtoLogEvent_SourceFilesFilterChanged';
|
||||
public static SearchStringFilterChanged = 'ViewerProtoLogEvent_SearchStringFilterChanged';
|
||||
static LogLevelsFilterChanged = 'ViewerProtoLogEvent_LogLevelsFilterChanged';
|
||||
static TagsFilterChanged = 'ViewerProtoLogEvent_TagsFilterChanged';
|
||||
static SourceFilesFilterChanged = 'ViewerProtoLogEvent_SourceFilesFilterChanged';
|
||||
static SearchStringFilterChanged = 'ViewerProtoLogEvent_SearchStringFilterChanged';
|
||||
}
|
||||
|
||||
export {Events};
|
||||
|
||||
@@ -27,7 +27,7 @@ export class Presenter {
|
||||
}
|
||||
|
||||
//TODO: replace input with something like iterator/cursor (same for other viewers/presenters)
|
||||
public notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
this.entry = entries.get(TraceType.PROTO_LOG) ? entries.get(TraceType.PROTO_LOG)[0] : undefined;
|
||||
if (this.uiData === UiData.EMPTY) {
|
||||
this.computeUiDataMessages();
|
||||
@@ -36,28 +36,28 @@ export class Presenter {
|
||||
this.notifyUiDataCallback(this.uiData);
|
||||
}
|
||||
|
||||
public onLogLevelsFilterChanged(levels: string[]) {
|
||||
onLogLevelsFilterChanged(levels: string[]) {
|
||||
this.levels = levels;
|
||||
this.computeUiDataMessages();
|
||||
this.computeUiDataCurrentMessageIndex();
|
||||
this.notifyUiDataCallback(this.uiData);
|
||||
}
|
||||
|
||||
public onTagsFilterChanged(tags: string[]) {
|
||||
onTagsFilterChanged(tags: string[]) {
|
||||
this.tags = tags;
|
||||
this.computeUiDataMessages();
|
||||
this.computeUiDataCurrentMessageIndex();
|
||||
this.notifyUiDataCallback(this.uiData);
|
||||
}
|
||||
|
||||
public onSourceFilesFilterChanged(files: string[]) {
|
||||
onSourceFilesFilterChanged(files: string[]) {
|
||||
this.files = files;
|
||||
this.computeUiDataMessages();
|
||||
this.computeUiDataCurrentMessageIndex();
|
||||
this.notifyUiDataCallback(this.uiData);
|
||||
}
|
||||
|
||||
public onSearchStringFilterChanged(searchString: string) {
|
||||
onSearchStringFilterChanged(searchString: string) {
|
||||
this.searchString = searchString;
|
||||
this.computeUiDataMessages();
|
||||
this.computeUiDataCurrentMessageIndex();
|
||||
@@ -82,7 +82,7 @@ export class Presenter {
|
||||
(message: LogMessage) => message.at
|
||||
);
|
||||
|
||||
let filteredMessagesAndOriginalIndex: [number, LogMessage][] = [
|
||||
let filteredMessagesAndOriginalIndex: Array<[number, LogMessage]> = [
|
||||
...this.entry!.messages.entries(),
|
||||
];
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ describe('ViewerProtoLogPresenter', () => {
|
||||
presenter.onLogLevelsFilterChanged([]);
|
||||
expect(outputUiData!.currentMessageIndex).toEqual(0);
|
||||
|
||||
(<ProtoLogTraceEntry>inputTraceEntries.get(TraceType.PROTO_LOG)[0]).currentMessageIndex = 1;
|
||||
(inputTraceEntries.get(TraceType.PROTO_LOG)[0] as ProtoLogTraceEntry).currentMessageIndex = 1;
|
||||
presenter.notifyCurrentTraceEntries(inputTraceEntries);
|
||||
presenter.onLogLevelsFilterChanged([]);
|
||||
expect(outputUiData!.currentMessageIndex).toEqual(1);
|
||||
|
||||
@@ -24,7 +24,7 @@ class UiData {
|
||||
public currentMessageIndex: undefined | number
|
||||
) {}
|
||||
|
||||
public static EMPTY = new UiData([], [], [], [], undefined);
|
||||
static EMPTY = new UiData([], [], [], [], undefined);
|
||||
}
|
||||
|
||||
export {UiData};
|
||||
|
||||
@@ -41,19 +41,19 @@ class ViewerProtoLog implements Viewer {
|
||||
});
|
||||
}
|
||||
|
||||
public notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
this.presenter.notifyCurrentTraceEntries(entries);
|
||||
}
|
||||
|
||||
public getViews(): View[] {
|
||||
getViews(): View[] {
|
||||
return [new View(ViewType.TAB, this.getDependencies(), this.htmlElement, 'ProtoLog')];
|
||||
}
|
||||
|
||||
public getDependencies(): TraceType[] {
|
||||
getDependencies(): TraceType[] {
|
||||
return ViewerProtoLog.DEPENDENCIES;
|
||||
}
|
||||
|
||||
public static readonly DEPENDENCIES: TraceType[] = [TraceType.PROTO_LOG];
|
||||
static readonly DEPENDENCIES: TraceType[] = [TraceType.PROTO_LOG];
|
||||
private htmlElement: HTMLElement;
|
||||
private presenter: Presenter;
|
||||
}
|
||||
|
||||
@@ -160,30 +160,30 @@ export class ViewerProtologComponent {
|
||||
}
|
||||
|
||||
@Input()
|
||||
public set inputData(data: UiData) {
|
||||
set inputData(data: UiData) {
|
||||
this.uiData = data;
|
||||
if (this.uiData.currentMessageIndex !== undefined && this.scrollComponent) {
|
||||
this.scrollComponent.scrollToIndex(this.uiData.currentMessageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public onLogLevelsChange(event: MatSelectChange) {
|
||||
onLogLevelsChange(event: MatSelectChange) {
|
||||
this.emitEvent(Events.LogLevelsFilterChanged, event.value);
|
||||
}
|
||||
|
||||
public onTagsChange(event: MatSelectChange) {
|
||||
onTagsChange(event: MatSelectChange) {
|
||||
this.emitEvent(Events.TagsFilterChanged, event.value);
|
||||
}
|
||||
|
||||
public onSourceFilesChange(event: MatSelectChange) {
|
||||
onSourceFilesChange(event: MatSelectChange) {
|
||||
this.emitEvent(Events.SourceFilesFilterChanged, event.value);
|
||||
}
|
||||
|
||||
public onSearchStringChange() {
|
||||
onSearchStringChange() {
|
||||
this.emitEvent(Events.SearchStringFilterChanged, this.searchString);
|
||||
}
|
||||
|
||||
public isCurrentMessage(index: number): boolean {
|
||||
isCurrentMessage(index: number): boolean {
|
||||
return index === this.uiData.currentMessageIndex;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ export class ViewerProtologComponent {
|
||||
|
||||
@ViewChild(CdkVirtualScrollViewport) scrollComponent!: CdkVirtualScrollViewport;
|
||||
|
||||
public uiData: UiData = UiData.EMPTY;
|
||||
uiData: UiData = UiData.EMPTY;
|
||||
private searchString = '';
|
||||
private elementRef: ElementRef;
|
||||
}
|
||||
|
||||
@@ -22,25 +22,25 @@ class ViewerScreenRecording implements Viewer {
|
||||
this.htmlElement = document.createElement('viewer-screen-recording');
|
||||
}
|
||||
|
||||
public notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
notifyCurrentTraceEntries(entries: Map<TraceType, any>): void {
|
||||
const entry: undefined | ScreenRecordingTraceEntry = entries.get(TraceType.SCREEN_RECORDING)
|
||||
? entries.get(TraceType.SCREEN_RECORDING)[0]
|
||||
: undefined;
|
||||
|
||||
(<any>this.htmlElement).currentTraceEntry = entry;
|
||||
(this.htmlElement as any).currentTraceEntry = entry;
|
||||
}
|
||||
|
||||
public getViews(): View[] {
|
||||
getViews(): View[] {
|
||||
return [
|
||||
new View(ViewType.OVERLAY, this.getDependencies(), this.htmlElement, 'ScreenRecording'),
|
||||
];
|
||||
}
|
||||
|
||||
public getDependencies(): TraceType[] {
|
||||
getDependencies(): TraceType[] {
|
||||
return ViewerScreenRecording.DEPENDENCIES;
|
||||
}
|
||||
|
||||
public static readonly DEPENDENCIES: TraceType[] = [TraceType.SCREEN_RECORDING];
|
||||
static readonly DEPENDENCIES: TraceType[] = [TraceType.SCREEN_RECORDING];
|
||||
private htmlElement: HTMLElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ class ViewerScreenRecordingComponent {
|
||||
}
|
||||
|
||||
@Input()
|
||||
public set currentTraceEntry(entry: undefined | ScreenRecordingTraceEntry) {
|
||||
set currentTraceEntry(entry: undefined | ScreenRecordingTraceEntry) {
|
||||
if (entry === undefined) {
|
||||
this.videoCurrentTime = undefined;
|
||||
return;
|
||||
@@ -123,13 +123,13 @@ class ViewerScreenRecordingComponent {
|
||||
this.videoCurrentTime = entry.videoTimeSeconds;
|
||||
}
|
||||
|
||||
public onMinimizeButtonClick() {
|
||||
onMinimizeButtonClick() {
|
||||
this.isMinimized = !this.isMinimized;
|
||||
}
|
||||
|
||||
public videoUrl: undefined | SafeUrl = undefined;
|
||||
public videoCurrentTime: number | undefined = undefined;
|
||||
public isMinimized = false;
|
||||
videoUrl: undefined | SafeUrl = undefined;
|
||||
videoCurrentTime: number | undefined = undefined;
|
||||
isMinimized = false;
|
||||
|
||||
private elementRef: ElementRef;
|
||||
private sanitizer: DomSanitizer;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user