1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {assertDefined} from 'common/assert_utils'; 18import {SetFormatters} from 'parsers/operations/set_formatters'; 19import {TraceRect} from 'trace/trace_rect'; 20import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 21import {OperationChain} from 'trace/tree_node/operations/operation_chain'; 22import {PropertiesProvider} from 'trace/tree_node/properties_provider'; 23import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 24import {PropertyTreeNodeFactory} from 'trace/tree_node/property_tree_node_factory'; 25import {ChildProperty, PropertyTreeBuilder} from './property_tree_builder'; 26import {TreeBuilder} from './tree_builder'; 27 28export class HierarchyTreeBuilder extends TreeBuilder< 29 HierarchyTreeNode, 30 ChildHierarchy 31> { 32 private properties: any; 33 private additionalProperties: ChildProperty[] = []; 34 35 setId(value: any): this { 36 this.id = value; 37 return this; 38 } 39 40 setProperties(value: any): this { 41 this.properties = value; 42 return this; 43 } 44 45 addChildProperty(value: ChildProperty): this { 46 this.additionalProperties.push(value); 47 return this; 48 } 49 50 protected override makeRootNode(): HierarchyTreeNode { 51 const rootId = this.makeHierarchyNodeId(); 52 53 const propertiesTree = new PropertyTreeNodeFactory().makeProtoProperty( 54 rootId, 55 '', 56 this.properties, 57 ); 58 this.additionalProperties.forEach((property) => { 59 const childNode = new PropertyTreeBuilder() 60 .setRootId(propertiesTree.id) 61 .setName(property.name) 62 .setSource(property.source ?? propertiesTree.source) 63 .setValue(property.value) 64 .setChildren(property.children ?? []) 65 .build(); 66 propertiesTree.addOrReplaceChild(childNode); 67 }); 68 new SetFormatters().apply(propertiesTree); 69 const provider = new PropertiesProvider( 70 propertiesTree, 71 async () => propertiesTree, 72 OperationChain.emptyChain<PropertyTreeNode>(), 73 OperationChain.emptyChain<PropertyTreeNode>(), 74 OperationChain.emptyChain<PropertyTreeNode>(), 75 ); 76 77 return new HierarchyTreeNode(rootId, assertDefined(this.name), provider); 78 } 79 80 protected override addOrReplaceChildNode( 81 rootNode: HierarchyTreeNode, 82 child: ChildHierarchy, 83 ): void { 84 const childNode = new HierarchyTreeBuilder() 85 .setId(child.id) 86 .setName(child.name) 87 .setProperties(child.properties) 88 .setChildren(child.children ?? []) 89 .build(); 90 rootNode.addOrReplaceChild(childNode); 91 childNode.setParent(rootNode); 92 if (child.rects !== undefined) { 93 childNode.setRects(child.rects); 94 } 95 if (child.secondaryRects !== undefined) { 96 childNode.setSecondaryRects(child.secondaryRects); 97 } 98 } 99 100 private makeHierarchyNodeId() { 101 return `${this.id} ${this.name}`; 102 } 103} 104 105export interface ChildHierarchy { 106 id: string | number; 107 name: string; 108 properties?: any; 109 children?: ChildHierarchy[]; 110 rects?: TraceRect[]; 111 secondaryRects?: TraceRect[]; 112} 113