diff --git a/tools/winscope-ng/src/common/trace/flickerlib/Configuration.json b/tools/winscope-ng/src/common/trace/flickerlib/Configuration.json index dfa07dea2..857ba3090 100644 --- a/tools/winscope-ng/src/common/trace/flickerlib/Configuration.json +++ b/tools/winscope-ng/src/common/trace/flickerlib/Configuration.json @@ -14,6 +14,13 @@ "visibilityReason", "absoluteZ", "children", + "childWindows", + "childContainers", + "windowToken", + "rootDisplayArea", + "rootWindowContainer", + "windowContainer", + "children", "stableId" ], "intDefColumn": { diff --git a/tools/winscope-ng/src/common/trace/flickerlib/ObjectFormatter.ts b/tools/winscope-ng/src/common/trace/flickerlib/ObjectFormatter.ts index 3ed79fc01..89d5c8393 100644 --- a/tools/winscope-ng/src/common/trace/flickerlib/ObjectFormatter.ts +++ b/tools/winscope-ng/src/common/trace/flickerlib/ObjectFormatter.ts @@ -16,6 +16,8 @@ import {toSize, toActiveBuffer, toColor, toColor3, toPoint, toPointF, toRect, toRectF, toRegion, toMatrix22, toTransform} from './common'; +import { PropertiesDump } from "viewers/common/ui_tree_utils"; + import intDefMapping from '../../../../../../../prebuilts/misc/common/winscope/intDefMapping.json'; import config from './Configuration.json' @@ -88,11 +90,11 @@ export default class ObjectFormatter { * @param obj The raw object to format * @return The formatted object */ - static format(obj: any): any { + static format(obj: any): PropertiesDump { const properties = this.getProperties(obj); const sortedProperties = properties.sort() - const result: any = {} + const result: PropertiesDump = {}; sortedProperties.forEach(entry => { const key = entry; const value: any = obj[key]; diff --git a/tools/winscope-ng/src/parsers/parser.ts b/tools/winscope-ng/src/parsers/parser.ts index 6349f1b2e..a6084b92b 100644 --- a/tools/winscope-ng/src/parsers/parser.ts +++ b/tools/winscope-ng/src/parsers/parser.ts @@ -39,7 +39,7 @@ abstract class Parser { } } - this.decodedEntries = this.decodeTrace(traceBuffer); + this.decodedEntries = this.decodeTrace(traceBuffer).map((it) => this.addDefaultProtoFields(it)); for (const type of [TimestampType.ELAPSED, TimestampType.REAL]) { const timestamps: Timestamp[] = []; @@ -60,6 +60,39 @@ abstract class Parser { } } + // Add default values to the proto objects. + private addDefaultProtoFields(protoObj: any): any { + if (!protoObj || protoObj !== Object(protoObj) || !protoObj.$type) { + return protoObj; + } + + for (const fieldName in protoObj.$type.fields) { + if (protoObj.$type.fields.hasOwnProperty(fieldName)) { + const fieldProperties = protoObj.$type.fields[fieldName]; + const field = protoObj[fieldName]; + + if (Array.isArray(field)) { + field.forEach((item, _) => { + this.addDefaultProtoFields(item); + }); + continue; + } + + if (!field) { + protoObj[fieldName] = fieldProperties.defaultValue; + } + + if (fieldProperties.resolvedType && fieldProperties.resolvedType.valuesById) { + protoObj[fieldName] = fieldProperties.resolvedType.valuesById[protoObj[fieldProperties.name]]; + continue; + } + this.addDefaultProtoFields(protoObj[fieldName]); + } + } + + return protoObj; + } + public abstract getTraceType(): TraceType; public getTrace(): Trace { diff --git a/tools/winscope-ng/src/viewers/common/properties_tree_generator.ts b/tools/winscope-ng/src/viewers/common/properties_tree_generator.ts index 4bbc371e3..3e2079f86 100644 --- a/tools/winscope-ng/src/viewers/common/properties_tree_generator.ts +++ b/tools/winscope-ng/src/viewers/common/properties_tree_generator.ts @@ -48,6 +48,9 @@ class PropertiesTreeGenerator { } private leafToString(value: any): undefined|string { + if (value == null) { + return ""; + } if (typeof value === "boolean") { return "" + value; } diff --git a/tools/winscope-ng/src/viewers/common/tree_transformer.spec.ts b/tools/winscope-ng/src/viewers/common/tree_transformer.spec.ts index 876eb5837..2be56d749 100644 --- a/tools/winscope-ng/src/viewers/common/tree_transformer.spec.ts +++ b/tools/winscope-ng/src/viewers/common/tree_transformer.spec.ts @@ -86,12 +86,12 @@ describe("TreeTransformer", () => { children: [ { kind: "", - name: "id: empty", + name: "id: 3", stableId: "3 Child1.id", children: [], combined: true, propertyKey: "id", - propertyValue: "empty" + propertyValue: "3" }, { kind: "", @@ -124,13 +124,13 @@ describe("TreeTransformer", () => { children: [ { kind: "", - name: "id: empty", + name: "id: 3", diffType: DiffType.ADDED, stableId: "3 Child1.id", children: [], combined: true, propertyKey: "id", - propertyValue: "empty" + propertyValue: "3" }, { kind: "", diff --git a/tools/winscope-ng/src/viewers/common/tree_transformer.ts b/tools/winscope-ng/src/viewers/common/tree_transformer.ts index d47fc7d4e..c6ad1353a 100644 --- a/tools/winscope-ng/src/viewers/common/tree_transformer.ts +++ b/tools/winscope-ng/src/viewers/common/tree_transformer.ts @@ -105,19 +105,7 @@ export class TreeTransformer { return null; } - const obj: PropertiesDump = {}; - const proto = ObjectFormatter.format(entry.proto); - if (proto) { - Object.keys(proto).forEach((prop: string) => { - obj[prop] = proto[prop] ?? "empty"; - - if (Object.keys(obj[prop]).length === 0) { - obj[prop]= "empty"; - } - }); - } - - return obj; + return ObjectFormatter.format(entry.proto); } private getPropertiesForDisplay(entry: TraceTreeNode): PropertiesDump | null { @@ -125,38 +113,7 @@ export class TreeTransformer { return null; } - let obj: PropertiesDump = {}; - - const properties = ObjectFormatter.getProperties(entry); - properties.forEach(prop => { - obj[prop] = entry[prop as keyof typeof entry]; - }); - if (obj["children"]) delete obj["children"]; - if (obj["proto"]) delete obj["proto"]; - - if (entry.proto) { - obj["proto"] = Object.assign({}, entry.proto); - if (obj["proto"].children) delete obj["proto"].children; - if (obj["proto"].childWindows) delete obj["proto"].childWindows; - if (obj["proto"].childrenWindows) delete obj["proto"].childrenWindows; - if (obj["proto"].childContainers) delete obj["proto"].childContainers; - if (obj["proto"].windowToken) delete obj["proto"].windowToken; - if (obj["proto"].rootDisplayArea) delete obj["proto"].rootDisplayArea; - if (obj["proto"].rootWindowContainer) delete obj["proto"].rootWindowContainer; - if (obj["proto"].windowContainer?.children) delete obj["proto"].windowContainer.children; - } - - obj = ObjectFormatter.format(obj); - - if (obj["proto"]) { - Object.keys(obj["proto"]).forEach((prop: string) => { - if (Object.keys(obj["proto"][prop]).length === 0) { - obj["proto"][prop] = "empty"; - } - }); - } - - return obj; + return ObjectFormatter.format(entry); } private findFlickerItem(entryFlickerItem: TraceTreeNode | null, stableId: string): TraceTreeNode | null { @@ -210,7 +167,11 @@ export class TreeTransformer { const children: any[] = []; - if (properties && !this.isTerminal(properties)) { + if (properties === null) { + properties = "null"; + } + + if (!this.isTerminal(properties)) { const transformedProperties = this.transformProperties(properties, transformOptions.metadataKey); properties = transformedProperties.properties; } @@ -224,7 +185,7 @@ export class TreeTransformer { } for (const key in properties) { - if (!(properties instanceof Terminal) && properties[key]) { + if (!(properties instanceof Terminal)/* && properties[key]*/) { let compareWithChild = new Terminal(); let compareWithChildName = new Terminal(); if (compareWithProperties && !(compareWithProperties instanceof Terminal) && compareWithProperties[key]) { @@ -379,12 +340,18 @@ export class TreeTransformer { // Similar to above — primitive type node has no children. transformedProperties.properties["" + properties] = new Terminal(); } else if (properties && typeof properties == "object") { - Object.keys(properties).forEach((key) => { - if (key === metadataKey) { - return; - } - transformedProperties.properties[key] = properties[key]; - }); + // Empty objects + if (Object.keys(properties).length == 0) { + transformedProperties.properties["[empty]"] = new Terminal(); + } else { + // Non empty objects + Object.keys(properties).forEach((key) => { + if (key === metadataKey) { + return; + } + transformedProperties.properties[key] = properties[key]; + }); + } } else if (properties === null) { // Null object has no children — set to be terminal node. transformedProperties.properties.null = new Terminal(); diff --git a/tools/winscope-ng/src/viewers/viewer_surface_flinger/presenter.spec.ts b/tools/winscope-ng/src/viewers/viewer_surface_flinger/presenter.spec.ts index 0876c6704..9ea24d173 100644 --- a/tools/winscope-ng/src/viewers/viewer_surface_flinger/presenter.spec.ts +++ b/tools/winscope-ng/src/viewers/viewer_surface_flinger/presenter.spec.ts @@ -195,7 +195,7 @@ describe("PresenterSurfaceFlinger", () => { (child: PropertiesTreeNode) => typeof child.propertyKey === "string" ) ?? []; - expect(nonTerminalChildren.length).toEqual(21); + expect(nonTerminalChildren.length).toEqual(22); presenter.filterPropertiesTree("bound"); nonTerminalChildren = uiData.propertiesTree?.children?.filter( diff --git a/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.spec.ts b/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.spec.ts index 24c0b8478..529a0bfa5 100644 --- a/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.spec.ts +++ b/tools/winscope-ng/src/viewers/viewer_window_manager/presenter.spec.ts @@ -200,12 +200,12 @@ describe("PresenterWindowManager", () => { (child: PropertiesTreeNode) => typeof child.propertyKey === "string" ) ?? []; - expect(nonTerminalChildren.length).toEqual(15); + expect(nonTerminalChildren.length).toEqual(14); presenter.filterPropertiesTree("visible"); nonTerminalChildren = uiData.propertiesTree?.children?.filter( (child: PropertiesTreeNode) => typeof child.propertyKey === "string" ) ?? []; - expect(nonTerminalChildren.length).toEqual(2); + expect(nonTerminalChildren.length).toEqual(1); }); });