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