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 if (strcmp(reinterpret_cast<char *>(xmlOutpath), "/data/log/thermal/thermal-log") == 0) {
205 this->traceConfig_.outPath = std::string(reinterpret_cast<char *>(xmlOutpath));
206 xmlFree(xmlOutpath);
207 } else {
208 THERMAL_HILOGE(COMP_HDI, "xmlOutpath is not /data/log/thermal/thermal-log");
209 }
210 }
211
212 auto cur = node->xmlChildrenNode;
213 while (cur != nullptr) {
214 ParseTracingSubNode(cur);
215 cur = cur->next;
216 }
217
218 THERMAL_HILOGI(COMP_HDI, "DfxTraceInfo number = %{public}zu", traceInfo_.size());
219 }
220
ParseTracingSubNode(xmlNodePtr node)221 void ThermalHdfConfig::ParseTracingSubNode(xmlNodePtr node)
222 {
223 DfxTraceInfo info;
224 std::string title;
225 std::string valuePath;
226
227 for (auto subNode = node->children; subNode != nullptr; subNode = subNode->next) {
228 if (!xmlStrcmp(subNode->name, BAD_CAST"title")) {
229 xmlChar* titlePath = xmlGetProp(subNode, BAD_CAST"path");
230 if (titlePath != nullptr) {
231 ThermalHdfUtils::ReadNode(std::string(reinterpret_cast<char*>(titlePath)), title);
232 xmlFree(titlePath);
233 }
234
235 xmlChar* titleName = xmlGetProp(subNode, BAD_CAST"name");
236 if (titleName != nullptr) {
237 title = std::string(reinterpret_cast<char*>(titleName));
238 xmlFree(titleName);
239 }
240 }
241
242 if (!xmlStrcmp(subNode->name, BAD_CAST"value")) {
243 xmlChar* xmlValuePath = xmlGetProp(subNode, BAD_CAST"path");
244 if (xmlValuePath != nullptr) {
245 valuePath = std::string(reinterpret_cast<char*>(xmlValuePath));
246 xmlFree(xmlValuePath);
247 }
248 }
249 }
250
251 info.title = title;
252 info.valuePath = valuePath;
253 traceInfo_.emplace_back(info);
254 THERMAL_HILOGD(
255 COMP_HDI, "traceInfo.title = %{public}s, traceInfo.valuePath = %{private}s", title.c_str(), valuePath.c_str());
256 }
257
GetThermalZoneNodeInfo(XMLThermalZoneInfo & tz,const xmlNode * node)258 void ThermalHdfConfig::GetThermalZoneNodeInfo(XMLThermalZoneInfo& tz, const xmlNode* node)
259 {
260 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type");
261 if (xmlType != nullptr) {
262 tz.type = std::string(reinterpret_cast<char*>(xmlType));
263 xmlFree(xmlType);
264 }
265
266 auto replace = xmlGetProp(node, BAD_CAST("replace"));
267 if (replace != nullptr) {
268 tz.replace = std::string(reinterpret_cast<char*>(replace));
269 tz.isReplace = true;
270 xmlFree(replace);
271 }
272 }
273
ParseIsolateNode(xmlNodePtr node)274 void ThermalHdfConfig::ParseIsolateNode(xmlNodePtr node)
275 {
276 THERMAL_HILOGD(COMP_HDI, "in");
277 auto cur = node->xmlChildrenNode;
278 while (cur != nullptr) {
279 std::shared_ptr<IsolateInfoConfig> isolateInfo = std::make_shared<IsolateInfoConfig>();
280 std::string groupName;
281 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
282 if (xmlName != nullptr) {
283 groupName = std::string(reinterpret_cast<char*>(xmlName));
284 xmlFree(xmlName);
285 isolateInfo->SetGroupName(groupName);
286 THERMAL_HILOGD(COMP_HDI, "groupName: %{public}s", groupName.c_str());
287 }
288
289 std::vector<IsolateNodeInfo> xmlTnInfoList;
290 for (auto subNode = cur->children; subNode; subNode = subNode->next) {
291 if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) {
292 IsolateNodeInfo tn;
293 ParseIsolateSubNode(subNode, tn);
294 xmlTnInfoList.push_back(tn);
295 }
296 }
297 isolateInfo->SetIsolateNodeInfo(xmlTnInfoList);
298 isolateInfoMap_.insert(std::make_pair(groupName, isolateInfo));
299 cur = cur->next;
300 }
301 }
302
ParseIsolateSubNode(xmlNodePtr node,IsolateNodeInfo & tn)303 void ThermalHdfConfig::ParseIsolateSubNode(xmlNodePtr node, IsolateNodeInfo& tn)
304 {
305 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type");
306 if (xmlType != nullptr) {
307 tn.type = std::string(reinterpret_cast<char*>(xmlType));
308 THERMAL_HILOGD(COMP_HDI, "type: %{public}s", tn.type.c_str());
309 xmlFree(xmlType);
310 }
311
312 xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path");
313 if (xmlPath != nullptr) {
314 tn.path = std::string(reinterpret_cast<char*>(xmlPath));
315 THERMAL_HILOGD(COMP_HDI, "path: %{public}s", tn.path.c_str());
316 xmlFree(xmlPath);
317 }
318 }
319
GetIsolateCpuNodePath(bool isSim,const std::string & type,std::string & path)320 int32_t ThermalHdfConfig::GetIsolateCpuNodePath(bool isSim, const std::string &type, std::string &path)
321 {
322 std::string groupName = isSim ? "sim" : "actual";
323 THERMAL_HILOGI(COMP_HDI, "isSim %d, type %{public}s, groupName %{public}s", isSim, type.c_str(), groupName.c_str());
324
325 auto mapIter = isolateInfoMap_.find(groupName);
326 if (mapIter == isolateInfoMap_.end()) {
327 THERMAL_HILOGE(COMP_HDI, "failed to get group %s config", groupName.c_str());
328 return HDF_FAILURE;
329 }
330
331 std::vector<IsolateNodeInfo> nodeVector = mapIter->second->GetIsolateNodeInfo();
332 for (auto nodeIter : nodeVector) {
333 if (type == nodeIter.type) {
334 path = nodeIter.path;
335 THERMAL_HILOGI(COMP_HDI, "path %{public}s", path.c_str());
336 return HDF_SUCCESS;
337 }
338 }
339
340 THERMAL_HILOGE(COMP_HDI, "failed to get type %{public}s path", type.c_str());
341 return HDF_FAILURE;
342 }
343 } // V1_1
344 } // Thermal
345 } // HDI
346 } // OHOS
347