Merge changes I2ab79fe4,I582d7c0d
* changes: Add ime_utils.ts Refactor tree_utils.ts
This commit is contained in:
committed by
Android (Google) Code Review
commit
2597772279
@@ -59,7 +59,7 @@ class ParserSurfaceFlinger extends Parser {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override processDecodedEntry(entryProto: any): any {
|
||||
override processDecodedEntry(entryProto: any): LayerTraceEntry {
|
||||
return LayerTraceEntry.fromProto(entryProto.layers.layers, entryProto.displays, entryProto.elapsedRealtimeNanos, entryProto.hwcBlob);
|
||||
}
|
||||
|
||||
|
||||
BIN
tools/winscope-ng/src/test/fixtures/traces/SurfaceFlinger_with_IME.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/SurfaceFlinger_with_IME.pb
vendored
Normal file
Binary file not shown.
BIN
tools/winscope-ng/src/test/fixtures/traces/WindowManager_with_IME.pb
vendored
Normal file
BIN
tools/winscope-ng/src/test/fixtures/traces/WindowManager_with_IME.pb
vendored
Normal file
Binary file not shown.
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HierarchyTree } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import Chip from "viewers/common/chip";
|
||||
|
||||
class HierarchyTreeBuilder {
|
||||
stableId = "";
|
||||
name = "";
|
||||
kind = "";
|
||||
children: HierarchyTree[] = [];
|
||||
children: HierarchyTreeNode[] = [];
|
||||
shortName?: string;
|
||||
type?: string;
|
||||
id?: string | number;
|
||||
@@ -76,7 +76,7 @@ class HierarchyTreeBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
setChildren(children: HierarchyTree[]) {
|
||||
setChildren(children: HierarchyTreeNode[]) {
|
||||
this.children = children;
|
||||
return this;
|
||||
}
|
||||
@@ -116,8 +116,8 @@ class HierarchyTreeBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): HierarchyTree {
|
||||
const node = new HierarchyTree(this.name, this.kind, this.stableId, this.children);
|
||||
build(): HierarchyTreeNode {
|
||||
const node = new HierarchyTreeNode(this.name, this.kind, this.stableId, this.children);
|
||||
|
||||
node.chips = this.chips;
|
||||
node.showInFilteredView = this.showInFilteredView;
|
||||
|
||||
108
tools/winscope-ng/src/viewers/common/ime_utils.spec.ts
Normal file
108
tools/winscope-ng/src/viewers/common/ime_utils.spec.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import {ImeUtils} from "./ime_utils";
|
||||
import {UnitTestUtils} from "test/unit/utils";
|
||||
|
||||
import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry";
|
||||
import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState";
|
||||
import {Timestamp, TimestampType} from "common/trace/timestamp";
|
||||
|
||||
async function getWindowManagerTraceEntry(): WindowManagerState {
|
||||
const parser = await UnitTestUtils.getParser("traces/WindowManager_with_IME.pb");
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 502938057652n);
|
||||
return parser.getTraceEntry(timestamp)!;
|
||||
}
|
||||
|
||||
async function getSurfaceFlingerTraceEntry(): LayerTraceEntry {
|
||||
const parser = await UnitTestUtils.getParser("traces/SurfaceFlinger_with_IME.pb");
|
||||
const timestamp = new Timestamp(TimestampType.ELAPSED, 502942319579n);
|
||||
return parser.getTraceEntry(timestamp);
|
||||
}
|
||||
|
||||
describe("ImeUtils", () => {
|
||||
it("processes WindowManager trace entry", async () => {
|
||||
const entry = await getWindowManagerTraceEntry();
|
||||
const processed = ImeUtils.processWindowManagerTraceEntry(entry);
|
||||
|
||||
expect(processed.focusedApp)
|
||||
.toEqual("com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity");
|
||||
|
||||
expect(processed.focusedActivity.token)
|
||||
.toEqual("9d8c2ef");
|
||||
expect(processed.focusedActivity.layerId)
|
||||
.toEqual(260);
|
||||
|
||||
expect(processed.focusedWindow.token)
|
||||
.toEqual("928b3d");
|
||||
expect(processed.focusedWindow.title)
|
||||
.toEqual("com.google.android.apps.messaging/com.google.android.apps.messaging.ui.search.ZeroStateSearchActivity");
|
||||
|
||||
expect(processed.protoImeControlTarget.windowContainer.identifier.title)
|
||||
.toEqual("com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity");
|
||||
expect(processed.protoImeControlTarget.windowContainer.identifier.hashCode)
|
||||
.toEqual(247026562);
|
||||
|
||||
expect(processed.protoImeInputTarget.windowContainer.identifier.title)
|
||||
.toEqual("com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity");
|
||||
expect(processed.protoImeInputTarget.windowContainer.identifier.hashCode)
|
||||
.toEqual(247026562);
|
||||
|
||||
expect(processed.protoImeInsetsSourceProvider
|
||||
.insetsSourceProvider).toBeDefined();
|
||||
|
||||
expect(processed.protoImeLayeringTarget.windowContainer.identifier.title)
|
||||
.toEqual("SnapshotStartingWindow for taskId=1393");
|
||||
expect(processed.protoImeLayeringTarget.windowContainer.identifier.hashCode)
|
||||
.toEqual(222907471);
|
||||
|
||||
expect(
|
||||
processed.isInputMethodWindowVisible)
|
||||
.toBeFalse();
|
||||
});
|
||||
|
||||
it("processes SurfaceFlinger trace entry", async () => {
|
||||
const processedWindowManagerState = ImeUtils.processWindowManagerTraceEntry(
|
||||
await getWindowManagerTraceEntry());
|
||||
const entry = await getSurfaceFlingerTraceEntry();
|
||||
const layers = ImeUtils.getImeLayers(entry, processedWindowManagerState)!;
|
||||
|
||||
expect(layers.inputMethodSurface.id)
|
||||
.toEqual(280);
|
||||
expect(layers.inputMethodSurface.isVisible)
|
||||
.toEqual(false);
|
||||
expect(layers.inputMethodSurface.rect.label).toEqual(
|
||||
"Surface(name=77f1069 InputMethod)/@0xb4afb8f - animation-leash of insets_animation#280");
|
||||
expect(layers.inputMethodSurface.screenBounds)
|
||||
.toBeDefined();
|
||||
|
||||
expect(layers.imeContainer.id)
|
||||
.toEqual(12);
|
||||
expect(layers.imeContainer.z).toEqual(1);
|
||||
expect(layers.imeContainer.zOrderRelativeOfId)
|
||||
.toEqual(115);
|
||||
|
||||
expect(String(layers.focusedWindow.color))
|
||||
.toEqual("r:0 g:0 b:0 a:1");
|
||||
|
||||
expect(layers.taskOfImeContainer.kind)
|
||||
.toEqual("SF subtree - 114");
|
||||
expect(layers.taskOfImeContainer.name)
|
||||
.toEqual("Task=1391#114");
|
||||
|
||||
expect(layers.taskOfImeSnapshot)
|
||||
.toBeUndefined();
|
||||
});
|
||||
});
|
||||
145
tools/winscope-ng/src/viewers/common/ime_utils.ts
Normal file
145
tools/winscope-ng/src/viewers/common/ime_utils.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import Activity from "common/trace/flickerlib/windows/Activity";
|
||||
import Layer from "common/trace/flickerlib/layers/Layer";
|
||||
import {LayerTraceEntry} from "common/trace/flickerlib/layers/LayerTraceEntry";
|
||||
import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState";
|
||||
import WindowState from "common/trace/flickerlib/windows/WindowState";
|
||||
import {TreeUtils, FilterType} from "./tree_utils";
|
||||
|
||||
class ProcessedWindowManagerState {
|
||||
constructor(
|
||||
public stableId: string,
|
||||
public focusedApp: string,
|
||||
public focusedWindow: WindowState,
|
||||
public focusedActivity: Activity,
|
||||
public isInputMethodWindowVisible: boolean,
|
||||
public protoImeControlTarget: any,
|
||||
public protoImeInputTarget: any,
|
||||
public protoImeLayeringTarget: any,
|
||||
public protoImeInsetsSourceProvider: any) {
|
||||
}
|
||||
}
|
||||
|
||||
class ImeLayers {
|
||||
constructor(
|
||||
public imeContainer: Layer,
|
||||
public inputMethodSurface: Layer,
|
||||
public focusedWindow: Layer|undefined,
|
||||
public taskOfImeContainer: Layer|undefined,
|
||||
public taskOfImeSnapshot: Layer|undefined) {
|
||||
}
|
||||
}
|
||||
|
||||
class ImeUtils {
|
||||
public static processWindowManagerTraceEntry(entry: WindowManagerState): ProcessedWindowManagerState {
|
||||
const displayContent = entry.root.children[0];
|
||||
|
||||
return new ProcessedWindowManagerState(
|
||||
entry.stableId,
|
||||
entry.focusedApp,
|
||||
entry.focusedWindow,
|
||||
entry.focusedActivity,
|
||||
this.isInputMethodVisible(displayContent),
|
||||
this.getImeControlTargetProperty(displayContent.proto),
|
||||
this.getImeInputTargetProperty(displayContent.proto),
|
||||
this.getImeLayeringTargetProperty(displayContent.proto),
|
||||
displayContent.proto.imeInsetsSourceProvider
|
||||
);
|
||||
}
|
||||
|
||||
public static getImeLayers(
|
||||
entry: LayerTraceEntry,
|
||||
processedWindowManagerState: ProcessedWindowManagerState): ImeLayers|undefined {
|
||||
const isImeContainer = TreeUtils.makeNodeFilter("ImeContainer");
|
||||
const imeContainer = TreeUtils.findDescendantNode(entry, isImeContainer);
|
||||
if (!imeContainer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isInputMethodSurface = TreeUtils.makeNodeFilter("InputMethod");
|
||||
const inputMethodSurface =
|
||||
TreeUtils.findDescendantNode(imeContainer, isInputMethodSurface);
|
||||
|
||||
let focusedWindowLayer: Layer = undefined;
|
||||
const focusedWindowToken = processedWindowManagerState.focusedWindow?.token;
|
||||
if (focusedWindowToken) {
|
||||
const isFocusedWindow = TreeUtils.makeNodeFilter(focusedWindowToken);
|
||||
focusedWindowLayer = TreeUtils.findDescendantNode(entry, isFocusedWindow);
|
||||
}
|
||||
|
||||
// we want to see both ImeContainer and IME-snapshot if there are
|
||||
// cases where both exist
|
||||
const taskLayerOfImeContainer =
|
||||
this.findAncestorTaskLayerOfImeLayer(entry, TreeUtils.makeNodeFilter("ImeContainer"));
|
||||
|
||||
const taskLayerOfImeSnapshot =
|
||||
this.findAncestorTaskLayerOfImeLayer(entry, TreeUtils.makeNodeFilter("IME-snapshot"));
|
||||
|
||||
return new ImeLayers(
|
||||
imeContainer,
|
||||
inputMethodSurface,
|
||||
focusedWindowLayer,
|
||||
taskLayerOfImeContainer,
|
||||
taskLayerOfImeSnapshot
|
||||
);
|
||||
}
|
||||
|
||||
private static findAncestorTaskLayerOfImeLayer(entry: LayerTraceEntry, isTargetImeLayer: FilterType): Layer {
|
||||
const imeLayer = TreeUtils.findDescendantNode(entry, isTargetImeLayer);
|
||||
if (!imeLayer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isTaskLayer = TreeUtils.makeNodeFilter("Task, ImePlaceholder");
|
||||
const taskLayer = <Layer>TreeUtils.findAncestorNode(imeLayer, isTaskLayer);
|
||||
if (!taskLayer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
taskLayer.kind = "SF subtree - " + taskLayer.id;
|
||||
return taskLayer;
|
||||
}
|
||||
|
||||
private static getImeControlTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ["inputMethodControlTarget", "imeControlTarget"];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static getImeInputTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ["inputMethodInputTarget", "imeInputTarget"];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static getImeLayeringTargetProperty(displayContentProto: any): any {
|
||||
const POSSIBLE_NAMES = ["inputMethodTarget", "imeLayeringTarget"];
|
||||
return this.findAnyPropertyWithMatchingName(displayContentProto, POSSIBLE_NAMES);
|
||||
}
|
||||
|
||||
private static findAnyPropertyWithMatchingName(object: any, possible_names: string[]): any {
|
||||
const key = Object.keys(object).find(key => possible_names.includes(key));
|
||||
return key ? object[key] : undefined;
|
||||
}
|
||||
|
||||
private static isInputMethodVisible(windowOrLayer: any) : boolean {
|
||||
const isInputMethod = TreeUtils.makeNodeFilter("InputMethod");
|
||||
const inputMethodWindowOrLayer =
|
||||
TreeUtils.findDescendantNode(windowOrLayer, isInputMethod);
|
||||
return inputMethodWindowOrLayer?.isVisible == true;
|
||||
}
|
||||
}
|
||||
|
||||
export {ImeUtils};
|
||||
@@ -13,12 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { DiffType, getFilter, HierarchyTree, TreeFlickerItem } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, DiffType, HierarchyTreeNode, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
|
||||
describe("TreeGenerator", () => {
|
||||
let entry: TreeFlickerItem;
|
||||
let entry: TreeNodeTrace;
|
||||
beforeAll(async () => {
|
||||
entry = {
|
||||
kind: "entry",
|
||||
@@ -26,44 +26,47 @@ describe("TreeGenerator", () => {
|
||||
stableId: "BaseLayerTraceEntry",
|
||||
id: 0,
|
||||
chips: [],
|
||||
parent: undefined,
|
||||
children: [{
|
||||
kind: "3",
|
||||
id: 3,
|
||||
name: "Child1",
|
||||
stableId: "3 Child1",
|
||||
parent: undefined,
|
||||
children: [
|
||||
{
|
||||
kind: "2",
|
||||
id: 2,
|
||||
name: "Child2",
|
||||
stableId: "2 Child2",
|
||||
children: []
|
||||
parent: undefined,
|
||||
children: [],
|
||||
}
|
||||
]}]
|
||||
};
|
||||
});
|
||||
it("generates tree", () => {
|
||||
const expected: HierarchyTree = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
const expected: HierarchyTreeNode = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
.setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child1").setStableId("3 Child1").setKind("3").setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child2").setStableId("2 Child2").setKind("2").setId(2).build()
|
||||
]).setId(3).build()
|
||||
]).setId(0).build();
|
||||
|
||||
const filter = getFilter("");
|
||||
const filter = TreeUtils.makeNodeFilter("");
|
||||
const generator = new TreeGenerator(entry, filter);
|
||||
expect(generator.generateTree()).toEqual(expected);
|
||||
});
|
||||
|
||||
it("generates diff tree with no diff", () => {
|
||||
const expected: HierarchyTree = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
const expected: HierarchyTreeNode = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
.setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child1").setStableId("3 Child1").setKind("3").setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child2").setStableId("2 Child2").setKind("2").setId(2).setDiffType(DiffType.NONE).build()
|
||||
]).setId(3).setDiffType(DiffType.NONE).build()
|
||||
]).setId(0).setDiffType(DiffType.NONE).build();
|
||||
|
||||
const filter = getFilter("");
|
||||
const filter = TreeUtils.makeNodeFilter("");
|
||||
const tree = new TreeGenerator(entry, filter).withUniqueNodeId((node: any) => {
|
||||
if (node) return node.stableId;
|
||||
else return null;
|
||||
@@ -72,19 +75,20 @@ describe("TreeGenerator", () => {
|
||||
});
|
||||
|
||||
it("generates diff tree with moved node", () => {
|
||||
const prevEntry: TreeFlickerItem = {
|
||||
const prevEntry: TreeNodeTrace = {
|
||||
kind: "entry",
|
||||
name: "BaseLayerTraceEntry",
|
||||
stableId: "BaseLayerTraceEntry",
|
||||
chips: [],
|
||||
id: 0,
|
||||
|
||||
parent: undefined,
|
||||
children: [
|
||||
{
|
||||
kind: "3",
|
||||
id: 3,
|
||||
stableId: "3 Child1",
|
||||
name: "Child1",
|
||||
parent: undefined,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
@@ -92,12 +96,13 @@ describe("TreeGenerator", () => {
|
||||
id: 2,
|
||||
stableId: "2 Child2",
|
||||
name: "Child2",
|
||||
parent: undefined,
|
||||
children: [],
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const expected: HierarchyTree = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
const expected: HierarchyTreeNode = new HierarchyTreeBuilder().setName("BaseLayerTraceEntry").setKind("entry").setStableId("BaseLayerTraceEntry")
|
||||
.setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child1").setStableId("3 Child1").setKind("3").setChildren([
|
||||
new HierarchyTreeBuilder().setName("Child2").setStableId("2 Child2").setKind("2").setId(2).setDiffType(DiffType.ADDED_MOVE).build()
|
||||
@@ -105,7 +110,7 @@ describe("TreeGenerator", () => {
|
||||
new HierarchyTreeBuilder().setName("Child2").setStableId("2 Child2").setKind("2").setId(2).setDiffType(DiffType.DELETED_MOVE).build()
|
||||
]).setId(0).setDiffType(DiffType.NONE).build();
|
||||
|
||||
const filter = getFilter("");
|
||||
const filter = TreeUtils.makeNodeFilter("");
|
||||
const generator = new TreeGenerator(entry, filter);
|
||||
const newDiffTree = generator.withUniqueNodeId((node: any) => {
|
||||
if (node) return node.stableId;
|
||||
|
||||
@@ -14,12 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
TreeUtils,
|
||||
FilterType,
|
||||
TreeFlickerItem,
|
||||
TreeNodeTrace,
|
||||
DiffType,
|
||||
isVisibleNode,
|
||||
isParentNode,
|
||||
HierarchyTree
|
||||
HierarchyTreeNode
|
||||
} from "./tree_utils";
|
||||
import ObjectFormatter from "common/trace/flickerlib/ObjectFormatter";
|
||||
import {
|
||||
@@ -31,8 +30,8 @@ import {
|
||||
RELATIVE_Z_PARENT_CHIP
|
||||
} from "viewers/common/chip";
|
||||
|
||||
type GetNodeIdCallbackType = (node: TreeFlickerItem | null) => string | null;
|
||||
type IsModifiedCallbackType = (newTree: TreeFlickerItem | null, oldTree: TreeFlickerItem | null) => boolean;
|
||||
type GetNodeIdCallbackType = (node: TreeNodeTrace | null) => string | null;
|
||||
type IsModifiedCallbackType = (newTree: TreeNodeTrace | null, oldTree: TreeNodeTrace | null) => boolean;
|
||||
|
||||
const HwcCompositionType = {
|
||||
CLIENT: 1,
|
||||
@@ -45,18 +44,18 @@ export class TreeGenerator {
|
||||
private isSimplifyNames = false;
|
||||
private isFlatView = false;
|
||||
private filter: FilterType;
|
||||
private inputEntry: TreeFlickerItem;
|
||||
private previousEntry: TreeFlickerItem | null = null;
|
||||
private inputEntry: TreeNodeTrace;
|
||||
private previousEntry: TreeNodeTrace | null = null;
|
||||
private getNodeId?: GetNodeIdCallbackType;
|
||||
private isModified?: IsModifiedCallbackType;
|
||||
private newMapping: Map<string, TreeFlickerItem> | null = null;
|
||||
private oldMapping: Map<string, TreeFlickerItem> | null = null;
|
||||
private newMapping: Map<string, TreeNodeTrace> | null = null;
|
||||
private oldMapping: Map<string, TreeNodeTrace> | null = null;
|
||||
private readonly pinnedIds: Array<string>;
|
||||
private pinnedItems: Array<HierarchyTree> = [];
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private relZParentIds: Array<string> = [];
|
||||
private flattenedChildren: Array<HierarchyTree> = [];
|
||||
private flattenedChildren: Array<HierarchyTreeNode> = [];
|
||||
|
||||
constructor(inputEntry: TreeFlickerItem, filter: FilterType, pinnedIds?: Array<string>) {
|
||||
constructor(inputEntry: TreeNodeTrace, filter: FilterType, pinnedIds?: Array<string>) {
|
||||
this.inputEntry = inputEntry;
|
||||
this.filter = filter;
|
||||
this.pinnedIds = pinnedIds ?? [];
|
||||
@@ -77,17 +76,17 @@ export class TreeGenerator {
|
||||
return this;
|
||||
}
|
||||
|
||||
public generateTree(): HierarchyTree | null {
|
||||
public generateTree(): HierarchyTreeNode | null {
|
||||
return this.getCustomisedTree(this.inputEntry);
|
||||
}
|
||||
|
||||
public compareWith(previousEntry: TreeFlickerItem | null): TreeGenerator {
|
||||
public compareWith(previousEntry: TreeNodeTrace | null): TreeGenerator {
|
||||
this.previousEntry = previousEntry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withUniqueNodeId(getNodeId?: GetNodeIdCallbackType): TreeGenerator {
|
||||
this.getNodeId = (node: TreeFlickerItem | null) => {
|
||||
this.getNodeId = (node: TreeNodeTrace | null) => {
|
||||
const id = getNodeId ? getNodeId(node) : this.defaultNodeIdCallback(node);
|
||||
if (id === null || id === undefined) {
|
||||
console.error("Null node ID for node", node);
|
||||
@@ -103,17 +102,18 @@ export class TreeGenerator {
|
||||
return this;
|
||||
}
|
||||
|
||||
public generateFinalTreeWithDiff(): HierarchyTree | null {
|
||||
public generateFinalTreeWithDiff(): HierarchyTreeNode | null {
|
||||
this.newMapping = this.generateIdToNodeMapping(this.inputEntry);
|
||||
this.oldMapping = this.previousEntry ? this.generateIdToNodeMapping(this.previousEntry) : null;
|
||||
|
||||
const diffTrees = this.generateDiffTree(this.inputEntry, this.previousEntry, [], []);
|
||||
|
||||
let diffTree;
|
||||
let diffTree: TreeNodeTrace;
|
||||
if (diffTrees.length > 1) {
|
||||
diffTree = {
|
||||
kind: "",
|
||||
name: "DiffTree",
|
||||
parent: undefined,
|
||||
children: diffTrees,
|
||||
stableId: "DiffTree",
|
||||
};
|
||||
@@ -123,7 +123,7 @@ export class TreeGenerator {
|
||||
return this.getCustomisedTree(diffTree);
|
||||
}
|
||||
|
||||
private getCustomisedTree(tree: TreeFlickerItem | null): HierarchyTree | null {
|
||||
private getCustomisedTree(tree: TreeNodeTrace | null): HierarchyTreeNode | null {
|
||||
if (!tree) return null;
|
||||
let newTree = this.generateTreeWithUserOptions(tree, false);
|
||||
if (!newTree) return null;
|
||||
@@ -136,14 +136,14 @@ export class TreeGenerator {
|
||||
return Object.freeze(newTree);
|
||||
}
|
||||
|
||||
public getPinnedItems(): Array<HierarchyTree> {
|
||||
public getPinnedItems(): Array<HierarchyTreeNode> {
|
||||
return this.pinnedItems;
|
||||
}
|
||||
|
||||
private flattenChildren(children: Array<HierarchyTree>) {
|
||||
private flattenChildren(children: Array<HierarchyTreeNode>) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
const childIsVisibleNode = child.isVisible && isVisibleNode(child.kind, child.type);
|
||||
const childIsVisibleNode = child.isVisible && TreeUtils.isVisibleNode(child.kind, child.type);
|
||||
const showInOnlyVisibleView = this.isOnlyVisibleView && childIsVisibleNode;
|
||||
const passVisibleCheck = !this.isOnlyVisibleView || showInOnlyVisibleView;
|
||||
if (this.filterMatches(child) && passVisibleCheck) {
|
||||
@@ -155,25 +155,25 @@ export class TreeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private filterMatches(item: HierarchyTree | null): boolean {
|
||||
private filterMatches(item: HierarchyTreeNode | null): boolean {
|
||||
return this.filter(item) ?? false;
|
||||
}
|
||||
|
||||
private generateTreeWithUserOptions(
|
||||
tree: TreeFlickerItem,
|
||||
tree: TreeNodeTrace,
|
||||
parentFilterMatch: boolean
|
||||
): HierarchyTree | null {
|
||||
): HierarchyTreeNode | null {
|
||||
return this.applyChecks(
|
||||
tree,
|
||||
parentFilterMatch
|
||||
);
|
||||
}
|
||||
|
||||
private updateTreeWithRelZParentChips(tree: HierarchyTree): HierarchyTree {
|
||||
private updateTreeWithRelZParentChips(tree: HierarchyTreeNode): HierarchyTreeNode {
|
||||
return this.applyRelZParentCheck(tree);
|
||||
}
|
||||
|
||||
private applyRelZParentCheck(tree: HierarchyTree) {
|
||||
private applyRelZParentCheck(tree: HierarchyTreeNode) {
|
||||
if (tree.id && tree.chips && this.relZParentIds.includes(`${tree.id}`)) {
|
||||
tree.chips.push(RELATIVE_Z_PARENT_CHIP);
|
||||
}
|
||||
@@ -186,7 +186,7 @@ export class TreeGenerator {
|
||||
return tree;
|
||||
}
|
||||
|
||||
private addChips(tree: HierarchyTree): HierarchyTree {
|
||||
private addChips(tree: HierarchyTreeNode): HierarchyTreeNode {
|
||||
tree.chips = [];
|
||||
if (tree.hwcCompositionType == HwcCompositionType.CLIENT) {
|
||||
tree.chips.push(GPU_CHIP);
|
||||
@@ -194,13 +194,13 @@ export class TreeGenerator {
|
||||
tree.hwcCompositionType == HwcCompositionType.SOLID_COLOR)) {
|
||||
tree.chips.push(HWC_CHIP);
|
||||
}
|
||||
if (tree.isVisible && isVisibleNode(tree.kind, tree.type)) {
|
||||
if (tree.isVisible && TreeUtils.isVisibleNode(tree.kind, tree.type)) {
|
||||
tree.chips.push(VISIBLE_CHIP);
|
||||
}
|
||||
if (
|
||||
tree.zOrderRelativeOfId !== undefined
|
||||
&& tree.zOrderRelativeOfId !== -1
|
||||
&& !isParentNode(tree.kind)
|
||||
&& !TreeUtils.isParentNode(tree.kind)
|
||||
&& !tree.isRootLayer
|
||||
) {
|
||||
tree.chips.push(RELATIVE_Z_CHIP);
|
||||
@@ -213,9 +213,9 @@ export class TreeGenerator {
|
||||
}
|
||||
|
||||
private applyChecks(
|
||||
tree: TreeFlickerItem,
|
||||
tree: TreeNodeTrace,
|
||||
parentFilterMatch: boolean
|
||||
): HierarchyTree | null {
|
||||
): HierarchyTreeNode | null {
|
||||
let newTree = this.getTreeNode(tree);
|
||||
|
||||
// add id field to tree if id does not exist (e.g. for WM traces)
|
||||
@@ -227,7 +227,7 @@ export class TreeGenerator {
|
||||
newTree.simplifyNames = this.isSimplifyNames;
|
||||
|
||||
// check item either matches filter, or has parents/children matching filter
|
||||
if (isParentNode(tree.kind) || parentFilterMatch) {
|
||||
if (TreeUtils.isParentNode(tree.kind) || parentFilterMatch) {
|
||||
newTree.showInFilteredView = true;
|
||||
} else {
|
||||
newTree.showInFilteredView = this.filterMatches(tree);
|
||||
@@ -271,8 +271,8 @@ export class TreeGenerator {
|
||||
return newTree;
|
||||
}
|
||||
|
||||
private generateIdToNodeMapping(node: TreeFlickerItem, acc?: Map<string, TreeFlickerItem>): Map<string, TreeFlickerItem> {
|
||||
acc = acc || new Map<string, TreeFlickerItem>();
|
||||
private generateIdToNodeMapping(node: TreeNodeTrace, acc?: Map<string, TreeNodeTrace>): Map<string, TreeNodeTrace> {
|
||||
acc = acc || new Map<string, TreeNodeTrace>();
|
||||
|
||||
const nodeId: string = this.getNodeId!(node)!;
|
||||
|
||||
@@ -289,7 +289,7 @@ export class TreeGenerator {
|
||||
return acc;
|
||||
}
|
||||
|
||||
private cloneDiffTreeNode(node: TreeFlickerItem | null): TreeFlickerItem | null {
|
||||
private cloneDiffTreeNode(node: TreeNodeTrace | null): TreeNodeTrace | null {
|
||||
const clone = ObjectFormatter.cloneObject(node);
|
||||
if (node) {
|
||||
clone.children = node.children;
|
||||
@@ -304,8 +304,8 @@ export class TreeGenerator {
|
||||
return clone;
|
||||
}
|
||||
|
||||
private getTreeNode(node: TreeFlickerItem): HierarchyTree {
|
||||
const clone = new HierarchyTree(
|
||||
private getTreeNode(node: TreeNodeTrace): HierarchyTreeNode {
|
||||
const clone = new HierarchyTreeNode(
|
||||
node.name,
|
||||
node.kind,
|
||||
node.stableId,
|
||||
@@ -327,11 +327,11 @@ export class TreeGenerator {
|
||||
}
|
||||
|
||||
private generateDiffTree(
|
||||
newTree: TreeFlickerItem | null,
|
||||
oldTree: TreeFlickerItem | null,
|
||||
newTreeSiblings: Array<TreeFlickerItem | null>,
|
||||
oldTreeSiblings: Array<TreeFlickerItem | null>
|
||||
): Array<TreeFlickerItem> {
|
||||
newTree: TreeNodeTrace | null,
|
||||
oldTree: TreeNodeTrace | null,
|
||||
newTreeSiblings: Array<TreeNodeTrace | null>,
|
||||
oldTreeSiblings: Array<TreeNodeTrace | null>
|
||||
): Array<TreeNodeTrace> {
|
||||
const diffTrees = [];
|
||||
// NOTE: A null ID represents a non existent node.
|
||||
if (!this.getNodeId) {
|
||||
@@ -350,9 +350,9 @@ export class TreeGenerator {
|
||||
// Default to no changes
|
||||
diffTree.diffType = DiffType.NONE;
|
||||
|
||||
if (!isParentNode(newTree.kind) && newId !== oldId) {
|
||||
if (!TreeUtils.isParentNode(newTree.kind) && newId !== oldId) {
|
||||
// A move, addition, or deletion has occurred
|
||||
let nextOldTree: TreeFlickerItem | null = null;
|
||||
let nextOldTree: TreeNodeTrace | null = null;
|
||||
|
||||
// Check if newTree has been added or moved
|
||||
if (newId && !oldTreeSiblingIds.includes(newId)) {
|
||||
@@ -422,7 +422,7 @@ export class TreeGenerator {
|
||||
return diffTrees;
|
||||
}
|
||||
|
||||
private visitChildren(newTree: TreeFlickerItem | null, oldTree: TreeFlickerItem | null): Array<TreeFlickerItem> {
|
||||
private visitChildren(newTree: TreeNodeTrace | null, oldTree: TreeNodeTrace | null): Array<TreeNodeTrace> {
|
||||
// Recursively traverse all children of new and old tree.
|
||||
const diffChildren = [];
|
||||
const numOfChildren = Math.max(newTree?.children?.length ?? 0, oldTree?.children?.length ?? 0);
|
||||
@@ -440,14 +440,14 @@ export class TreeGenerator {
|
||||
return diffChildren;
|
||||
}
|
||||
|
||||
private defaultNodeIdCallback(node: TreeFlickerItem | null): string | null {
|
||||
private defaultNodeIdCallback(node: TreeNodeTrace | null): string | null {
|
||||
return node ? node.stableId : null;
|
||||
}
|
||||
|
||||
private defaultModifiedCheck(newNode: TreeFlickerItem | null, oldNode: TreeFlickerItem | null): boolean {
|
||||
private defaultModifiedCheck(newNode: TreeNodeTrace | null, oldNode: TreeNodeTrace | null): boolean {
|
||||
if (!newNode && !oldNode) {
|
||||
return false;
|
||||
} else if (newNode && isParentNode(newNode.kind)) {
|
||||
} else if (newNode && TreeUtils.isParentNode(newNode.kind)) {
|
||||
return false;
|
||||
} else if ((newNode && !oldNode) || (!newNode && oldNode)) {
|
||||
return true;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import { DiffType, getFilter, HierarchyTree, Terminal, TreeFlickerItem } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, DiffType, HierarchyTreeNode, Terminal, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
|
||||
describe("TreeTransformer", () => {
|
||||
let entry: TreeFlickerItem;
|
||||
let selectedTree: HierarchyTree;
|
||||
let entry: TreeNodeTrace;
|
||||
let selectedTree: HierarchyTreeNode;
|
||||
beforeAll(async () => {
|
||||
entry = {
|
||||
id: 3,
|
||||
@@ -34,10 +34,12 @@ describe("TreeTransformer", () => {
|
||||
type: "ContainerLayer",
|
||||
},
|
||||
chips: [],
|
||||
parent: undefined,
|
||||
children: [{
|
||||
id: 2,
|
||||
name: "Child2",
|
||||
stackId: 0,
|
||||
parent: undefined,
|
||||
children: [],
|
||||
kind: "2",
|
||||
stableId: "2 Child2",
|
||||
@@ -104,7 +106,7 @@ describe("TreeTransformer", () => {
|
||||
propertyValue: null
|
||||
};
|
||||
|
||||
const filter = getFilter("");
|
||||
const filter = TreeUtils.makeNodeFilter("");
|
||||
const transformer = new TreeTransformer(selectedTree, filter)
|
||||
.showOnlyProtoDump()
|
||||
.setProperties(entry);
|
||||
@@ -145,7 +147,7 @@ describe("TreeTransformer", () => {
|
||||
propertyValue: null,
|
||||
};
|
||||
|
||||
const filter = getFilter("");
|
||||
const filter = TreeUtils.makeNodeFilter("");
|
||||
const transformer = new TreeTransformer(selectedTree, filter)
|
||||
.setIsShowDiff(true)
|
||||
.showOnlyProtoDump()
|
||||
|
||||
@@ -17,11 +17,11 @@ import ObjectFormatter from "common/trace/flickerlib/ObjectFormatter";
|
||||
|
||||
import {
|
||||
FilterType,
|
||||
PropertiesTree,
|
||||
PropertiesTreeNode,
|
||||
DiffType,
|
||||
Terminal,
|
||||
TreeFlickerItem,
|
||||
HierarchyTree,
|
||||
TreeNodeTrace,
|
||||
HierarchyTreeNode,
|
||||
PropertiesDump
|
||||
} from "./tree_utils";
|
||||
|
||||
@@ -49,7 +49,7 @@ export class TreeTransformer {
|
||||
keepOriginal: false, freeze: true, metadataKey: null,
|
||||
};
|
||||
|
||||
constructor(selectedTree: HierarchyTree, filter: FilterType) {
|
||||
constructor(selectedTree: HierarchyTreeNode, filter: FilterType) {
|
||||
this.stableId = this.compatibleStableId(selectedTree);
|
||||
this.rootName = selectedTree.name;
|
||||
this.filter = filter;
|
||||
@@ -79,7 +79,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setProperties(currentEntry: TreeFlickerItem): TreeTransformer {
|
||||
public setProperties(currentEntry: TreeNodeTrace): TreeTransformer {
|
||||
const currFlickerItem = this.getOriginalFlickerItem(currentEntry, this.stableId);
|
||||
const target = currFlickerItem ? currFlickerItem.obj ?? currFlickerItem : null;
|
||||
ObjectFormatter.displayDefaults = this.isShowDefaults;
|
||||
@@ -87,7 +87,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setDiffProperties(previousEntry: TreeFlickerItem | null): TreeTransformer {
|
||||
public setDiffProperties(previousEntry: TreeNodeTrace | null): TreeTransformer {
|
||||
if (this.isShowDiff) {
|
||||
const prevFlickerItem = this.findFlickerItem(previousEntry, this.stableId);
|
||||
const target = prevFlickerItem ? prevFlickerItem.obj ?? prevFlickerItem : null;
|
||||
@@ -96,11 +96,11 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public getOriginalFlickerItem(entry: TreeFlickerItem, stableId: string): TreeFlickerItem | null {
|
||||
public getOriginalFlickerItem(entry: TreeNodeTrace, stableId: string): TreeNodeTrace | null {
|
||||
return this.findFlickerItem(entry, stableId);
|
||||
}
|
||||
|
||||
private getProtoDumpPropertiesForDisplay(entry: TreeFlickerItem): PropertiesDump | null {
|
||||
private getProtoDumpPropertiesForDisplay(entry: TreeNodeTrace): PropertiesDump | null {
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ export class TreeTransformer {
|
||||
return obj;
|
||||
}
|
||||
|
||||
private getPropertiesForDisplay(entry: TreeFlickerItem): PropertiesDump | null {
|
||||
private getPropertiesForDisplay(entry: TreeNodeTrace): PropertiesDump | null {
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export class TreeTransformer {
|
||||
return obj;
|
||||
}
|
||||
|
||||
private findFlickerItem(entryFlickerItem: TreeFlickerItem | null, stableId: string): TreeFlickerItem | null {
|
||||
private findFlickerItem(entryFlickerItem: TreeNodeTrace | null, stableId: string): TreeNodeTrace | null {
|
||||
if (!entryFlickerItem) {
|
||||
return null;
|
||||
}
|
||||
@@ -179,7 +179,7 @@ export class TreeTransformer {
|
||||
}
|
||||
|
||||
|
||||
public transform(): PropertiesTree {
|
||||
public transform(): PropertiesTreeNode {
|
||||
const {formatter} = this.options!;
|
||||
if (!formatter) {
|
||||
throw new Error("Missing formatter, please set with setOptions()");
|
||||
@@ -198,7 +198,7 @@ export class TreeTransformer {
|
||||
compareWithName: string | Terminal,
|
||||
stableId: string,
|
||||
transformOptions: TransformOptions,
|
||||
): PropertiesTree {
|
||||
): PropertiesTreeNode {
|
||||
const originalProperties = properties;
|
||||
const metadata = this.getMetadata(
|
||||
originalProperties, transformOptions.metadataKey
|
||||
@@ -305,7 +305,7 @@ export class TreeTransformer {
|
||||
return transformOptions.freeze ? Object.freeze(transformedProperties) : transformedProperties;
|
||||
}
|
||||
|
||||
private hasChildMatchingFilter(children: PropertiesTree[] | null | undefined): boolean {
|
||||
private hasChildMatchingFilter(children: PropertiesTreeNode[] | null | undefined): boolean {
|
||||
if (!children || children.length === 0) return false;
|
||||
|
||||
let match = false;
|
||||
@@ -350,9 +350,9 @@ export class TreeTransformer {
|
||||
return this.filter(item) ?? false;
|
||||
}
|
||||
|
||||
private transformProperties(properties: PropertiesDump, metadataKey: string | null): PropertiesTree {
|
||||
private transformProperties(properties: PropertiesDump, metadataKey: string | null): PropertiesTreeNode {
|
||||
const {skip, formatter} = this.options!;
|
||||
const transformedProperties: PropertiesTree = {
|
||||
const transformedProperties: PropertiesTreeNode = {
|
||||
properties: {},
|
||||
};
|
||||
let formatted = undefined;
|
||||
@@ -399,7 +399,7 @@ export class TreeTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
private compatibleStableId(item: HierarchyTree): string {
|
||||
private compatibleStableId(item: HierarchyTreeNode): string {
|
||||
// For backwards compatibility
|
||||
// (the only item that doesn't have a unique stable ID in the tree)
|
||||
if (item.stableId === "winToken|-|") {
|
||||
|
||||
@@ -16,21 +16,49 @@
|
||||
|
||||
import Chip from "./chip";
|
||||
|
||||
export type FilterType = (item: HierarchyTree | PropertiesTree | null) => boolean;
|
||||
export type FilterType = (item: HierarchyTreeNode | PropertiesTreeNode | null) => boolean;
|
||||
|
||||
export type Tree = HierarchyTree | PropertiesTree;
|
||||
export type UiTreeNode = HierarchyTreeNode | PropertiesTreeNode;
|
||||
|
||||
export class HierarchyTree {
|
||||
export interface TreeNodeTrace {
|
||||
parent: TreeNodeTrace|undefined;
|
||||
children: TreeNodeTrace[];
|
||||
name: string;
|
||||
kind: string;
|
||||
stableId: string;
|
||||
displays?: TreeNodeTrace[];
|
||||
windowStates?: TreeNodeTrace[];
|
||||
shortName?: string;
|
||||
type?: string;
|
||||
id?: string | number;
|
||||
layerId?: number;
|
||||
displayId?: number;
|
||||
stackId?: number;
|
||||
isVisible?: boolean;
|
||||
isMissing?: boolean;
|
||||
hwcCompositionType?: number;
|
||||
zOrderRelativeOfId?: number;
|
||||
isRootLayer?: boolean;
|
||||
chips?: Chip[];
|
||||
diffType?: string;
|
||||
skip?: any;
|
||||
equals?: any;
|
||||
obj?: any;
|
||||
get?: any;
|
||||
proto?: any;
|
||||
}
|
||||
|
||||
export class HierarchyTreeNode {
|
||||
constructor(
|
||||
public name: string,
|
||||
public kind: string,
|
||||
public stableId: string,
|
||||
children?: HierarchyTree[]
|
||||
children?: HierarchyTreeNode[]
|
||||
) {
|
||||
this.children = children ?? [];
|
||||
}
|
||||
|
||||
children: HierarchyTree[];
|
||||
children: HierarchyTreeNode[];
|
||||
shortName?: string;
|
||||
type?: string;
|
||||
id?: string | number;
|
||||
@@ -52,42 +80,15 @@ export class HierarchyTree {
|
||||
skip?: any;
|
||||
}
|
||||
|
||||
export interface TreeFlickerItem {
|
||||
children: TreeFlickerItem[];
|
||||
name: string;
|
||||
kind: string;
|
||||
stableId: string;
|
||||
displays?: TreeFlickerItem[];
|
||||
windowStates?: TreeFlickerItem[];
|
||||
shortName?: string;
|
||||
type?: string;
|
||||
id?: string | number;
|
||||
layerId?: number;
|
||||
displayId?: number;
|
||||
stackId?: number;
|
||||
isVisible?: boolean;
|
||||
isMissing?: boolean;
|
||||
hwcCompositionType?: number;
|
||||
zOrderRelativeOfId?: number;
|
||||
isRootLayer?: boolean;
|
||||
chips?: Chip[];
|
||||
diffType?: string;
|
||||
skip?: any;
|
||||
equals?: any;
|
||||
obj?: any;
|
||||
get?: any;
|
||||
proto?: any;
|
||||
}
|
||||
|
||||
export interface PropertiesDump {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface PropertiesTree {
|
||||
export interface PropertiesTreeNode {
|
||||
properties?: any;
|
||||
kind?: string;
|
||||
stableId?: string;
|
||||
children?: PropertiesTree[];
|
||||
children?: PropertiesTreeNode[];
|
||||
propertyKey?: string | Terminal | null;
|
||||
propertyValue?: string | Terminal | null;
|
||||
name?: string | Terminal;
|
||||
@@ -106,46 +107,74 @@ export const DiffType = {
|
||||
|
||||
export class Terminal {}
|
||||
|
||||
export function diffClass(item: Tree): string {
|
||||
const diffType = item.diffType;
|
||||
return diffType ?? "";
|
||||
}
|
||||
|
||||
export function isHighlighted(item: Tree, highlightedItems: Array<string>) {
|
||||
return item instanceof HierarchyTree && highlightedItems.includes(`${item.id}`);
|
||||
}
|
||||
|
||||
export function getFilter(filterString: string): FilterType {
|
||||
const filterStrings = filterString.split(",");
|
||||
const positive: any[] = [];
|
||||
const negative: any[] = [];
|
||||
filterStrings.forEach((f) => {
|
||||
f = f.trim();
|
||||
if (f.startsWith("!")) {
|
||||
const regex = new RegExp(f.substring(1), "i");
|
||||
negative.push((s:any) => !regex.test(s));
|
||||
} else {
|
||||
const regex = new RegExp(f, "i");
|
||||
positive.push((s:any) => regex.test(s));
|
||||
export class TreeUtils
|
||||
{
|
||||
public static findDescendantNode(node: TreeNodeTrace, isTargetNode: FilterType): TreeNodeTrace|undefined {
|
||||
if (isTargetNode(node)) {
|
||||
return node;
|
||||
}
|
||||
});
|
||||
const filter = (item: any) => {
|
||||
if (item) {
|
||||
const apply = (f:any) => f(`${item.name}`);
|
||||
return (positive.length === 0 || positive.some(apply)) &&
|
||||
(negative.length === 0 || negative.every(apply));
|
||||
|
||||
for (const child of node.children) {
|
||||
const target = this.findDescendantNode(child, isTargetNode);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return filter;
|
||||
}
|
||||
|
||||
const parentNodeKinds = ["entry", "WindowManagerState"];
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isParentNode(kind: string) {
|
||||
return parentNodeKinds.includes(kind);
|
||||
}
|
||||
public static findAncestorNode(node: TreeNodeTrace, isTargetNode: FilterType): TreeNodeTrace|undefined {
|
||||
let ancestor = node.parent;
|
||||
|
||||
export function isVisibleNode(kind: string, type?: string) {
|
||||
return kind === "WindowState" || kind === "Activity" || type?.includes("Layer");
|
||||
while (ancestor && !isTargetNode(ancestor)) {
|
||||
ancestor = ancestor.parent;
|
||||
}
|
||||
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
public static makeNodeFilter(filterString: string): FilterType {
|
||||
const filterStrings = filterString.split(",");
|
||||
const positive: any[] = [];
|
||||
const negative: any[] = [];
|
||||
filterStrings.forEach((f) => {
|
||||
f = f.trim();
|
||||
if (f.startsWith("!")) {
|
||||
const regex = new RegExp(f.substring(1), "i");
|
||||
negative.push((s: any) => !regex.test(s));
|
||||
} else {
|
||||
const regex = new RegExp(f, "i");
|
||||
positive.push((s: any) => regex.test(s));
|
||||
}
|
||||
});
|
||||
const filter = (item: any) => {
|
||||
if (item) {
|
||||
const apply = (f: any) => f(`${item.name}`);
|
||||
return (positive.length === 0 || positive.some(apply)) &&
|
||||
(negative.length === 0 || negative.every(apply));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static diffClass(item: UiTreeNode): string {
|
||||
const diffType = item.diffType;
|
||||
return diffType ?? "";
|
||||
}
|
||||
|
||||
public static isHighlighted(item: UiTreeNode, highlightedItems: Array<string>) {
|
||||
return item instanceof HierarchyTreeNode && highlightedItems.includes(`${item.id}`);
|
||||
}
|
||||
|
||||
public 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);
|
||||
}
|
||||
|
||||
private static readonly PARENT_NODE_KINDS = ["entry", "WindowManagerState"];
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import { MatInputModule } from "@angular/material/input";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { HierarchyTree } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
|
||||
describe("HierarchyComponent", () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { Component, Input, Inject, ElementRef } from "@angular/core";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { PersistentStore } from "common/persistent_store";
|
||||
import { HierarchyTree, diffClass, isHighlighted, Tree } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, HierarchyTreeNode, UiTreeNode } from "viewers/common/tree_utils";
|
||||
import { nodeStyles } from "viewers/components/styles/node.styles";
|
||||
import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
@@ -147,13 +147,13 @@ import { TraceType } from "common/trace/trace_type";
|
||||
export class HierarchyComponent {
|
||||
objectKeys = Object.keys;
|
||||
filterString = "";
|
||||
diffClass = diffClass;
|
||||
isHighlighted = isHighlighted;
|
||||
diffClass = TreeUtils.diffClass;
|
||||
isHighlighted = TreeUtils.isHighlighted;
|
||||
|
||||
@Input() tree!: HierarchyTree | null;
|
||||
@Input() tree!: HierarchyTreeNode | null;
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
@Input() pinnedItems: Array<HierarchyTree> = [];
|
||||
@Input() pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
@Input() store!: PersistentStore;
|
||||
@Input() userOptions: UserOptions = {};
|
||||
|
||||
@@ -172,7 +172,7 @@ export class HierarchyComponent {
|
||||
};
|
||||
}
|
||||
|
||||
public onPinnedNodeClick(event: MouseEvent, pinnedItem: HierarchyTree) {
|
||||
public onPinnedNodeClick(event: MouseEvent, pinnedItem: HierarchyTreeNode) {
|
||||
event.preventDefault();
|
||||
if (window.getSelection()?.type === "range") {
|
||||
return;
|
||||
@@ -211,8 +211,8 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public selectedTreeChange(item: Tree) {
|
||||
if (!(item instanceof HierarchyTree)) {
|
||||
public selectedTreeChange(item: UiTreeNode) {
|
||||
if (!(item instanceof HierarchyTreeNode)) {
|
||||
return;
|
||||
}
|
||||
const event: CustomEvent = new CustomEvent(
|
||||
@@ -224,8 +224,8 @@ export class HierarchyComponent {
|
||||
this.elementRef.nativeElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
public pinnedItemChange(item: Tree) {
|
||||
if (!(item instanceof HierarchyTree)) {
|
||||
public pinnedItemChange(item: UiTreeNode) {
|
||||
if (!(item instanceof HierarchyTreeNode)) {
|
||||
return;
|
||||
}
|
||||
const event: CustomEvent = new CustomEvent(
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { Component, Input, Inject, ElementRef } from "@angular/core";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
import { PropertiesTree, Terminal, TreeFlickerItem } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode, Terminal, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "properties-view",
|
||||
@@ -134,8 +134,8 @@ export class PropertiesComponent {
|
||||
filterString = "";
|
||||
|
||||
@Input() userOptions: UserOptions = {};
|
||||
@Input() propertiesTree: PropertiesTree = {};
|
||||
@Input() selectedFlickerItem: TreeFlickerItem | null = null;
|
||||
@Input() propertiesTree: PropertiesTreeNode = {};
|
||||
@Input() selectedFlickerItem: TreeNodeTrace | null = null;
|
||||
@Input() propertyGroups = false;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { Component, Inject, Input, Output, ElementRef, EventEmitter } from "@angular/core";
|
||||
import { PersistentStore } from "common/persistent_store";
|
||||
import { nodeStyles, treeNodeDataViewStyles } from "viewers/components/styles/node.styles";
|
||||
import { Tree, diffClass, isHighlighted, PropertiesTree, Terminal, isParentNode, HierarchyTree } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, UiTreeNode, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
|
||||
@Component({
|
||||
@@ -77,17 +77,17 @@ import { TraceType } from "common/trace/trace_type";
|
||||
})
|
||||
|
||||
export class TreeComponent {
|
||||
diffClass = diffClass;
|
||||
isHighlighted = isHighlighted;
|
||||
diffClass = TreeUtils.diffClass;
|
||||
isHighlighted = TreeUtils.isHighlighted;
|
||||
|
||||
@Input() item!: Tree;
|
||||
@Input() item!: UiTreeNode;
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
@Input() store!: PersistentStore;
|
||||
@Input() isFlattened? = false;
|
||||
@Input() isShaded? = false;
|
||||
@Input() initialDepth = 0;
|
||||
@Input() highlightedItems: Array<string> = [];
|
||||
@Input() pinnedItems?: Array<HierarchyTree> = [];
|
||||
@Input() pinnedItems?: Array<HierarchyTreeNode> = [];
|
||||
@Input() itemsClickable?: boolean;
|
||||
@Input() useGlobalCollapsedState?: boolean;
|
||||
@Input() isAlwaysCollapsed?: boolean;
|
||||
@@ -95,8 +95,8 @@ export class TreeComponent {
|
||||
@Input() isLeaf: (item: any) => boolean = (item: any) => !item.children || item.children.length === 0;
|
||||
|
||||
@Output() highlightedItemChange = new EventEmitter<string>();
|
||||
@Output() selectedTreeChange = new EventEmitter<Tree>();
|
||||
@Output() pinnedItemChange = new EventEmitter<Tree>();
|
||||
@Output() selectedTreeChange = new EventEmitter<UiTreeNode>();
|
||||
@Output() pinnedItemChange = new EventEmitter<UiTreeNode>();
|
||||
@Output() hoverStart = new EventEmitter<void>();
|
||||
@Output() hoverEnd = new EventEmitter<void>();
|
||||
|
||||
@@ -123,7 +123,7 @@ export class TreeComponent {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
if (this.item instanceof HierarchyTree && isHighlighted(this.item, this.highlightedItems)) {
|
||||
if (this.item instanceof HierarchyTreeNode && TreeUtils.isHighlighted(this.item, this.highlightedItems)) {
|
||||
this.selectedTreeChange.emit(this.item);
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ export class TreeComponent {
|
||||
}
|
||||
|
||||
private updateHighlightedItems() {
|
||||
if (this.item instanceof HierarchyTree) {
|
||||
if (this.item instanceof HierarchyTreeNode) {
|
||||
if (this.item && this.item.id) {
|
||||
this.highlightedItemChange.emit(`${this.item.id}`);
|
||||
} else if (!this.item.id) {
|
||||
@@ -169,7 +169,7 @@ export class TreeComponent {
|
||||
}
|
||||
|
||||
public isPinned() {
|
||||
if (this.item instanceof HierarchyTree) {
|
||||
if (this.item instanceof HierarchyTreeNode) {
|
||||
return this.pinnedItems?.map(item => `${item.id}`).includes(`${this.item.id}`);
|
||||
}
|
||||
return false;
|
||||
@@ -179,11 +179,11 @@ export class TreeComponent {
|
||||
this.highlightedItemChange.emit(newId);
|
||||
}
|
||||
|
||||
public propagateNewPinnedItem(newPinnedItem: Tree) {
|
||||
public propagateNewPinnedItem(newPinnedItem: UiTreeNode) {
|
||||
this.pinnedItemChange.emit(newPinnedItem);
|
||||
}
|
||||
|
||||
public propagateNewSelectedTree(newTree: Tree) {
|
||||
public propagateNewSelectedTree(newTree: UiTreeNode) {
|
||||
this.selectedTreeChange.emit(newTree);
|
||||
}
|
||||
|
||||
@@ -211,12 +211,12 @@ export class TreeComponent {
|
||||
return this.localCollapsedState;
|
||||
}
|
||||
|
||||
public children(): Tree[] {
|
||||
public children(): UiTreeNode[] {
|
||||
return this.item.children ?? [];
|
||||
}
|
||||
|
||||
public hasChildren() {
|
||||
const isParentEntryInFlatView = isParentNode(this.item.kind ?? "") && this.isFlattened;
|
||||
const isParentEntryInFlatView = TreeUtils.isParentNode(this.item.kind ?? "") && this.isFlattened;
|
||||
return (!this.isFlattened || isParentEntryInFlatView) && !this.isLeaf(this.item);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Component, Input, Output, EventEmitter } from "@angular/core";
|
||||
import { nodeInnerItemStyles } from "viewers/components/styles/node.styles";
|
||||
import { Tree, DiffType, isParentNode, HierarchyTree } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, UiTreeNode, DiffType, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "tree-node",
|
||||
@@ -76,7 +76,7 @@ import { Tree, DiffType, isParentNode, HierarchyTree } from "viewers/common/tree
|
||||
})
|
||||
|
||||
export class TreeNodeComponent {
|
||||
@Input() item!: Tree;
|
||||
@Input() item!: UiTreeNode;
|
||||
@Input() isLeaf?: boolean;
|
||||
@Input() flattened?: boolean;
|
||||
@Input() isCollapsed?: boolean;
|
||||
@@ -87,7 +87,7 @@ export class TreeNodeComponent {
|
||||
|
||||
@Output() toggleTreeChange = new EventEmitter<void>();
|
||||
@Output() expandTreeChange = new EventEmitter<boolean>();
|
||||
@Output() pinNodeChange = new EventEmitter<Tree>();
|
||||
@Output() pinNodeChange = new EventEmitter<UiTreeNode>();
|
||||
|
||||
collapseDiffClass = "";
|
||||
|
||||
@@ -96,11 +96,11 @@ export class TreeNodeComponent {
|
||||
}
|
||||
|
||||
public isPropertiesTreeNode() {
|
||||
return !(this.item instanceof HierarchyTree);
|
||||
return !(this.item instanceof HierarchyTreeNode);
|
||||
}
|
||||
|
||||
public showPinNodeIcon() {
|
||||
return (!this.isPropertiesTreeNode() && !isParentNode(this.item.kind ?? "")) ?? false;
|
||||
return (!this.isPropertiesTreeNode() && !TreeUtils.isParentNode(this.item.kind ?? "")) ?? false;
|
||||
}
|
||||
|
||||
public toggleTree(event: MouseEvent) {
|
||||
@@ -148,7 +148,7 @@ export class TreeNodeComponent {
|
||||
return DiffType.MODIFIED;
|
||||
}
|
||||
|
||||
private getAllDiffTypesOfChildren(item: Tree) {
|
||||
private getAllDiffTypesOfChildren(item: UiTreeNode) {
|
||||
if (!item.children) {
|
||||
return new Set();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { treeNodeDataViewStyles } from "viewers/components/styles/tree_node_data_view.styles";
|
||||
import { Terminal, HierarchyTree, Tree } from "viewers/common/tree_utils";
|
||||
import { Terminal, HierarchyTreeNode, UiTreeNode } from "viewers/common/tree_utils";
|
||||
import Chip from "viewers/common/chip";
|
||||
|
||||
@Component({
|
||||
@@ -37,14 +37,14 @@ import Chip from "viewers/common/chip";
|
||||
})
|
||||
|
||||
export class TreeNodeDataViewComponent {
|
||||
@Input() item!: Tree;
|
||||
@Input() item!: UiTreeNode;
|
||||
|
||||
public chips() {
|
||||
return (this.item instanceof HierarchyTree) ? this.item.chips : [];
|
||||
return (this.item instanceof HierarchyTreeNode) ? this.item.chips : [];
|
||||
}
|
||||
|
||||
public itemShortName() {
|
||||
return (this.item instanceof HierarchyTree)? this.item.shortName : "";
|
||||
return (this.item instanceof HierarchyTreeNode)? this.item.shortName : "";
|
||||
}
|
||||
|
||||
public itemTooltip() {
|
||||
@@ -55,7 +55,7 @@ export class TreeNodeDataViewComponent {
|
||||
}
|
||||
|
||||
public showShortName() {
|
||||
return (this.item instanceof HierarchyTree) && this.item.simplifyNames && this.item.shortName !== this.item.name;
|
||||
return (this.item instanceof HierarchyTreeNode) && this.item.simplifyNames && this.item.shortName !== this.item.name;
|
||||
}
|
||||
|
||||
public chipClass(chip: Chip) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { treeNodePropertiesDataViewStyles } from "viewers/components/styles/tree_node_data_view.styles";
|
||||
import { PropertiesTree } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "tree-node-properties-data-view",
|
||||
@@ -30,7 +30,7 @@ import { PropertiesTree } from "viewers/common/tree_utils";
|
||||
})
|
||||
|
||||
export class TreeNodePropertiesDataViewComponent {
|
||||
@Input() item!: PropertiesTree;
|
||||
@Input() item!: PropertiesTreeNode;
|
||||
|
||||
public valueClass() {
|
||||
if (!this.item.propertyValue) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { UiData } from "./ui_data";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { LayerTraceEntry } from "common/trace/flickerlib/common";
|
||||
import { HierarchyTree, PropertiesTree } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { UnitTestUtils } from "test/unit/utils";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
|
||||
@@ -26,7 +26,7 @@ describe("PresenterSurfaceFlinger", () => {
|
||||
let presenter: Presenter;
|
||||
let uiData: UiData;
|
||||
let entries: Map<TraceType, any>;
|
||||
let selectedTree: HierarchyTree;
|
||||
let selectedTree: HierarchyTreeNode;
|
||||
|
||||
beforeAll(async () => {
|
||||
entries = new Map<TraceType, any>();
|
||||
@@ -182,14 +182,14 @@ describe("PresenterSurfaceFlinger", () => {
|
||||
presenter.notifyCurrentTraceEntries(entries);
|
||||
presenter.newPropertiesTree(selectedTree);
|
||||
let nonTerminalChildren = uiData.propertiesTree?.children?.filter(
|
||||
(child: PropertiesTree) => typeof child.propertyKey === "string"
|
||||
(child: PropertiesTreeNode) => typeof child.propertyKey === "string"
|
||||
) ?? [];
|
||||
|
||||
expect(nonTerminalChildren.length).toEqual(55);
|
||||
presenter.filterPropertiesTree("bound");
|
||||
|
||||
nonTerminalChildren = uiData.propertiesTree?.children?.filter(
|
||||
(child: PropertiesTree) => typeof child.propertyKey === "string"
|
||||
(child: PropertiesTreeNode) => typeof child.propertyKey === "string"
|
||||
) ?? [];
|
||||
expect(nonTerminalChildren.length).toEqual(3);
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ import { UiData } from "./ui_data";
|
||||
import { Rectangle, RectMatrix, RectTransform } from "viewers/common/rectangle";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { getFilter, FilterType, HierarchyTree, Tree, TreeFlickerItem, PropertiesTree } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, FilterType, HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import { Layer, LayerTraceEntry } from "common/trace/flickerlib/common";
|
||||
@@ -32,7 +32,7 @@ export class Presenter {
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updatePinnedItems(pinnedItem: HierarchyTree) {
|
||||
public 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);
|
||||
@@ -63,7 +63,7 @@ export class Presenter {
|
||||
}
|
||||
|
||||
public filterHierarchyTree(filterString: string) {
|
||||
this.hierarchyFilter = getFilter(filterString);
|
||||
this.hierarchyFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.uiData.tree = this.generateTree();
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
@@ -75,11 +75,11 @@ export class Presenter {
|
||||
}
|
||||
|
||||
public filterPropertiesTree(filterString: string) {
|
||||
this.propertiesFilter = getFilter(filterString);
|
||||
this.propertiesFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public newPropertiesTree(selectedItem: HierarchyTree) {
|
||||
public newPropertiesTree(selectedItem: HierarchyTreeNode) {
|
||||
this.selectedHierarchyTree = selectedItem;
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
@@ -145,7 +145,7 @@ export class Presenter {
|
||||
.setIsSimplifyNames(this.hierarchyUserOptions["simplifyNames"]?.enabled)
|
||||
.setIsFlatView(this.hierarchyUserOptions["flat"]?.enabled)
|
||||
.withUniqueNodeId();
|
||||
let tree: HierarchyTree | null;
|
||||
let tree: HierarchyTreeNode | null;
|
||||
if (!this.hierarchyUserOptions["showDiff"]?.enabled) {
|
||||
tree = generator.generateTree();
|
||||
} else {
|
||||
@@ -210,7 +210,7 @@ export class Presenter {
|
||||
}
|
||||
}
|
||||
|
||||
private getTreeWithTransformedProperties(selectedTree: HierarchyTree): PropertiesTree {
|
||||
private getTreeWithTransformedProperties(selectedTree: HierarchyTreeNode): PropertiesTreeNode {
|
||||
const transformer = new TreeTransformer(selectedTree, this.propertiesFilter)
|
||||
.showOnlyProtoDump()
|
||||
.setIsShowDefaults(this.propertiesUserOptions["showDefaults"]?.enabled)
|
||||
@@ -225,13 +225,13 @@ export class Presenter {
|
||||
|
||||
private readonly notifyViewCallback: NotifyViewCallbackType;
|
||||
private uiData: UiData;
|
||||
private hierarchyFilter: FilterType = getFilter("");
|
||||
private propertiesFilter: FilterType = getFilter("");
|
||||
private hierarchyFilter: FilterType = TreeUtils.makeNodeFilter("");
|
||||
private propertiesFilter: FilterType = TreeUtils.makeNodeFilter("");
|
||||
private highlightedItems: Array<string> = [];
|
||||
private displayIds: Array<number> = [];
|
||||
private pinnedItems: Array<HierarchyTree> = [];
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private pinnedIds: Array<string> = [];
|
||||
private selectedHierarchyTree: HierarchyTree | null = null;
|
||||
private selectedHierarchyTree: HierarchyTreeNode | null = null;
|
||||
private selectedLayer: LayerTraceEntry | Layer | null = null;
|
||||
private previousEntry: LayerTraceEntry | null = null;
|
||||
private entry: LayerTraceEntry | null = null;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HierarchyTree, PropertiesTree } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { Layer } from "common/trace/flickerlib/common";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
@@ -25,10 +25,10 @@ export class UiData {
|
||||
displayIds: number[] = [];
|
||||
hasVirtualDisplays = false;
|
||||
highlightedItems: Array<string> = [];
|
||||
pinnedItems: Array<HierarchyTree> = [];
|
||||
pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
hierarchyUserOptions: UserOptions = {};
|
||||
propertiesUserOptions: UserOptions = {};
|
||||
tree: HierarchyTree | null = null;
|
||||
propertiesTree: PropertiesTree | null = null;
|
||||
tree: HierarchyTreeNode | null = null;
|
||||
propertiesTree: PropertiesTreeNode | null = null;
|
||||
selectedLayer: Layer = {};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
9;/*
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -18,7 +18,7 @@ import { UiData } from "./ui_data";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { WindowManagerState } from "common/trace/flickerlib/common";
|
||||
import { PropertiesTree, Terminal, HierarchyTree } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode, Terminal, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { UnitTestUtils } from "test/unit/utils";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
import { VISIBLE_CHIP } from "viewers/common/chip";
|
||||
@@ -27,7 +27,7 @@ describe("PresenterWindowManager", () => {
|
||||
let presenter: Presenter;
|
||||
let uiData: UiData;
|
||||
let entries: Map<TraceType, any>;
|
||||
let selectedTree: HierarchyTree;
|
||||
let selectedTree: HierarchyTreeNode;
|
||||
|
||||
beforeAll(async () => {
|
||||
entries = new Map<TraceType, any>();
|
||||
@@ -187,14 +187,14 @@ describe("PresenterWindowManager", () => {
|
||||
presenter.newPropertiesTree(selectedTree);
|
||||
|
||||
let nonTerminalChildren = uiData.propertiesTree?.children?.filter(
|
||||
(child: PropertiesTree) => typeof child.propertyKey === "string"
|
||||
(child: PropertiesTreeNode) => typeof child.propertyKey === "string"
|
||||
) ?? [];
|
||||
|
||||
expect(nonTerminalChildren.length).toEqual(45);
|
||||
presenter.filterPropertiesTree("visible");
|
||||
|
||||
nonTerminalChildren = uiData.propertiesTree?.children?.filter(
|
||||
(child: PropertiesTree) => typeof child.propertyKey === "string"
|
||||
(child: PropertiesTreeNode) => typeof child.propertyKey === "string"
|
||||
) ?? [];
|
||||
expect(nonTerminalChildren.length).toEqual(4);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import { UiData } from "./ui_data";
|
||||
import { Rectangle, RectMatrix, RectTransform } from "viewers/common/rectangle";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { getFilter, FilterType, Tree, HierarchyTree, PropertiesTree, TreeFlickerItem } from "viewers/common/tree_utils";
|
||||
import { TreeUtils, FilterType, HierarchyTreeNode, PropertiesTreeNode, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import DisplayContent from "common/trace/flickerlib/windows/DisplayContent";
|
||||
@@ -31,7 +31,7 @@ export class Presenter {
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
|
||||
public updatePinnedItems(pinnedItem: HierarchyTree) {
|
||||
public 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);
|
||||
@@ -62,7 +62,7 @@ export class Presenter {
|
||||
}
|
||||
|
||||
public filterHierarchyTree(filterString: string) {
|
||||
this.hierarchyFilter = getFilter(filterString);
|
||||
this.hierarchyFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.uiData.tree = this.generateTree();
|
||||
this.notifyViewCallback(this.uiData);
|
||||
}
|
||||
@@ -74,11 +74,11 @@ export class Presenter {
|
||||
}
|
||||
|
||||
public filterPropertiesTree(filterString: string) {
|
||||
this.propertiesFilter = getFilter(filterString);
|
||||
this.propertiesFilter = TreeUtils.makeNodeFilter(filterString);
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
|
||||
public newPropertiesTree(selectedTree: HierarchyTree) {
|
||||
public newPropertiesTree(selectedTree: HierarchyTreeNode) {
|
||||
this.selectedHierarchyTree = selectedTree;
|
||||
this.updateSelectedTreeUiData();
|
||||
}
|
||||
@@ -143,7 +143,7 @@ export class Presenter {
|
||||
.setIsSimplifyNames(this.hierarchyUserOptions["simplifyNames"]?.enabled)
|
||||
.setIsFlatView(this.hierarchyUserOptions["flat"]?.enabled)
|
||||
.withUniqueNodeId();
|
||||
let tree: HierarchyTree | null;
|
||||
let tree: HierarchyTreeNode | null;
|
||||
if (!this.hierarchyUserOptions["showDiff"]?.enabled) {
|
||||
tree = generator.generateTree();
|
||||
} else {
|
||||
@@ -208,7 +208,7 @@ export class Presenter {
|
||||
}
|
||||
}
|
||||
|
||||
private getTreeWithTransformedProperties(selectedTree: HierarchyTree): PropertiesTree {
|
||||
private getTreeWithTransformedProperties(selectedTree: HierarchyTreeNode): PropertiesTreeNode {
|
||||
if (!this.entry) {
|
||||
return {};
|
||||
}
|
||||
@@ -225,15 +225,15 @@ export class Presenter {
|
||||
|
||||
private readonly notifyViewCallback: NotifyViewCallbackType;
|
||||
private uiData: UiData;
|
||||
private hierarchyFilter: FilterType = getFilter("");
|
||||
private propertiesFilter: FilterType = getFilter("");
|
||||
private hierarchyFilter: FilterType = TreeUtils.makeNodeFilter("");
|
||||
private propertiesFilter: FilterType = TreeUtils.makeNodeFilter("");
|
||||
private highlightedItems: Array<string> = [];
|
||||
private displayIds: Array<number> = [];
|
||||
private pinnedItems: Array<HierarchyTree> = [];
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private pinnedIds: Array<string> = [];
|
||||
private selectedHierarchyTree: HierarchyTree | null = null;
|
||||
private previousEntry: TreeFlickerItem | null = null;
|
||||
private entry: TreeFlickerItem | null = null;
|
||||
private selectedHierarchyTree: HierarchyTreeNode | null = null;
|
||||
private previousEntry: TreeNodeTrace | null = null;
|
||||
private entry: TreeNodeTrace | null = null;
|
||||
private hierarchyUserOptions: UserOptions = {
|
||||
showDiff: {
|
||||
name: "Show diff",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HierarchyTree, PropertiesTree } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { Rectangle } from "viewers/common/rectangle";
|
||||
@@ -23,9 +23,9 @@ export class UiData {
|
||||
rects: Rectangle[] = [];
|
||||
displayIds: number[] = [];
|
||||
highlightedItems: Array<string> = [];
|
||||
pinnedItems: Array<HierarchyTree> = [];
|
||||
pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
hierarchyUserOptions: UserOptions = {};
|
||||
propertiesUserOptions: UserOptions = {};
|
||||
tree: HierarchyTree | null = null;
|
||||
propertiesTree: PropertiesTree | null = null;
|
||||
tree: HierarchyTreeNode | null = null;
|
||||
propertiesTree: PropertiesTreeNode | null = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user