1 /*
2 * Copyright (c) 2022-2023 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 #include "thermal_hdf_config.h"
17
18 #include "thermal_hdf_utils.h"
19 #include "thermal_log.h"
20 #include "hdf_remote_service.h"
21 #include "osal_mem.h"
22 #include "string_ex.h"
23
24 namespace OHOS {
25 namespace HDI {
26 namespace Thermal {
27 namespace V1_1 {
28 namespace {
29 const int32_t DEFAULT_POLLING_INTERVAL = 30000;
30 }
31
GetInstance()32 ThermalHdfConfig& ThermalHdfConfig::GetInstance()
33 {
34 static ThermalHdfConfig instance;
35 return instance;
36 }
37
ThermalHDIConfigInit(const std::string & path)38 int32_t ThermalHdfConfig::ThermalHDIConfigInit(const std::string& path)
39 {
40 if (!baseConfig_) {
41 baseConfig_ = std::make_shared<BaseInfoConfig>();
42 }
43 return ParseThermalHdiXMLConfig(path);
44 }
45
ParseThermalHdiXMLConfig(const std::string & path)46 int32_t ThermalHdfConfig::ParseThermalHdiXMLConfig(const std::string& path)
47 {
48 std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
49 xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
50 if (docPtr == nullptr) {
51 THERMAL_HILOGW(COMP_HDI, "failed to read xml file");
52 return HDF_ERR_INVALID_OBJECT;
53 }
54
55 auto rootNode = xmlDocGetRootElement(docPtr.get());
56 if (rootNode == nullptr) {
57 THERMAL_HILOGE(COMP_HDI, "failed to read root node");
58 return HDF_ERR_INVALID_OBJECT;
59 }
60
61 if (!xmlStrcmp(rootNode->name, BAD_CAST"thermal")) {
62 xmlChar* xmlVersion = xmlGetProp(rootNode, BAD_CAST"version");
63 if (xmlVersion != nullptr) {
64 this->thermal_.version = std::string(reinterpret_cast<char*>(xmlVersion));
65 xmlFree(xmlVersion);
66 THERMAL_HILOGD(COMP_HDI, "version: %{public}s", this->thermal_.version.c_str());
67 }
68
69 xmlChar* xmlProduct = xmlGetProp(rootNode, BAD_CAST"product");
70 if (xmlProduct != nullptr) {
71 this->thermal_.product = std::string(reinterpret_cast<char*>(xmlProduct));
72 xmlFree(xmlProduct);
73 THERMAL_HILOGD(COMP_HDI, "product: %{public}s", this->thermal_.product.c_str());
74 }
75 }
76
77 for (auto node = rootNode->children; node; node = node->next) {
78 if (node == nullptr) {
79 continue;
80 }
81
82 if (!xmlStrcmp(node->name, BAD_CAST"base")) {
83 ParseBaseNode(node);
84 } else if (!xmlStrcmp(node->name, BAD_CAST"polling")) {
85 ParsePollingNode(node);
86 } else if (!xmlStrcmp(node->name, BAD_CAST"tracing")) {
87 ParseTracingNode(node);
88 } else if (!xmlStrcmp(node->name, BAD_CAST"isolate")) {
89 ParseIsolateNode(node);
90 }
91 }
92 return HDF_SUCCESS;
93 }
94
ParseBaseNode(xmlNodePtr node)95 void ThermalHdfConfig::ParseBaseNode(xmlNodePtr node)
96 {
97 auto cur = node->xmlChildrenNode;
98 std::vector<BaseItem> vBase;
99 while (cur != nullptr) {
100 BaseItem item;
101 xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag");
102 if (xmlTag != nullptr) {
103 item.tag = std::string(reinterpret_cast<char*>(xmlTag));
104 xmlFree(xmlTag);
105 THERMAL_HILOGD(COMP_HDI, "ParseBaseNode tag: %{public}s", item.tag.c_str());
106 }
107
108 xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value");
109 if (xmlValue != nullptr) {
110 item.value = std::string(reinterpret_cast<char*>(xmlValue));
111 xmlFree(xmlValue);
112 THERMAL_HILOGD(COMP_HDI, "ParseBaseNode value: %{public}s", item.value.c_str());
113 }
114
115 vBase.push_back(item);
116 cur = cur->next;
117 }
118 baseConfig_->SetBase(vBase);
119 }
120
GetXmlNodeName(xmlNodePtr node,std::string & defaultName)121 std::string ThermalHdfConfig::GetXmlNodeName(xmlNodePtr node, std::string &defaultName)
122 {
123 std::string name;
124 xmlChar* xmlName = xmlGetProp(node, BAD_CAST"name");
125 if (xmlName == nullptr) {
126 return defaultName;
127 }
128 name = std::string(reinterpret_cast<char*>(xmlName));
129 xmlFree(xmlName);
130
131 return name;
132 }
133
ParsePollingNode(xmlNodePtr node)134 void ThermalHdfConfig::ParsePollingNode(xmlNodePtr node)
135 {
136 std::string pollingDefaultName("thermal");
137 std::string pollingName = GetXmlNodeName(node, pollingDefaultName);
138 GroupMap groupMap;
139
140 auto cur = node->xmlChildrenNode;
141 while (cur != nullptr) {
142 std::shared_ptr<SensorInfoConfig> sensorInfo = std::make_shared<SensorInfoConfig>();
143 std::string groupDefaultName("actual");
144 std::string groupName = GetXmlNodeName(cur, groupDefaultName);
145 sensorInfo->SetGroupName(groupName);
146 THERMAL_HILOGD(COMP_HDI, "ParsePollingNode groupName: %{public}s", groupName.c_str());
147
148 xmlChar* xmlInterval = xmlGetProp(cur, BAD_CAST"interval");
149 if (xmlInterval != nullptr) {
150 std::string strInterval = reinterpret_cast<char *>(xmlInterval);
151 int32_t interval = DEFAULT_POLLING_INTERVAL;
152 StrToInt(TrimStr(strInterval), interval);
153 xmlFree(xmlInterval);
154 THERMAL_HILOGD(COMP_HDI, "ParsePollingNode interval: %{public}d", interval);
155 sensorInfo->SetGroupInterval(interval);
156 }
157
158 std::vector<XMLThermalZoneInfo> xmlTzInfoList;
159 std::vector<XMLThermalNodeInfo> xmlTnInfoList;
160 for (auto subNode = cur->children; subNode; subNode = subNode->next) {
161 if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_zone")) {
162 XMLThermalZoneInfo tz;
163 GetThermalZoneNodeInfo(tz, subNode);
164 THERMAL_HILOGI(COMP_HDI, "ParsePollingNode ParsePollingNodetztype: %{public}s, replace: %{public}s",
165 tz.type.c_str(), tz.replace.c_str());
166 xmlTzInfoList.push_back(tz);
167 } else if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) {
168 XMLThermalNodeInfo tn;
169 ParsePollingSubNode(subNode, tn);
170 THERMAL_HILOGI(COMP_HDI, "ParsePollingNode tntype: %{public}s", tn.type.c_str());
171 xmlTnInfoList.push_back(tn);
172 }
173 }
174 sensorInfo->SetXMLThermalZoneInfo(xmlTzInfoList);
175 sensorInfo->SetXMLThermalNodeInfo(xmlTnInfoList);
176 groupMap.insert(std::make_pair(groupName, sensorInfo));
177 cur = cur->next;
178 }
179
180 pollingMap_.insert(std::make_pair(pollingName, groupMap));
181 }
182
ParsePollingSubNode(xmlNodePtr node,XMLThermalNodeInfo & tn)183 void ThermalHdfConfig::ParsePollingSubNode(xmlNodePtr node, XMLThermalNodeInfo& tn)
184 {
185 DfxTraceInfo info;
186
187 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type");
188 if (xmlType != nullptr) {
189 tn.type = std::string(reinterpret_cast<char*>(xmlType));
190 xmlFree(xmlType);
191 }
192
193 xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path");
194 if (xmlPath != nullptr) {
195 tn.path = std::string(reinterpret_cast<char*>(xmlPath));
196 xmlFree(xmlPath);
197 }
198 }
199
ParseTracingNode(xmlNodePtr node)200 void ThermalHdfConfig::ParseTracingNode(xmlNodePtr node)
201 {
202 xmlChar* xmlOutpath = xmlGetProp(node, BAD_CAST"outpath");
203 if (xmlOutpath != nullptr) {
204 this->traceConfig_.outPath = std::string(reinterpret_cast<char *>(xmlOutpath));
205 xmlFree(xmlOutpath);
206 }
207
208 auto cur = node->xmlChildrenNode;
209 while (cur != nullptr) {
210 ParseTracingSubNode(cur);
211 cur = cur->next;
212 }
213 }
214
ParseTracingSubNode(xmlNodePtr node)215 void ThermalHdfConfig::ParseTracingSubNode(xmlNodePtr node)
216 {
217 std::string title;
218 DfxTraceInfo info;
219 std::string valuePath;
220
221 for (auto subNode = node->children; subNode != nullptr; subNode = subNode->next) {
222 if (!xmlStrcmp(subNode->name, BAD_CAST"title")) {
223 xmlChar* titlePath = xmlGetProp(subNode, BAD_CAST"path");
224 if (titlePath != nullptr) {
225 ThermalHdfUtils::ReadNode(
226 std::string(reinterpret_cast<char*>(titlePath)), title);
227 THERMAL_HILOGD(COMP_HDI, "title form path");
228 xmlFree(titlePath);
229 }
230
231 xmlChar* titleName = xmlGetProp(subNode, BAD_CAST"name");
232 if (titleName != nullptr) {
233 title = std::string(reinterpret_cast<char*>(titleName));
234 xmlFree(titleName);
235 }
236 }
237
238 if (!xmlStrcmp(subNode->name, BAD_CAST"value")) {
239 xmlChar* xmlValuePath = xmlGetProp(subNode, BAD_CAST"path");
240 if (xmlValuePath != nullptr) {
241 valuePath = std::string(reinterpret_cast<char*>(xmlValuePath));
242 xmlFree(xmlValuePath);
243 }
244 }
245 }
246
247 info.title = title;
248 info.valuePath = valuePath;
249 traceInfo_.emplace_back(info);
250
251 for (const auto& item : traceInfo_) {
252 THERMAL_HILOGD(COMP_HDI, "item.title = %{public}s", item.title.c_str());
253 }
254 }
255
GetThermalZoneNodeInfo(XMLThermalZoneInfo & tz,const xmlNode * node)256 void ThermalHdfConfig::GetThermalZoneNodeInfo(XMLThermalZoneInfo& tz, const xmlNode* node)
257 {
258 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type");
259 if (xmlType != nullptr) {
260 tz.type = std::string(reinterpret_cast<char*>(xmlType));
261 xmlFree(xmlType);
262 }
263
264 auto replace = xmlGetProp(node, BAD_CAST("replace"));
265 if (replace != nullptr) {
266 tz.replace = std::string(reinterpret_cast<char*>(replace));
267 tz.isReplace = true;
268 xmlFree(replace);
269 }
270 }
271
ParseIsolateNode(xmlNodePtr node)272 void ThermalHdfConfig::ParseIsolateNode(xmlNodePtr node)
273 {
274 THERMAL_HILOGD(COMP_HDI, "in");
275 auto cur = node->xmlChildrenNode;
276 while (cur != nullptr) {
277 std::shared_ptr<IsolateInfoConfig> isolateInfo = std::make_shared<IsolateInfoConfig>();
278 std::string groupName;
279 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
280 if (xmlName != nullptr) {
281 groupName = std::string(reinterpret_cast<char*>(xmlName));
282 xmlFree(xmlName);
283 isolateInfo->SetGroupName(groupName);
284 THERMAL_HILOGD(COMP_HDI, "groupName: %{public}s", groupName.c_str());
285 }
286
287 std::vector<IsolateNodeInfo> xmlTnInfoList;
288 for (auto subNode = cur->children; subNode; subNode = subNode->next) {
289 if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) {
290 IsolateNodeInfo tn;
291 ParseIsolateSubNode(subNode, tn);
292 xmlTnInfoList.push_back(tn);
293 }
294 }
295 isolateInfo->SetIsolateNodeInfo(xmlTnInfoList);
296 isolateInfoMap_.insert(std::make_pair(groupName, isolateInfo));
297 cur = cur->next;
298 }
299 }
300
ParseIsolateSubNode(xmlNodePtr node,IsolateNodeInfo & tn)301 void ThermalHdfConfig::ParseIsolateSubNode(xmlNodePtr node, IsolateNodeInfo& tn)
302 {
303 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type");
304 if (xmlType != nullptr) {
305 tn.type = std::string(reinterpret_cast<char*>(xmlType));
306 THERMAL_HILOGD(COMP_HDI, "type: %{public}s", tn.type.c_str());
307 xmlFree(xmlType);
308 }
309
310 xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path");
311 if (xmlPath != nullptr) {
312 tn.path = std::string(reinterpret_cast<char*>(xmlPath));
313 THERMAL_HILOGD(COMP_HDI, "path: %{public}s", tn.path.c_str());
314 xmlFree(xmlPath);
315 }
316 }
317
GetIsolateCpuNodePath(bool isSim,const std::string & type,std::string & path)318 int32_t ThermalHdfConfig::GetIsolateCpuNodePath(bool isSim, const std::string &type, std::string &path)
319 {
320 std::string groupName = isSim ? "sim" : "actual";
321 THERMAL_HILOGI(COMP_HDI, "isSim %d, type %{public}s, groupName %{public}s", isSim, type.c_str(), groupName.c_str());
322
323 auto mapIter = isolateInfoMap_.find(groupName);
324 if (mapIter == isolateInfoMap_.end()) {
325 THERMAL_HILOGE(COMP_HDI, "failed to get group %s config", groupName.c_str());
326 return HDF_FAILURE;
327 }
328
329 std::vector<IsolateNodeInfo> nodeVector = mapIter->second->GetIsolateNodeInfo();
330 for (auto nodeIter : nodeVector) {
331 if (type == nodeIter.type) {
332 path = nodeIter.path;
333 THERMAL_HILOGI(COMP_HDI, "path %{public}s", path.c_str());
334 return HDF_SUCCESS;
335 }
336 }
337
338 THERMAL_HILOGE(COMP_HDI, "failed to get type %{public}s path", type.c_str());
339 return HDF_FAILURE;
340 }
341 } // V1_1
342 } // Thermal
343 } // HDI
344 } // OHOS
345