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 {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 19import {OperationChain} from 'trace/tree_node/operations/operation_chain'; 20import {PropertiesProvider} from 'trace/tree_node/properties_provider'; 21import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 22import {PropertyTreeNodeFactory} from 'trace/tree_node/property_tree_node_factory'; 23import {ChildProperty, PropertyTreeBuilder} from './property_tree_builder'; 24import {TreeBuilder} from './tree_builder'; 25 26export class HierarchyTreeBuilder extends TreeBuilder< 27 HierarchyTreeNode, 28 ChildHierarchy 29> { 30 private properties: any; 31 private additionalProperties: ChildProperty[] = []; 32 33 setId(value: any): this { 34 this.id = value; 35 return this; 36 } 37 38 setProperties(value: any): this { 39 this.properties = value; 40 return this; 41 } 42 43 addChildProperty(value: ChildProperty): this { 44 this.additionalProperties.push(value); 45 return this; 46 } 47 48 protected override makeRootNode(): HierarchyTreeNode { 49 const rootId = this.makeHierarchyNodeId(); 50 51 const propertiesTree = new PropertyTreeNodeFactory().makeProtoProperty( 52 rootId, 53 assertDefined(this.name), 54 this.properties, 55 ); 56 this.additionalProperties.forEach((property) => { 57 const childNode = new PropertyTreeBuilder() 58 .setRootId(propertiesTree.id) 59 .setName(property.name) 60 .setSource(property.source ?? propertiesTree.source) 61 .setValue(property.value) 62 .setChildren(property.children ?? []) 63 .build(); 64 propertiesTree.addOrReplaceChild(childNode); 65 }); 66 const provider = new PropertiesProvider( 67 propertiesTree, 68 async () => propertiesTree, 69 OperationChain.emptyChain<PropertyTreeNode>(), 70 OperationChain.emptyChain<PropertyTreeNode>(), 71 OperationChain.emptyChain<PropertyTreeNode>(), 72 ); 73 74 return new HierarchyTreeNode(rootId, assertDefined(this.name), provider); 75 } 76 77 protected override addOrReplaceChildNode( 78 rootNode: HierarchyTreeNode, 79 child: ChildHierarchy, 80 ): void { 81 const childNode = new HierarchyTreeBuilder() 82 .setId(child.id) 83 .setName(child.name) 84 .setProperties(child.properties) 85 .setChildren(child.children ?? []) 86 .build(); 87 rootNode.addOrReplaceChild(childNode); 88 childNode.setParent(rootNode); 89 } 90 91 private makeHierarchyNodeId() { 92 return `${this.id} ${this.name}`; 93 } 94} 95 96export interface ChildHierarchy { 97 id: string | number; 98 name: string; 99 properties?: any; 100 children?: ChildHierarchy[]; 101} 102