Refactor tree utils
Refactor tree utils for proper reuse from IME viewers: - add common/trace/trace_tree_node (factored out from viewers) - rename renaming viewers/common/tree_utils -> viewers/common/ui_tree_utils - add common/utils/tree_utils: generic tree utils reused from "trace" and "ui" Bug: 238088679 Test: npm run build:all && npm run test:all Change-Id: Ib14dd3495dc7e91e3a0eef2fdc20efa27fe1ef2e
This commit is contained in:
49
tools/winscope-ng/src/common/trace/trace_tree_node.ts
Normal file
49
tools/winscope-ng/src/common/trace/trace_tree_node.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
//TODO: remove
|
||||
import Chip from "viewers/common/chip";
|
||||
|
||||
export interface TraceTreeNode {
|
||||
children: TraceTreeNode[];
|
||||
name: string;
|
||||
kind: string;
|
||||
stableId: string;
|
||||
parent?: TraceTreeNode;
|
||||
displays?: TraceTreeNode[];
|
||||
windowStates?: TraceTreeNode[];
|
||||
client?: any;
|
||||
inputMethodService?: any;
|
||||
inputMethodManagerService?: any;
|
||||
where?: string;
|
||||
elapsedRealtimeNanos?: number;
|
||||
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;
|
||||
obj?: any;
|
||||
proto?: any;
|
||||
equals?: any;
|
||||
}
|
||||
82
tools/winscope-ng/src/common/utils/tree_utils.ts
Normal file
82
tools/winscope-ng/src/common/utils/tree_utils.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
interface TreeNode {
|
||||
name: string;
|
||||
parent?: TreeNode;
|
||||
children?: TreeNode[];
|
||||
}
|
||||
|
||||
type FilterType = (node: TreeNode | undefined | null) => boolean;
|
||||
|
||||
class TreeUtils
|
||||
{
|
||||
public static findDescendantNode(node: TreeNode, isTargetNode: FilterType): TreeNode|undefined {
|
||||
if (isTargetNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!node.children) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
const target = this.findDescendantNode(child, isTargetNode);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public static findAncestorNode(node: TreeNode, isTargetNode: FilterType): TreeNode|undefined {
|
||||
let ancestor = node.parent;
|
||||
|
||||
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: TreeNode | undefined | null) => {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
export {TreeNode, TreeUtils, FilterType};
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import Chip from "viewers/common/chip";
|
||||
|
||||
class HierarchyTreeBuilder {
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
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 {WindowContainer} from "common/trace/flickerlib/common";
|
||||
import {WindowManagerState} from "common/trace/flickerlib/windows/WindowManagerState";
|
||||
import WindowState from "common/trace/flickerlib/windows/WindowState";
|
||||
import {TreeUtils, FilterType} from "./tree_utils";
|
||||
import {TreeUtils, FilterType} from "common/utils/tree_utils";
|
||||
|
||||
class ProcessedWindowManagerState {
|
||||
constructor(
|
||||
@@ -134,10 +135,10 @@ class ImeUtils {
|
||||
return key ? object[key] : undefined;
|
||||
}
|
||||
|
||||
private static isInputMethodVisible(windowOrLayer: any) : boolean {
|
||||
private static isInputMethodVisible(displayContent: WindowContainer) : boolean {
|
||||
const isInputMethod = TreeUtils.makeNodeFilter("InputMethod");
|
||||
const inputMethodWindowOrLayer =
|
||||
TreeUtils.findDescendantNode(windowOrLayer, isInputMethod);
|
||||
<WindowContainer>TreeUtils.findDescendantNode(displayContent, isInputMethod);
|
||||
return inputMethodWindowOrLayer?.isVisible == true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { TreeUtils, DiffType, HierarchyTreeNode, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import { TraceTreeNode } from "common/trace/trace_tree_node";
|
||||
import { TreeUtils } from "common/utils/tree_utils";
|
||||
import { DiffType, HierarchyTreeNode} from "viewers/common/ui_tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
|
||||
describe("TreeGenerator", () => {
|
||||
let entry: TreeNodeTrace;
|
||||
let entry: TraceTreeNode;
|
||||
beforeAll(async () => {
|
||||
entry = {
|
||||
kind: "entry",
|
||||
@@ -75,7 +77,7 @@ describe("TreeGenerator", () => {
|
||||
});
|
||||
|
||||
it("generates diff tree with moved node", () => {
|
||||
const prevEntry: TreeNodeTrace = {
|
||||
const prevEntry: TraceTreeNode = {
|
||||
kind: "entry",
|
||||
name: "BaseLayerTraceEntry",
|
||||
stableId: "BaseLayerTraceEntry",
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {FilterType} from "common/utils/tree_utils";
|
||||
import {TraceTreeNode} from "common/trace/trace_tree_node";
|
||||
import {
|
||||
TreeUtils,
|
||||
FilterType,
|
||||
TreeNodeTrace,
|
||||
UiTreeUtils,
|
||||
DiffType,
|
||||
HierarchyTreeNode
|
||||
} from "./tree_utils";
|
||||
} from "./ui_tree_utils";
|
||||
import ObjectFormatter from "common/trace/flickerlib/ObjectFormatter";
|
||||
import {
|
||||
HWC_CHIP,
|
||||
@@ -30,8 +30,8 @@ import {
|
||||
RELATIVE_Z_PARENT_CHIP
|
||||
} from "viewers/common/chip";
|
||||
|
||||
type GetNodeIdCallbackType = (node: TreeNodeTrace | null) => string | null;
|
||||
type IsModifiedCallbackType = (newTree: TreeNodeTrace | null, oldTree: TreeNodeTrace | null) => boolean;
|
||||
type GetNodeIdCallbackType = (node: TraceTreeNode | null) => string | null;
|
||||
type IsModifiedCallbackType = (newTree: TraceTreeNode | null, oldTree: TraceTreeNode | null) => boolean;
|
||||
|
||||
const HwcCompositionType = {
|
||||
CLIENT: 1,
|
||||
@@ -44,18 +44,18 @@ export class TreeGenerator {
|
||||
private isSimplifyNames = false;
|
||||
private isFlatView = false;
|
||||
private filter: FilterType;
|
||||
private inputEntry: TreeNodeTrace;
|
||||
private previousEntry: TreeNodeTrace | null = null;
|
||||
private inputEntry: TraceTreeNode;
|
||||
private previousEntry: TraceTreeNode | null = null;
|
||||
private getNodeId?: GetNodeIdCallbackType;
|
||||
private isModified?: IsModifiedCallbackType;
|
||||
private newMapping: Map<string, TreeNodeTrace> | null = null;
|
||||
private oldMapping: Map<string, TreeNodeTrace> | null = null;
|
||||
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> = [];
|
||||
|
||||
constructor(inputEntry: TreeNodeTrace, filter: FilterType, pinnedIds?: Array<string>) {
|
||||
constructor(inputEntry: TraceTreeNode, filter: FilterType, pinnedIds?: Array<string>) {
|
||||
this.inputEntry = inputEntry;
|
||||
this.filter = filter;
|
||||
this.pinnedIds = pinnedIds ?? [];
|
||||
@@ -80,13 +80,13 @@ export class TreeGenerator {
|
||||
return this.getCustomisedTree(this.inputEntry);
|
||||
}
|
||||
|
||||
public compareWith(previousEntry: TreeNodeTrace | null): TreeGenerator {
|
||||
public compareWith(previousEntry: TraceTreeNode | null): TreeGenerator {
|
||||
this.previousEntry = previousEntry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withUniqueNodeId(getNodeId?: GetNodeIdCallbackType): TreeGenerator {
|
||||
this.getNodeId = (node: TreeNodeTrace | null) => {
|
||||
this.getNodeId = (node: TraceTreeNode | null) => {
|
||||
const id = getNodeId ? getNodeId(node) : this.defaultNodeIdCallback(node);
|
||||
if (id === null || id === undefined) {
|
||||
console.error("Null node ID for node", node);
|
||||
@@ -108,7 +108,7 @@ export class TreeGenerator {
|
||||
|
||||
const diffTrees = this.generateDiffTree(this.inputEntry, this.previousEntry, [], []);
|
||||
|
||||
let diffTree: TreeNodeTrace;
|
||||
let diffTree: TraceTreeNode;
|
||||
if (diffTrees.length > 1) {
|
||||
diffTree = {
|
||||
kind: "",
|
||||
@@ -123,7 +123,7 @@ export class TreeGenerator {
|
||||
return this.getCustomisedTree(diffTree);
|
||||
}
|
||||
|
||||
private getCustomisedTree(tree: TreeNodeTrace | null): HierarchyTreeNode | null {
|
||||
private getCustomisedTree(tree: TraceTreeNode | null): HierarchyTreeNode | null {
|
||||
if (!tree) return null;
|
||||
let newTree = this.generateTreeWithUserOptions(tree, false);
|
||||
if (!newTree) return null;
|
||||
@@ -143,7 +143,7 @@ export class TreeGenerator {
|
||||
private flattenChildren(children: Array<HierarchyTreeNode>) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i];
|
||||
const childIsVisibleNode = child.isVisible && TreeUtils.isVisibleNode(child.kind, child.type);
|
||||
const childIsVisibleNode = child.isVisible && UiTreeUtils.isVisibleNode(child.kind, child.type);
|
||||
const showInOnlyVisibleView = this.isOnlyVisibleView && childIsVisibleNode;
|
||||
const passVisibleCheck = !this.isOnlyVisibleView || showInOnlyVisibleView;
|
||||
if (this.filterMatches(child) && passVisibleCheck) {
|
||||
@@ -155,12 +155,12 @@ export class TreeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private filterMatches(item: HierarchyTreeNode | null): boolean {
|
||||
private filterMatches(item?: HierarchyTreeNode | null): boolean {
|
||||
return this.filter(item) ?? false;
|
||||
}
|
||||
|
||||
private generateTreeWithUserOptions(
|
||||
tree: TreeNodeTrace,
|
||||
tree: TraceTreeNode,
|
||||
parentFilterMatch: boolean
|
||||
): HierarchyTreeNode | null {
|
||||
return this.applyChecks(
|
||||
@@ -194,13 +194,13 @@ export class TreeGenerator {
|
||||
tree.hwcCompositionType == HwcCompositionType.SOLID_COLOR)) {
|
||||
tree.chips.push(HWC_CHIP);
|
||||
}
|
||||
if (tree.isVisible && TreeUtils.isVisibleNode(tree.kind, tree.type)) {
|
||||
if (tree.isVisible && UiTreeUtils.isVisibleNode(tree.kind, tree.type)) {
|
||||
tree.chips.push(VISIBLE_CHIP);
|
||||
}
|
||||
if (
|
||||
tree.zOrderRelativeOfId !== undefined
|
||||
&& tree.zOrderRelativeOfId !== -1
|
||||
&& !TreeUtils.isParentNode(tree.kind)
|
||||
&& !UiTreeUtils.isParentNode(tree.kind)
|
||||
&& !tree.isRootLayer
|
||||
) {
|
||||
tree.chips.push(RELATIVE_Z_CHIP);
|
||||
@@ -213,7 +213,7 @@ export class TreeGenerator {
|
||||
}
|
||||
|
||||
private applyChecks(
|
||||
tree: TreeNodeTrace,
|
||||
tree: TraceTreeNode,
|
||||
parentFilterMatch: boolean
|
||||
): HierarchyTreeNode | null {
|
||||
let newTree = this.getTreeNode(tree);
|
||||
@@ -227,7 +227,7 @@ export class TreeGenerator {
|
||||
newTree.simplifyNames = this.isSimplifyNames;
|
||||
|
||||
// check item either matches filter, or has parents/children matching filter
|
||||
if (TreeUtils.isParentNode(tree.kind) || parentFilterMatch) {
|
||||
if (UiTreeUtils.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: TreeNodeTrace, acc?: Map<string, TreeNodeTrace>): Map<string, TreeNodeTrace> {
|
||||
acc = acc || new Map<string, TreeNodeTrace>();
|
||||
private generateIdToNodeMapping(node: TraceTreeNode, acc?: Map<string, TraceTreeNode>): Map<string, TraceTreeNode> {
|
||||
acc = acc || new Map<string, TraceTreeNode>();
|
||||
|
||||
const nodeId: string = this.getNodeId!(node)!;
|
||||
|
||||
@@ -289,7 +289,7 @@ export class TreeGenerator {
|
||||
return acc;
|
||||
}
|
||||
|
||||
private cloneDiffTreeNode(node: TreeNodeTrace | null): TreeNodeTrace | null {
|
||||
private cloneDiffTreeNode(node: TraceTreeNode | null): TraceTreeNode | null {
|
||||
const clone = ObjectFormatter.cloneObject(node);
|
||||
if (node) {
|
||||
clone.children = node.children;
|
||||
@@ -304,7 +304,7 @@ export class TreeGenerator {
|
||||
return clone;
|
||||
}
|
||||
|
||||
private getTreeNode(node: TreeNodeTrace): HierarchyTreeNode {
|
||||
private getTreeNode(node: TraceTreeNode): HierarchyTreeNode {
|
||||
const clone = new HierarchyTreeNode(
|
||||
node.name,
|
||||
node.kind,
|
||||
@@ -327,11 +327,11 @@ export class TreeGenerator {
|
||||
}
|
||||
|
||||
private generateDiffTree(
|
||||
newTree: TreeNodeTrace | null,
|
||||
oldTree: TreeNodeTrace | null,
|
||||
newTreeSiblings: Array<TreeNodeTrace | null>,
|
||||
oldTreeSiblings: Array<TreeNodeTrace | null>
|
||||
): Array<TreeNodeTrace> {
|
||||
newTree: TraceTreeNode | null,
|
||||
oldTree: TraceTreeNode | null,
|
||||
newTreeSiblings: Array<TraceTreeNode | null>,
|
||||
oldTreeSiblings: Array<TraceTreeNode | null>
|
||||
): Array<TraceTreeNode> {
|
||||
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 (!TreeUtils.isParentNode(newTree.kind) && newId !== oldId) {
|
||||
if (!UiTreeUtils.isParentNode(newTree.kind) && newId !== oldId) {
|
||||
// A move, addition, or deletion has occurred
|
||||
let nextOldTree: TreeNodeTrace | null = null;
|
||||
let nextOldTree: TraceTreeNode | 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: TreeNodeTrace | null, oldTree: TreeNodeTrace | null): Array<TreeNodeTrace> {
|
||||
private visitChildren(newTree: TraceTreeNode | null, oldTree: TraceTreeNode | null): Array<TraceTreeNode> {
|
||||
// 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: TreeNodeTrace | null): string | null {
|
||||
private defaultNodeIdCallback(node: TraceTreeNode | null): string | null {
|
||||
return node ? node.stableId : null;
|
||||
}
|
||||
|
||||
private defaultModifiedCheck(newNode: TreeNodeTrace | null, oldNode: TreeNodeTrace | null): boolean {
|
||||
private defaultModifiedCheck(newNode: TraceTreeNode | null, oldNode: TraceTreeNode | null): boolean {
|
||||
if (!newNode && !oldNode) {
|
||||
return false;
|
||||
} else if (newNode && TreeUtils.isParentNode(newNode.kind)) {
|
||||
} else if (newNode && UiTreeUtils.isParentNode(newNode.kind)) {
|
||||
return false;
|
||||
} else if ((newNode && !oldNode) || (!newNode && oldNode)) {
|
||||
return true;
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import { TreeUtils, DiffType, HierarchyTreeNode, Terminal, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import {TraceTreeNode} from "common/trace/trace_tree_node";
|
||||
import {TreeUtils} from "common/utils/tree_utils";
|
||||
import {TreeTransformer} from "viewers/common/tree_transformer";
|
||||
import {DiffType, HierarchyTreeNode} from "viewers/common/ui_tree_utils";
|
||||
|
||||
describe("TreeTransformer", () => {
|
||||
let entry: TreeNodeTrace;
|
||||
let entry: TraceTreeNode;
|
||||
let selectedTree: HierarchyTreeNode;
|
||||
beforeAll(async () => {
|
||||
entry = {
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import ObjectFormatter from "common/trace/flickerlib/ObjectFormatter";
|
||||
import {TraceTreeNode} from "common/trace/trace_tree_node";
|
||||
import {TreeNode, FilterType} from "common/utils/tree_utils";
|
||||
|
||||
import {
|
||||
FilterType,
|
||||
PropertiesTreeNode,
|
||||
DiffType,
|
||||
Terminal,
|
||||
TreeNodeTrace,
|
||||
HierarchyTreeNode,
|
||||
PropertiesDump
|
||||
} from "./tree_utils";
|
||||
} from "./ui_tree_utils";
|
||||
|
||||
interface TransformOptions {
|
||||
freeze: boolean;
|
||||
@@ -79,7 +79,7 @@ export class TreeTransformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setProperties(currentEntry: TreeNodeTrace): TreeTransformer {
|
||||
public setProperties(currentEntry: TraceTreeNode): 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: TreeNodeTrace | null): TreeTransformer {
|
||||
public setDiffProperties(previousEntry: TraceTreeNode | 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: TreeNodeTrace, stableId: string): TreeNodeTrace | null {
|
||||
public getOriginalFlickerItem(entry: TraceTreeNode, stableId: string): TraceTreeNode | null {
|
||||
return this.findFlickerItem(entry, stableId);
|
||||
}
|
||||
|
||||
private getProtoDumpPropertiesForDisplay(entry: TreeNodeTrace): PropertiesDump | null {
|
||||
private getProtoDumpPropertiesForDisplay(entry: TraceTreeNode): PropertiesDump | null {
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ export class TreeTransformer {
|
||||
return obj;
|
||||
}
|
||||
|
||||
private getPropertiesForDisplay(entry: TreeNodeTrace): PropertiesDump | null {
|
||||
private getPropertiesForDisplay(entry: TraceTreeNode): PropertiesDump | null {
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
@@ -129,33 +129,37 @@ export class TreeTransformer {
|
||||
|
||||
const properties = ObjectFormatter.getProperties(entry);
|
||||
properties.forEach(prop => {
|
||||
if (entry.get) obj[prop] = entry.get(prop);
|
||||
obj[prop] = entry[prop as keyof typeof entry];
|
||||
});
|
||||
if (obj["children"]) delete obj["children"];
|
||||
if (obj["proto"]) delete obj["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;
|
||||
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);
|
||||
|
||||
Object.keys(obj["proto"]).forEach((prop: string) => {
|
||||
if (Object.keys(obj["proto"][prop]).length === 0) {
|
||||
obj["proto"][prop] = "empty";
|
||||
}
|
||||
});
|
||||
if (obj["proto"]) {
|
||||
Object.keys(obj["proto"]).forEach((prop: string) => {
|
||||
if (Object.keys(obj["proto"][prop]).length === 0) {
|
||||
obj["proto"][prop] = "empty";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private findFlickerItem(entryFlickerItem: TreeNodeTrace | null, stableId: string): TreeNodeTrace | null {
|
||||
private findFlickerItem(entryFlickerItem: TraceTreeNode | null, stableId: string): TraceTreeNode | null {
|
||||
if (!entryFlickerItem) {
|
||||
return null;
|
||||
}
|
||||
@@ -347,7 +351,8 @@ export class TreeTransformer {
|
||||
|
||||
|
||||
private filterMatches(item: PropertiesDump | null): boolean {
|
||||
return this.filter(item) ?? false;
|
||||
//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;
|
||||
}
|
||||
|
||||
private transformProperties(properties: PropertiesDump, metadataKey: string | null): PropertiesTreeNode {
|
||||
|
||||
@@ -16,38 +16,8 @@
|
||||
|
||||
import Chip from "./chip";
|
||||
|
||||
export type FilterType = (item: HierarchyTreeNode | PropertiesTreeNode | null) => boolean;
|
||||
|
||||
export type UiTreeNode = HierarchyTreeNode | PropertiesTreeNode;
|
||||
|
||||
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,
|
||||
@@ -107,58 +77,8 @@ export const DiffType = {
|
||||
|
||||
export class Terminal {}
|
||||
|
||||
export class TreeUtils
|
||||
export class UiTreeUtils
|
||||
{
|
||||
public static findDescendantNode(node: TreeNodeTrace, isTargetNode: FilterType): TreeNodeTrace|undefined {
|
||||
if (isTargetNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
const target = this.findDescendantNode(child, isTargetNode);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public static findAncestorNode(node: TreeNodeTrace, isTargetNode: FilterType): TreeNodeTrace|undefined {
|
||||
let ancestor = node.parent;
|
||||
|
||||
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 ?? "";
|
||||
@@ -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 { HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode } from "viewers/common/ui_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 { TreeUtils, HierarchyTreeNode, UiTreeNode } from "viewers/common/tree_utils";
|
||||
import { UiTreeUtils, HierarchyTreeNode, UiTreeNode } from "viewers/common/ui_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,8 +147,8 @@ import { TraceType } from "common/trace/trace_type";
|
||||
export class HierarchyComponent {
|
||||
objectKeys = Object.keys;
|
||||
filterString = "";
|
||||
diffClass = TreeUtils.diffClass;
|
||||
isHighlighted = TreeUtils.isHighlighted;
|
||||
diffClass = UiTreeUtils.diffClass;
|
||||
isHighlighted = UiTreeUtils.isHighlighted;
|
||||
|
||||
@Input() tree!: HierarchyTreeNode | null;
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Component, Input, Inject, ElementRef } from "@angular/core";
|
||||
import { TraceTreeNode } from "common/trace/trace_tree_node";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
import { PropertiesTreeNode, Terminal, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode, Terminal} from "viewers/common/ui_tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "properties-view",
|
||||
@@ -135,7 +136,7 @@ export class PropertiesComponent {
|
||||
|
||||
@Input() userOptions: UserOptions = {};
|
||||
@Input() propertiesTree: PropertiesTreeNode = {};
|
||||
@Input() selectedFlickerItem: TreeNodeTrace | null = null;
|
||||
@Input() selectedFlickerItem: TraceTreeNode | 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 { TreeUtils, UiTreeNode, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { UiTreeUtils, UiTreeNode, HierarchyTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
|
||||
@Component({
|
||||
@@ -77,8 +77,8 @@ import { TraceType } from "common/trace/trace_type";
|
||||
})
|
||||
|
||||
export class TreeComponent {
|
||||
diffClass = TreeUtils.diffClass;
|
||||
isHighlighted = TreeUtils.isHighlighted;
|
||||
diffClass = UiTreeUtils.diffClass;
|
||||
isHighlighted = UiTreeUtils.isHighlighted;
|
||||
|
||||
@Input() item!: UiTreeNode;
|
||||
@Input() dependencies: Array<TraceType> = [];
|
||||
@@ -123,7 +123,7 @@ export class TreeComponent {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
if (this.item instanceof HierarchyTreeNode && TreeUtils.isHighlighted(this.item, this.highlightedItems)) {
|
||||
if (this.item instanceof HierarchyTreeNode && UiTreeUtils.isHighlighted(this.item, this.highlightedItems)) {
|
||||
this.selectedTreeChange.emit(this.item);
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ export class TreeComponent {
|
||||
}
|
||||
|
||||
public hasChildren() {
|
||||
const isParentEntryInFlatView = TreeUtils.isParentNode(this.item.kind ?? "") && this.isFlattened;
|
||||
const isParentEntryInFlatView = UiTreeUtils.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 { TreeUtils, UiTreeNode, DiffType, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { UiTreeUtils, UiTreeNode, DiffType, HierarchyTreeNode } from "viewers/common/ui_tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "tree-node",
|
||||
@@ -100,7 +100,7 @@ export class TreeNodeComponent {
|
||||
}
|
||||
|
||||
public showPinNodeIcon() {
|
||||
return (!this.isPropertiesTreeNode() && !TreeUtils.isParentNode(this.item.kind ?? "")) ?? false;
|
||||
return (!this.isPropertiesTreeNode() && !UiTreeUtils.isParentNode(this.item.kind ?? "")) ?? false;
|
||||
}
|
||||
|
||||
public toggleTree(event: MouseEvent) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { treeNodeDataViewStyles } from "viewers/components/styles/tree_node_data_view.styles";
|
||||
import { Terminal, HierarchyTreeNode, UiTreeNode } from "viewers/common/tree_utils";
|
||||
import { Terminal, HierarchyTreeNode, UiTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import Chip from "viewers/common/chip";
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { treeNodePropertiesDataViewStyles } from "viewers/components/styles/tree_node_data_view.styles";
|
||||
import { PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
|
||||
@Component({
|
||||
selector: "tree-node-properties-data-view",
|
||||
|
||||
@@ -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 { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { UnitTestUtils } from "test/unit/utils";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
|
||||
@@ -32,7 +32,6 @@ describe("PresenterSurfaceFlinger", () => {
|
||||
entries = new Map<TraceType, any>();
|
||||
const entry: LayerTraceEntry = await UnitTestUtils.getLayerTraceEntry();
|
||||
|
||||
|
||||
selectedTree = new HierarchyTreeBuilder().setName("Dim layer#53").setStableId("EffectLayer 53 Dim layer#53")
|
||||
.setFilteredView(true).setKind("53").setDiffType("EffectLayer").setId(53).build();
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
import { UiData } from "./ui_data";
|
||||
import { Rectangle, RectMatrix, RectTransform } from "viewers/common/rectangle";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { TreeUtils, FilterType } from "common/utils/tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TreeUtils, FilterType, HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import { Layer, LayerTraceEntry } from "common/trace/flickerlib/common";
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { Layer } from "common/trace/flickerlib/common";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
|
||||
@@ -17,7 +17,7 @@ import {TraceType} from "common/trace/trace_type";
|
||||
import {Viewer} from "viewers/viewer";
|
||||
import {Presenter} from "./presenter";
|
||||
import {UiData} from "./ui_data";
|
||||
import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
import {ViewerEvents} from "viewers/common/viewer_events";
|
||||
|
||||
class ViewerSurfaceFlinger implements Viewer {
|
||||
constructor() {
|
||||
|
||||
@@ -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 { PropertiesTreeNode, Terminal, HierarchyTreeNode } from "viewers/common/tree_utils";
|
||||
import { PropertiesTreeNode, HierarchyTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { UnitTestUtils } from "test/unit/utils";
|
||||
import { HierarchyTreeBuilder } from "test/unit/hierarchy_tree_builder";
|
||||
import { VISIBLE_CHIP } from "viewers/common/chip";
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
import { UiData } from "./ui_data";
|
||||
import { Rectangle, RectMatrix, RectTransform } from "viewers/common/rectangle";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { TraceTreeNode } from "common/trace/trace_tree_node";
|
||||
import { TreeUtils, FilterType } from "common/utils/tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TreeUtils, FilterType, HierarchyTreeNode, PropertiesTreeNode, TreeNodeTrace } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { TreeGenerator } from "viewers/common/tree_generator";
|
||||
import { TreeTransformer } from "viewers/common/tree_transformer";
|
||||
import DisplayContent from "common/trace/flickerlib/windows/DisplayContent";
|
||||
@@ -232,8 +234,8 @@ export class Presenter {
|
||||
private pinnedItems: Array<HierarchyTreeNode> = [];
|
||||
private pinnedIds: Array<string> = [];
|
||||
private selectedHierarchyTree: HierarchyTreeNode | null = null;
|
||||
private previousEntry: TreeNodeTrace | null = null;
|
||||
private entry: TreeNodeTrace | null = null;
|
||||
private previousEntry: TraceTreeNode | null = null;
|
||||
private entry: TraceTreeNode | 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 { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/tree_utils";
|
||||
import { HierarchyTreeNode, PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
import { UserOptions } from "viewers/common/user_options";
|
||||
import { TraceType } from "common/trace/trace_type";
|
||||
import { Rectangle } from "viewers/common/rectangle";
|
||||
|
||||
Reference in New Issue
Block a user