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 {HierarchyTreeBuilder} from 'parsers/hierarchy_tree_builder'; 19import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 20import {PropertiesProvider} from 'trace/tree_node/properties_provider'; 21import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 22import {DEFAULT_PROPERTY_TREE_NODE_FACTORY} from 'trace/tree_node/property_tree_node_factory'; 23 24export class HierarchyTreeBuilderSf extends HierarchyTreeBuilder { 25 protected override buildIdentifierToChildrenMap( 26 layers: PropertiesProvider[], 27 ): Map<string | number, readonly HierarchyTreeNode[]> { 28 const map = layers.reduce((map, layer) => { 29 const layerProperties = layer.getEagerProperties(); 30 const layerNode = this.makeNode( 31 layerProperties.id, 32 layerProperties.name, 33 layer, 34 ); 35 const layerId = assertDefined( 36 layerProperties.getChildByName('id'), 37 ).getValue(); 38 39 const curr = map.get(layerId); 40 if (curr) { 41 curr.push(layerNode); 42 console.warn( 43 `Duplicate layer id ${layerId} found. Adding it as duplicate to the hierarchy`, 44 ); 45 layer.addEagerProperty( 46 DEFAULT_PROPERTY_TREE_NODE_FACTORY.makeCalculatedProperty( 47 layerProperties.id, 48 'isDuplicate', 49 true, 50 ), 51 ); 52 } else { 53 map.set(layerId, [layerNode]); 54 } 55 return map; 56 }, new Map<string | number, HierarchyTreeNode[]>()); 57 return map; 58 } 59 60 protected override assignParentChildRelationships( 61 root: HierarchyTreeNode, 62 identifierToChildren: Map<string | number, HierarchyTreeNode[]>, 63 isRoot?: boolean, 64 ): void { 65 for (const children of identifierToChildren.values()) { 66 children.forEach((child) => { 67 const parentIdNode = assertDefined( 68 child.getEagerPropertyByName('parent'), 69 ); 70 const parentId = this.getIdentifierValue(parentIdNode); 71 const parent = identifierToChildren.get(parentId)?.at(0); 72 if (parent) { 73 this.setParentChildRelationship(parent, child); 74 } else { 75 this.setParentChildRelationship(root, child); 76 } 77 }); 78 } 79 } 80 81 private getIdentifierValue(identifier: PropertyTreeNode): number { 82 return Number(identifier.getValue()); 83 } 84} 85