• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LOG_TAG
17 #define LOG_TAG "HpaeDfxTree"
18 #endif
19 #include "hpae_dfx_tree.h"
20 #include "audio_engine_log.h"
21 namespace OHOS {
22 namespace AudioStandard {
23 namespace HPAE {
24 
FindDfxNode(DfxTreeNode * currentNode,const uint32_t nodeId)25 DfxTreeNode *HpaeDfxTree::FindDfxNode(DfxTreeNode *currentNode, const uint32_t nodeId)
26 {
27     if (!currentNode) {
28         return nullptr;
29     }
30     std::queue<DfxTreeNode *> q;
31     q.push(currentNode);
32     while (!q.empty()) {
33         DfxTreeNode *node = q.front();
34         q.pop();
35         if (node->nodeInfo_.nodeId == nodeId) {
36             return node;
37         }
38         for (auto &child : node->children_) {
39             q.push(child);
40         }
41     }
42     return nullptr;
43 }
44 
FindDfxParent(DfxTreeNode * target)45 DfxTreeNode *HpaeDfxTree::FindDfxParent(DfxTreeNode *target)
46 {
47     if (!root_ || target == root_) {
48         return nullptr;
49     }
50     std::queue<DfxTreeNode *> q;
51     q.push(root_);
52     while (!q.empty()) {
53         DfxTreeNode *node = q.front();
54         q.pop();
55         for (auto &child : node->children_) {
56             if (child->nodeInfo_.nodeId == target->nodeInfo_.nodeId) {
57                 return node;
58             }
59             q.push(child);
60         }
61     }
62     return nullptr;
63 }
64 
Insert(const uint32_t parentNodeId,const HpaeDfxNodeInfo & info)65 bool HpaeDfxTree::Insert(const uint32_t parentNodeId, const HpaeDfxNodeInfo &info)
66 {
67     if (!root_) {
68         AUDIO_INFO_LOG("Insert Root is null");
69         root_ = new DfxTreeNode(info);
70         return true;
71     }
72     DfxTreeNode *parent = FindDfxNode(root_, parentNodeId);
73     if (!parent) {
74         AUDIO_INFO_LOG("Insert can not find correct parent");
75         return false;
76     }
77     auto it = find_if(parent->children_.begin(), parent->children_.end(),
78         [&info](DfxTreeNode *node) -> bool { return node->nodeInfo_.nodeId == info.nodeId; });
79     if (it == parent->children_.end()) {
80         parent->children_.push_back(new DfxTreeNode(info));
81     }
82     return true;
83 }
84 
Remove(const uint32_t nodeId)85 bool HpaeDfxTree::Remove(const uint32_t nodeId)
86 {
87     if (!root_) {
88         AUDIO_INFO_LOG("Remove Root is null");
89         return false;
90     }
91     DfxTreeNode *nodeToRemove = FindDfxNode(root_, nodeId);
92     if (!nodeToRemove) {
93         return false;
94     }
95 
96     if (nodeToRemove == root_) {
97         delete root_;
98         root_ = nullptr;
99         return true;
100     }
101 
102     DfxTreeNode *parent = FindDfxParent(nodeToRemove);
103     if (!parent) {
104         return false;
105     }
106     // Remove from parent's children
107     auto &children = parent->children_;
108     auto it = find(children.begin(), children.end(), nodeToRemove);
109     if (it != children.end()) {
110         children.erase(it);
111         delete nodeToRemove;
112         return true;
113     }
114     return false;
115 }
116 
LevelOrderTraversal()117 std::vector<std::vector<HpaeDfxNodeInfo>> HpaeDfxTree::LevelOrderTraversal()
118 {
119     std::vector<std::vector<HpaeDfxNodeInfo>> result;
120     if (!root_) {
121         return result;
122     }
123     std::queue<DfxTreeNode *> q;
124     q.push(root_);
125     while (!q.empty()) {
126         size_t levelSize = q.size();
127         std::vector<HpaeDfxNodeInfo> curLevelResult;
128         for (size_t i = 0; i < levelSize; ++i) {
129             DfxTreeNode *node = q.front();
130             q.pop();
131             curLevelResult.push_back(node->nodeInfo_);
132             for (auto &child : node->children_) {
133                 q.push(child);
134             }
135         }
136         result.push_back(curLevelResult);
137     }
138     return result;
139 }
140 
PrintNodeInfo(std::string & outStr,HpaeDfxNodeInfo & nodeInfo)141 void HpaeDfxTree::PrintNodeInfo(std::string &outStr, HpaeDfxNodeInfo &nodeInfo)
142 {
143     outStr = outStr + nodeInfo.nodeName + ": " + "sessionId[" + std::to_string(nodeInfo.sessionId) + "],";
144     outStr = outStr + "nodeId[" + std::to_string(nodeInfo.nodeId) + "],";
145     outStr = outStr + "rate[" + std::to_string(nodeInfo.samplingRate) + "],";
146     outStr = outStr + "ch[" + std::to_string(nodeInfo.channels) + "],";
147     outStr = outStr + "bw[" + std::to_string(nodeInfo.format) + "],";
148     outStr = outStr + "len[" + std::to_string(nodeInfo.frameLen) + "],";
149     outStr = outStr + "scene[" + std::to_string(nodeInfo.sceneType) + "] \n";
150 }
151 
PrintSubTree(DfxTreeNode * node,const std::string & prefix,bool isLastChild,std::string & outStr)152 void HpaeDfxTree::PrintSubTree(DfxTreeNode *node, const std::string &prefix, bool isLastChild, std::string &outStr)
153 {
154     if (!node) {
155         return;
156     }
157 
158     outStr = outStr + prefix;
159     outStr = outStr + (isLastChild ? "|___ " : "|--- ");
160     PrintNodeInfo(outStr, node->nodeInfo_);
161     std::string newPrefix = prefix + (isLastChild ? "    " : "|   ");
162     for (size_t i = 0; i < node->children_.size(); ++i) {
163         bool childIsLast = (i == node->children_.size() - 1);
164         PrintSubTree(node->children_[i], newPrefix, childIsLast, outStr);
165     }
166 }
167 
PrintTree(std::string & outStr)168 void HpaeDfxTree::PrintTree(std::string &outStr)
169 {
170     if (!root_) {
171         return;
172     }
173     PrintNodeInfo(outStr, root_->nodeInfo_);
174     for (size_t i = 0; i < root_->children_.size(); ++i) {
175         bool isLast = (i == root_->children_.size() - 1);
176         PrintSubTree(root_->children_[i], "", isLast, outStr);
177     }
178 }
179 
UpdateNodeInfo(uint32_t nodeId,const HpaeDfxNodeInfo & nodeInfo)180 void HpaeDfxTree::UpdateNodeInfo(uint32_t nodeId, const HpaeDfxNodeInfo &nodeInfo)
181 {
182     if (root_ == nullptr) {
183         AUDIO_WARNING_LOG("Hidumper dfx tree is empty!");
184         return;
185     }
186     DfxTreeNode *target = FindDfxNode(root_, nodeId);
187     if (target == nullptr) {
188         AUDIO_WARNING_LOG("Cannot find Node Id: %{public}d", nodeId);
189         return;
190     }
191     target->nodeInfo_ = nodeInfo;
192 }
193 
194 }  // namespace HPAE
195 }  // namespace AudioStandard
196 }  // namespace OHOS