1 /*
2 * Copyright (c) 2021-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_srv_config_parser.h"
17
18 #include "string_operation.h"
19 #include "thermal_common.h"
20 #include "thermal_service.h"
21 #include "string_ex.h"
22
23 #include <dlfcn.h>
24
25 namespace OHOS {
26 namespace PowerMgr {
27 namespace {
28 constexpr uint32_t AUX_SENSOR_RANGE_LEN = 2;
29 const std::string TRUE_STR = "1";
30 constexpr const char* GET_THERMAL_EXT_CONGIH_FUNC = "GetThermalExtConfig";
31 constexpr const char* THERMAL_CONFIG_LIBRARY_PATH = "libthermal_manager_ext.z.so";
32 const std::string SYSTEM_PREFIX = "/system";
33 constexpr int32_t SYSTEM_PREFIX_INDEX = 7;
34 constexpr int32_t THERMAL_SERVICE_CONFIG_INDEX = 2;
35 typedef int32_t(*Func)(int32_t, std::string&);
36 }
37
ThermalSrvConfigParser()38 ThermalSrvConfigParser::ThermalSrvConfigParser() {};
39
ThermalSrvConfigInit(const std::string & path)40 bool ThermalSrvConfigParser::ThermalSrvConfigInit(const std::string& path)
41 {
42 if (ParseXmlFile(path)) {
43 return true;
44 }
45 return false;
46 }
47
DecryptConfig(const std::string & path,std::string & result)48 bool ThermalSrvConfigParser::DecryptConfig(const std::string& path, std::string& result)
49 {
50 if (path.compare(0, SYSTEM_PREFIX_INDEX, SYSTEM_PREFIX) == 0) {
51 return false;
52 }
53 THERMAL_HILOGI(COMP_SVC, "start DecryptConfig");
54 void *handler = dlopen(THERMAL_CONFIG_LIBRARY_PATH, RTLD_LAZY);
55 if (handler == nullptr) {
56 THERMAL_HILOGE(COMP_SVC, "dlopen failed, reason : %{public}s", dlerror());
57 return false;
58 }
59
60 Func getDecryptConfig = reinterpret_cast<Func>(dlsym(handler, GET_THERMAL_EXT_CONGIH_FUNC));
61 if (getDecryptConfig == nullptr) {
62 THERMAL_HILOGE(COMP_SVC, "find function %{public}s failed, reason : %{public}s",
63 GET_THERMAL_EXT_CONGIH_FUNC, dlerror());
64 #ifndef FUZZ_TEST
65 dlclose(handler);
66 #endif
67 return false;
68 }
69
70 int32_t ret = getDecryptConfig(THERMAL_SERVICE_CONFIG_INDEX, result);
71 if (ret != 0) {
72 THERMAL_HILOGE(COMP_SVC, "decrypt config failed, ret:%{public}d", ret);
73 #ifndef FUZZ_TEST
74 dlclose(handler);
75 #endif
76 return false;
77 }
78
79 #ifndef FUZZ_TEST
80 dlclose(handler);
81 #endif
82 THERMAL_HILOGI(COMP_SVC, "end DecryptConfig");
83 return true;
84 }
85
ParseXmlFile(const std::string & path)86 bool ThermalSrvConfigParser::ParseXmlFile(const std::string& path)
87 {
88 xmlDocPtr docParse;
89 std::string result;
90 if (DecryptConfig(path, result)) {
91 // Initialize configuration file through the decrypt results
92 docParse = xmlReadMemory(
93 result.c_str(), int(result.size()), NULL, NULL, XML_PARSE_NOBLANKS);
94 } else {
95 THERMAL_HILOGI(COMP_SVC, "don't need decrypt");
96 docParse = xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS);
97 }
98
99 std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(docParse, xmlFreeDoc);
100 if (docPtr == nullptr) {
101 THERMAL_HILOGE(COMP_SVC, "init failed, read file failed");
102 return false;
103 }
104
105 auto rootNode = xmlDocGetRootElement(docPtr.get());
106 if (rootNode == nullptr) {
107 THERMAL_HILOGE(COMP_SVC, "get root node failed");
108 return false;
109 }
110
111 for (xmlNodePtr node = rootNode->xmlChildrenNode; node != nullptr; node = node->next) {
112 if (!ParseRootNode(node)) {
113 return false;
114 }
115 }
116 return true;
117 }
118
ParseRootNode(const xmlNodePtr & node)119 bool ThermalSrvConfigParser::ParseRootNode(const xmlNodePtr& node)
120 {
121 bool ret = false;
122 if (!xmlStrcmp(node->name, BAD_CAST"base")) {
123 ret = ParseBaseNode(node);
124 } else if (!xmlStrcmp(node->name, BAD_CAST"level")) {
125 ret = ParseLevelNode(node);
126 } else if (!xmlStrcmp(node->name, BAD_CAST"state")) {
127 ret = ParseStateNode(node);
128 } else if (!xmlStrcmp(node->name, BAD_CAST"action")) {
129 ret = ParseActionNode(node);
130 } else if (!xmlStrcmp(node->name, BAD_CAST"policy")) {
131 ret = ParsePolicyNode(node);
132 } else if (!xmlStrcmp(node->name, BAD_CAST"idle")) {
133 ret = ParseIdleNode(node);
134 } else if (!xmlStrcmp(node->name, BAD_CAST"fan")) {
135 ret = ParseFanNode(node);
136 } else if (!xmlStrcmp(node->name, BAD_CAST"comment")) {
137 ret = true;
138 } else {
139 THERMAL_HILOGE(COMP_SVC, "unknown root node %{public}s",
140 reinterpret_cast<const char*>(node->name));
141 }
142 return ret;
143 }
144
ParseBaseNode(const xmlNodePtr & node)145 bool ThermalSrvConfigParser::ParseBaseNode(const xmlNodePtr& node)
146 {
147 BaseInfoMap baseInfoMap;
148 xmlNodePtr cur = node->xmlChildrenNode;
149 while (cur != nullptr) {
150 if (xmlStrcmp(cur->name, BAD_CAST"item")) {
151 cur = cur->next;
152 continue;
153 }
154 BaseItem bi;
155 xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag");
156 if (xmlTag != nullptr) {
157 bi.tag = reinterpret_cast<char*>(xmlTag);
158 xmlFree(xmlTag);
159 } else {
160 THERMAL_HILOGE(COMP_SVC, "base tag is null");
161 return false;
162 }
163
164 xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value");
165 if (xmlValue != nullptr) {
166 bi.value = reinterpret_cast<char*>(xmlValue);
167 xmlFree(xmlValue);
168 } else {
169 THERMAL_HILOGE(COMP_SVC, "base value is null, tag: %{public}s", bi.tag.c_str());
170 return false;
171 }
172 baseInfoMap.emplace(bi.tag, bi.value);
173 cur = cur->next;
174 THERMAL_HILOGD(COMP_SVC, "tag: %{public}s, value: %{public}s", bi.tag.c_str(), bi.value.c_str());
175 }
176 auto tms = ThermalService::GetInstance();
177 tms->GetBaseinfoObj()->SetBaseInfo(baseInfoMap);
178 auto iter = baseInfoMap.find("sim_tz");
179 if (iter != baseInfoMap.end()) {
180 if (iter->second == "") {
181 tms->SetSimulationXml(false);
182 return true;
183 }
184 if (iter->second == "0" || iter->second == "1") {
185 tms->SetSimulationXml(static_cast<bool>(std::stoi(iter->second)));
186 return true;
187 }
188 return false;
189 }
190 tms->SetSimulationXml(false);
191 return true;
192 }
193
ParseLevelNode(const xmlNodePtr & node)194 bool ThermalSrvConfigParser::ParseLevelNode(const xmlNodePtr& node)
195 {
196 xmlNodePtr cur = node->xmlChildrenNode;
197 SensorClusterMap msc;
198 while (cur != nullptr) {
199 if (xmlStrcmp(cur->name, BAD_CAST"sensor_cluster")) {
200 cur = cur->next;
201 continue;
202 }
203 std::string name;
204 SensorClusterPtr sc = std::make_shared<ThermalConfigSensorCluster>();
205 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
206 if (xmlName != nullptr) {
207 name = reinterpret_cast<char*>(xmlName);
208 xmlFree(xmlName);
209 } else {
210 THERMAL_HILOGE(COMP_SVC, "level cluster name is null");
211 return false;
212 }
213 if (!ParseLevelState(cur, sc) || !ParseAuxSensorInfo(cur, sc) || !ParseSensorInfo(cur, sc)) {
214 THERMAL_HILOGE(COMP_SVC, "parse sensor info failed, cluster name: %{public}s", name.c_str());
215 return false;
216 }
217 xmlChar* desc = xmlGetProp(cur, BAD_CAST("desc"));
218 if (desc != nullptr) {
219 if (TrimStr(reinterpret_cast<char*>(desc)) == TRUE_STR) {
220 sc->SetDescFlag(true);
221 THERMAL_HILOGD(COMP_SVC, "cluster [%{public}s] is desc", name.c_str());
222 }
223 xmlFree(desc);
224 }
225 if (!sc->CheckStandard()) {
226 THERMAL_HILOGE(COMP_SVC, "cluster [%{public}s] some config error", name.c_str());
227 return false;
228 }
229 msc.emplace(std::pair(name, sc));
230 cur = cur->next;
231 }
232 auto tms = ThermalService::GetInstance();
233 tms->GetPolicy()->SetSensorClusterMap(msc);
234 return true;
235 }
236
ParseLevelState(const xmlNodePtr & cur,SensorClusterPtr & sc)237 bool ThermalSrvConfigParser::ParseLevelState(const xmlNodePtr& cur, SensorClusterPtr& sc)
238 {
239 for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
240 if (xmlStrcmp(subNode->name, BAD_CAST"state") || (subNode->properties == nullptr)) {
241 continue;
242 }
243 for (auto levStateProp = subNode->properties; levStateProp != nullptr; levStateProp = levStateProp->next) {
244 std::string propName = reinterpret_cast<const char*>(levStateProp->name);
245 xmlChar* xmlPropValue = xmlGetProp(subNode, levStateProp->name);
246 if (xmlPropValue != nullptr) {
247 std::string propValue = reinterpret_cast<char*>(xmlPropValue);
248 THERMAL_HILOGD(COMP_SVC, "level state: %{public}s, value: %{public}s",
249 propName.c_str(), propValue.c_str());
250 sc->AddState(propName, propValue);
251 xmlFree(xmlPropValue);
252 } else {
253 THERMAL_HILOGE(COMP_SVC, "level state prop [%{public}s] value is null", propName.c_str());
254 return false;
255 }
256 }
257 }
258 return true;
259 }
260
ParseAuxSensorInfo(const xmlNodePtr & cur,SensorClusterPtr & sc)261 bool ThermalSrvConfigParser::ParseAuxSensorInfo(const xmlNodePtr& cur, SensorClusterPtr& sc)
262 {
263 xmlChar* auxSensor = xmlGetProp(cur, BAD_CAST"aux_sensor");
264 if (auxSensor != nullptr) {
265 std::vector<std::string> auxsensors;
266 AuxSensorInfoMap auxSensorLevelInfo;
267 std::string auxsensor = reinterpret_cast<char*>(auxSensor);
268 sc->SetAuxFlag(true);
269 StringOperation::SplitString(auxsensor, auxsensors, ",");
270 for (uint32_t i = 0; i < auxsensors.size(); i++) {
271 std::vector<AuxLevelItem> auxLevelItems;
272 std::string sensorType = auxsensors[i];
273 if (sensorType.empty()) {
274 THERMAL_HILOGE(COMP_SVC, "aux sensor type is empty");
275 return false;
276 }
277 THERMAL_HILOGD(COMP_SVC, "parse aux sensor [%{public}s] item:", sensorType.c_str());
278 if (!ParseAuxSensorLevInfo(cur, auxsensors, i, auxLevelItems)) {
279 THERMAL_HILOGE(COMP_SVC, "parse aux sensor [%{public}s] sub node failed", sensorType.c_str());
280 return false;
281 }
282 if (auxLevelItems.empty()) {
283 THERMAL_HILOGE(COMP_SVC, "aux sensor [%{public}s] level info is empty", sensorType.c_str());
284 return false;
285 }
286 auxSensorLevelInfo.emplace(sensorType, auxLevelItems);
287 }
288 sc->SetAuxSensorLevelInfo(auxSensorLevelInfo);
289 xmlFree(auxSensor);
290 }
291 return true;
292 }
293
ParseAuxSensorLevInfo(const xmlNodePtr & cur,std::vector<std::string> & auxsensors,const uint32_t sensorIdx,std::vector<AuxLevelItem> & auxLevelItems)294 bool ThermalSrvConfigParser::ParseAuxSensorLevInfo(const xmlNodePtr& cur,
295 std::vector<std::string>& auxsensors, const uint32_t sensorIdx, std::vector<AuxLevelItem>& auxLevelItems)
296 {
297 for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
298 if (xmlStrcmp(subNode->name, BAD_CAST"item")) {
299 continue;
300 }
301 std::string tempRangeStr;
302 AuxLevelItem auxlevelItem;
303 if (!ParseAuxSensorTriggerRange(subNode, auxsensors, tempRangeStr, sensorIdx)) {
304 THERMAL_HILOGE(COMP_SVC, "parse aux sensor range failed");
305 return false;
306 }
307
308 std::vector<std::string> tempRanges;
309 StringOperation::SplitString(tempRangeStr, tempRanges, "_");
310 if (static_cast<uint32_t>(tempRanges.size()) < AUX_SENSOR_RANGE_LEN) {
311 THERMAL_HILOGE(COMP_SVC, "aux sensor temp range split failed");
312 return false;
313 }
314 const int32_t INDEX0 = 0;
315 const int32_t INDEX1 = 1;
316 StrToInt(tempRanges[INDEX0], auxlevelItem.lowerTemp);
317 StrToInt(tempRanges[INDEX1], auxlevelItem.upperTemp);
318 xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
319 if (xmlLevel != nullptr) {
320 StrToInt(reinterpret_cast<char*>(xmlLevel), auxlevelItem.level);
321 xmlFree(xmlLevel);
322 } else {
323 THERMAL_HILOGE(COMP_SVC, "aux sensor level is null");
324 return false;
325 }
326 THERMAL_HILOGD(COMP_SVC, "lowerTemp: %{public}d, upperTemp: %{public}d",
327 auxlevelItem.lowerTemp, auxlevelItem.upperTemp);
328 auxLevelItems.push_back(auxlevelItem);
329 }
330 return true;
331 }
332
ParseAuxSensorTriggerRange(const xmlNodePtr & subNode,std::vector<std::string> & auxsensors,std::string & tempRangeStr,const uint32_t sensorIdx)333 bool ThermalSrvConfigParser::ParseAuxSensorTriggerRange(const xmlNodePtr& subNode,
334 std::vector<std::string>& auxsensors, std::string& tempRangeStr, const uint32_t sensorIdx)
335 {
336 xmlChar* xmlTriggerRange = xmlGetProp(subNode, BAD_CAST("aux_trigger_range"));
337 if (xmlTriggerRange != nullptr) {
338 std::string auxTriggerRange = reinterpret_cast<char*>(xmlTriggerRange);
339 if (!auxTriggerRange.empty()) {
340 std::vector<std::string> auxTempranges;
341 StringOperation::SplitString(auxTriggerRange, auxTempranges, ",");
342 if (auxsensors.size() > auxTempranges.size()) {
343 THERMAL_HILOGE(COMP_SVC, "aux sensor size (%{public}zu) don't match range size (%{public}zu)",
344 auxsensors.size(), auxTempranges.size());
345 xmlFree(xmlTriggerRange);
346 return false;
347 }
348 tempRangeStr = auxTempranges[sensorIdx];
349 } else {
350 THERMAL_HILOGE(COMP_SVC, "aux sensor trigger range is empty");
351 return false;
352 }
353 xmlFree(xmlTriggerRange);
354 } else {
355 THERMAL_HILOGE(COMP_SVC, "aux sensor trigger range is null");
356 return false;
357 }
358 return true;
359 }
360
ParseSensorInfo(const xmlNodePtr & cur,SensorClusterPtr & sc)361 bool ThermalSrvConfigParser::ParseSensorInfo(const xmlNodePtr& cur, SensorClusterPtr& sc)
362 {
363 SensorInfoMap sensorLevelInfo;
364 std::vector<std::string> sensors;
365 xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor");
366 if (xmlSensor != nullptr) {
367 StringOperation::SplitString(reinterpret_cast<char*>(xmlSensor), sensors, ",");
368 if (sensors.empty()) {
369 THERMAL_HILOGE(COMP_SVC, "sensor type is empty");
370 return false;
371 }
372 for (uint32_t i = 0; i < sensors.size(); i++) {
373 std::string sensorType = sensors.at(i);
374 std::vector<LevelItem> levelItems;
375 if (!ParseSensorLevelInfo(cur, levelItems, sensors, i, sc)) {
376 THERMAL_HILOGE(COMP_SVC, "parse sensor [%{public}s] level failed", sensorType.c_str());
377 return false;
378 }
379 if (levelItems.empty()) {
380 THERMAL_HILOGE(COMP_SVC, "sensor [%{public}s] level info is empty", sensorType.c_str());
381 return false;
382 }
383 sensorLevelInfo.emplace(std::pair(sensorType, levelItems));
384 }
385 sc->SetSensorLevelInfo(sensorLevelInfo);
386 xmlFree(xmlSensor);
387 } else {
388 THERMAL_HILOGE(COMP_SVC, "sensor type is null");
389 return false;
390 }
391 return true;
392 }
393
ParseSensorLevelInfo(const xmlNodePtr & cur,std::vector<LevelItem> & levelItems,std::vector<std::string> & sensors,const uint32_t sensorIdx,SensorClusterPtr & sc)394 bool ThermalSrvConfigParser::ParseSensorLevelInfo(const xmlNodePtr& cur, std::vector<LevelItem>& levelItems,
395 std::vector<std::string>& sensors, const uint32_t sensorIdx, SensorClusterPtr& sc)
396 {
397 for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
398 if (xmlStrcmp(subNode->name, BAD_CAST"item")) {
399 continue;
400 }
401 LevelItem levelItem;
402 if (!ParseLevelThreshold(subNode, levelItem, sensors, sensorIdx)) {
403 THERMAL_HILOGE(COMP_SVC, "parse level threshold failed");
404 return false;
405 }
406
407 xmlChar* tempRiseRates = xmlGetProp(subNode, BAD_CAST("temp_rise_rate"));
408 if (tempRiseRates != nullptr) {
409 std::vector<std::string> rates;
410 sc->SetRateFlag(true);
411 StringOperation::SplitString(reinterpret_cast<char*>(tempRiseRates), rates, ",");
412 if (sensors.size() != rates.size()) {
413 THERMAL_HILOGE(COMP_SVC, "sensor size (%{public}zu) don't match rise rate (%{public}zu)",
414 sensors.size(), rates.size());
415 xmlFree(tempRiseRates);
416 return false;
417 }
418 StringOperation::StrToDouble(rates.at(sensorIdx), levelItem.tempRiseRate);
419 }
420 levelItems.push_back(levelItem);
421 xmlFree(tempRiseRates);
422 }
423 return true;
424 }
425
ParseLevelThreshold(const xmlNodePtr & subNode,LevelItem & levelItem,std::vector<std::string> & sensors,const uint32_t sensorIdx)426 bool ThermalSrvConfigParser::ParseLevelThreshold(const xmlNodePtr& subNode, LevelItem& levelItem,
427 std::vector<std::string>& sensors, const uint32_t sensorIdx)
428 {
429 std::vector<std::string> thresholds;
430 std::vector<std::string> thresholdClrs;
431 xmlChar* xmlThreshold = xmlGetProp(subNode, BAD_CAST("threshold"));
432 if (xmlThreshold != nullptr) {
433 StringOperation::SplitString(reinterpret_cast<char*>(xmlThreshold), thresholds, ",");
434 xmlFree(xmlThreshold);
435 } else {
436 THERMAL_HILOGE(COMP_SVC, "threshold is null");
437 return false;
438 }
439 xmlChar* xmlThresholdClr = xmlGetProp(subNode, BAD_CAST("threshold_clr"));
440 if (xmlThresholdClr != nullptr) {
441 StringOperation::SplitString(reinterpret_cast<char*>(xmlThresholdClr), thresholdClrs, ",");
442 xmlFree(xmlThresholdClr);
443 } else {
444 THERMAL_HILOGE(COMP_SVC, "threshold_clr is null");
445 return false;
446 }
447 if (sensors.size() != thresholds.size() || sensors.size() != thresholdClrs.size()) {
448 THERMAL_HILOGE(COMP_SVC,
449 "sensor size (%{public}zu) don't match threshold (%{public}zu) or clr (%{public}zu)",
450 sensors.size(), thresholds.size(), thresholdClrs.size());
451 return false;
452 }
453 xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
454 if (xmlLevel != nullptr) {
455 StringOperation::StrToUint(reinterpret_cast<char*>(xmlLevel), levelItem.level);
456 xmlFree(xmlLevel);
457 } else {
458 THERMAL_HILOGE(COMP_SVC, "level is null");
459 return false;
460 }
461
462 StrToInt(thresholds.at(sensorIdx), levelItem.threshold);
463 StrToInt(thresholdClrs.at(sensorIdx), levelItem.thresholdClr);
464 return true;
465 }
466
ParseStateNode(const xmlNodePtr & node)467 bool ThermalSrvConfigParser::ParseStateNode(const xmlNodePtr& node)
468 {
469 auto cur = node->xmlChildrenNode;
470 std::vector<StateItem> stateItems;
471 while (cur != nullptr) {
472 if (xmlStrcmp(cur->name, BAD_CAST"item")) {
473 cur = cur->next;
474 continue;
475 }
476 StateItem si;
477 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
478 if (xmlName != nullptr) {
479 si.name = reinterpret_cast<char*>(xmlName);
480 xmlFree(xmlName);
481 } else {
482 THERMAL_HILOGE(COMP_SVC, "state name is null");
483 return false;
484 }
485
486 xmlChar* param = xmlGetProp(cur, BAD_CAST("param"));
487 if (param != nullptr) {
488 si.params = reinterpret_cast<char*>(param);
489 si.isExistParam = true;
490 xmlFree(param);
491 }
492 stateItems.push_back(si);
493 THERMAL_HILOGD(COMP_SVC, "state: %{public}s, params: %{public}s", si.name.c_str(), si.params.c_str());
494 cur = cur->next;
495 }
496 auto tms = ThermalService::GetInstance();
497 tms->GetStateMachineObj()->SetStateItem(stateItems);
498 return true;
499 }
500
ParseActionNode(const xmlNodePtr & node)501 bool ThermalSrvConfigParser::ParseActionNode(const xmlNodePtr& node)
502 {
503 auto cur = node->xmlChildrenNode;
504 std::vector<ActionItem> actionItems;
505 while (cur != nullptr) {
506 if (xmlStrcmp(cur->name, BAD_CAST"item")) {
507 cur = cur->next;
508 continue;
509 }
510
511 ActionItem ai;
512 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
513 if (xmlName != nullptr) {
514 ai.name = reinterpret_cast<char*>(xmlName);
515 xmlFree(xmlName);
516 } else {
517 THERMAL_HILOGE(COMP_SVC, "action name is null");
518 return false;
519 }
520
521 ParseActionInfo(cur, ai);
522 actionItems.push_back(ai);
523 cur = cur->next;
524 }
525 auto tms = ThermalService::GetInstance();
526 tms->GetActionManagerObj()->SetActionItem(actionItems);
527 return true;
528 }
529
ParseActionInfo(const xmlNodePtr & cur,ActionItem & ai)530 bool ThermalSrvConfigParser::ParseActionInfo(const xmlNodePtr& cur, ActionItem& ai)
531 {
532 xmlChar* param = xmlGetProp(cur, BAD_CAST("param"));
533 if (param != nullptr) {
534 ai.params = reinterpret_cast<char*>(param);
535 xmlFree(param);
536 }
537 xmlChar* uid = xmlGetProp(cur, BAD_CAST("uid"));
538 if (uid != nullptr) {
539 ai.uid = reinterpret_cast<char*>(uid);
540 xmlFree(uid);
541 }
542 xmlChar* protocol = xmlGetProp(cur, BAD_CAST("protocol"));
543 if (protocol != nullptr) {
544 ai.protocol = reinterpret_cast<char*>(protocol);
545 xmlFree(protocol);
546 }
547 xmlChar* strict = xmlGetProp(cur, BAD_CAST("strict"));
548 if (strict != nullptr) {
549 ai.strict = (TrimStr(reinterpret_cast<char*>(strict)) == TRUE_STR);
550 xmlFree(strict);
551 }
552 xmlChar* event = xmlGetProp(cur, BAD_CAST("event"));
553 if (event != nullptr) {
554 ai.enableEvent = (TrimStr(reinterpret_cast<char*>(event)) == TRUE_STR);
555 xmlFree(event);
556 }
557 THERMAL_HILOGD(COMP_SVC,
558 "ai.name: %{public}s, ai.strict: %{public}d, ai.params: %{public}s, ai.uid: %{public}s," \
559 "ai.strict: %{public}s, ai.enableEvent: %{public}d",
560 ai.name.c_str(), ai.strict, ai.params.c_str(), ai.uid.c_str(), ai.protocol.c_str(), ai.enableEvent);
561 return true;
562 }
563
ParsePolicyNode(const xmlNodePtr & node)564 bool ThermalSrvConfigParser::ParsePolicyNode(const xmlNodePtr& node)
565 {
566 auto cur = node->xmlChildrenNode;
567 ThermalPolicy::PolicyConfigMap clusterPolicyMap;
568 while (cur != nullptr) {
569 if (xmlStrcmp(cur->name, BAD_CAST"config")) {
570 cur = cur->next;
571 continue;
572 }
573 PolicyConfig policyConfig;
574 std::string clusterName;
575 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
576 if (xmlName != nullptr) {
577 clusterName = reinterpret_cast<char*>(xmlName);
578 xmlFree(xmlName);
579 } else {
580 THERMAL_HILOGE(COMP_SVC, "policy config name is null");
581 return false;
582 }
583
584 xmlChar* xmlLevel = xmlGetProp(cur, BAD_CAST"level");
585 if (xmlLevel != nullptr) {
586 StringOperation::StrToUint(reinterpret_cast<char*>(xmlLevel), policyConfig.level);
587 THERMAL_HILOGD(COMP_SVC, "policyConfig.name: %{public}s, policyConfig.level: %{public}u",
588 clusterName.c_str(), policyConfig.level);
589 xmlFree(xmlLevel);
590 } else {
591 THERMAL_HILOGE(COMP_SVC, "policy [%{public}s] level is null", clusterName.c_str());
592 return false;
593 }
594
595 ParsePolicyActionInfo(cur, policyConfig);
596
597 const auto& clusterIter = clusterPolicyMap.find(clusterName);
598 if (clusterIter == clusterPolicyMap.end()) {
599 std::vector<PolicyConfig> policyList;
600 policyList.push_back(policyConfig);
601 clusterPolicyMap.emplace(clusterName, policyList);
602 } else {
603 clusterIter->second.push_back(policyConfig);
604 }
605 cur = cur->next;
606 }
607 auto tms = ThermalService::GetInstance();
608 tms->GetPolicy()->SetPolicyMap(clusterPolicyMap);
609 return true;
610 }
611
ParsePolicyActionInfo(const xmlNodePtr & cur,PolicyConfig & policyConfig)612 bool ThermalSrvConfigParser::ParsePolicyActionInfo(const xmlNodePtr& cur, PolicyConfig& policyConfig)
613 {
614 for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
615 if (!xmlStrcmp(subNode->name, BAD_CAST"comment")) {
616 continue;
617 }
618 PolicyAction policyAction;
619 policyAction.actionName = reinterpret_cast<const char*>(subNode->name);
620 xmlChar* actionValue = xmlNodeGetContent(subNode);
621 if (actionValue != nullptr) {
622 policyAction.actionValue = reinterpret_cast<char*>(actionValue);
623 THERMAL_HILOGD(COMP_SVC,
624 "policyAction.actionNodeName: %{public}s, policyAction.value: %{public}s",
625 policyAction.actionName.c_str(), policyAction.actionValue.c_str());
626 xmlFree(actionValue);
627 } else {
628 THERMAL_HILOGE(COMP_SVC, "action [%{public}s] value is null", policyAction.actionName.c_str());
629 return false;
630 }
631
632 if (subNode->properties == nullptr) {
633 policyAction.isProp = false;
634 policyConfig.policyActionList.push_back(policyAction);
635 continue;
636 }
637 for (auto actionProp = subNode->properties; actionProp != nullptr; actionProp = actionProp->next) {
638 std::string propName = reinterpret_cast<const char*>(actionProp->name);
639 xmlChar* xmlPropValue = xmlGetProp(subNode, actionProp->name);
640 if (xmlPropValue != nullptr) {
641 std::string propValue = reinterpret_cast<char*>(xmlPropValue);
642 THERMAL_HILOGD(COMP_SVC, "propName.name: %{public}s, propValue:%{public}s",
643 propName.c_str(), propValue.c_str());
644 policyAction.actionPropMap.emplace(std::pair(propName, propValue));
645 xmlFree(xmlPropValue);
646 } else {
647 THERMAL_HILOGE(COMP_SVC, "prop [%{public}s] value is null", propName.c_str());
648 return false;
649 }
650 policyAction.isProp = true;
651 }
652 policyConfig.policyActionList.push_back(policyAction);
653 }
654 return true;
655 }
656
ParseIdleNode(const xmlNodePtr & node)657 bool ThermalSrvConfigParser::ParseIdleNode(const xmlNodePtr& node)
658 {
659 IdleState idleState;
660 for (xmlNodePtr subNode = node->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
661 if (!xmlStrcmp(subNode->name, BAD_CAST"thermallevel")) {
662 xmlChar* value = xmlNodeGetContent(subNode);
663 if (value != nullptr) {
664 StrToInt(reinterpret_cast<char*>(value), idleState.level);
665 xmlFree(value);
666 }
667 } else if (!xmlStrcmp(subNode->name, BAD_CAST"soc")) {
668 xmlChar* value = xmlNodeGetContent(subNode);
669 if (value != nullptr) {
670 StrToInt(reinterpret_cast<char*>(value), idleState.soc);
671 xmlFree(value);
672 }
673 } else if (!xmlStrcmp(subNode->name, BAD_CAST"charging")) {
674 xmlChar* value = xmlNodeGetContent(subNode);
675 if (value != nullptr) {
676 StrToInt(reinterpret_cast<char*>(value), idleState.charging);
677 xmlFree(value);
678 }
679 } else if (!xmlStrcmp(subNode->name, BAD_CAST"current")) {
680 xmlChar* value = xmlNodeGetContent(subNode);
681 if (value != nullptr) {
682 StrToInt(reinterpret_cast<char*>(value), idleState.current);
683 xmlFree(value);
684 }
685 } else {
686 THERMAL_HILOGD(COMP_SVC, "not supported node, name=%{public}s", subNode->name);
687 }
688 }
689 THERMAL_HILOGI(COMP_SVC, "level=%{public}d, soc=%{public}d, charging=%{public}d, current=%{public}d",
690 idleState.level, idleState.soc, idleState.charging, idleState.current);
691 auto tms = ThermalService::GetInstance();
692 tms->GetStateMachineObj()->SetIdleStateConfig(idleState);
693 return true;
694 }
695
ParseFanNode(const xmlNodePtr & node)696 bool ThermalSrvConfigParser::ParseFanNode(const xmlNodePtr &node)
697 {
698 FanFaultInfoMap fanFaultInfoMap;
699 xmlNodePtr cur = node->xmlChildrenNode;
700
701 while (cur != nullptr) {
702 if (xmlStrcmp(cur->name, BAD_CAST"sensor_cluster")) {
703 cur = cur->next;
704 continue;
705 }
706 xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor");
707 if (xmlSensor == nullptr) {
708 return false;
709 }
710 std::vector<std::string> sensors;
711 std::string sensorStr = reinterpret_cast<char*>(xmlSensor);
712 StringOperation::SplitString(sensorStr, sensors, ",");
713 xmlFree(xmlSensor);
714 if (!ParseFanFaultInfo(cur, sensors, fanFaultInfoMap)) {
715 THERMAL_HILOGE(COMP_SVC, "ParseFanFaultInfo failed");
716 return false;
717 }
718 cur = cur->next;
719 }
720
721 auto tms = ThermalService::GetInstance();
722 tms->GetFanFaultDetect()->SetFaultInfoMap(fanFaultInfoMap);
723 return true;
724 }
725
ParseFanFaultInfo(const xmlNodePtr & node,std::vector<std::string> & sensors,FanFaultInfoMap & fanFaultInfoMap)726 bool ThermalSrvConfigParser::ParseFanFaultInfo(const xmlNodePtr& node,
727 std::vector<std::string> &sensors, FanFaultInfoMap &fanFaultInfoMap)
728 {
729 uint32_t sensorNum = sensors.size();
730 xmlNodePtr cur = node->xmlChildrenNode;
731
732 while (cur != nullptr) {
733 if (xmlStrcmp(cur->name, BAD_CAST"item")) {
734 cur = cur->next;
735 continue;
736 }
737 FanSensorInfo fanSensorInfo;
738 xmlChar* xmlFault = xmlGetProp(cur, BAD_CAST"fault");
739 if (xmlFault == nullptr) {
740 return false;
741 }
742 std::string faultStr = reinterpret_cast<char*>(xmlFault);
743 xmlFree(xmlFault);
744 int32_t faultNum;
745 StrToInt(faultStr, faultNum);
746 xmlChar* xmlThreshold = xmlGetProp(cur, BAD_CAST"threshold");
747 if (xmlThreshold == nullptr) {
748 return false;
749 }
750 std::string thresholdStr = reinterpret_cast<char*>(xmlThreshold);
751 std::vector<std::string> thresholds;
752 StringOperation::SplitString(thresholdStr, thresholds, ",");
753 xmlFree(xmlThreshold);
754 if (thresholds.size() != sensorNum) {
755 return false;
756 }
757 for (uint32_t i = 0; i < sensorNum; i++) {
758 int32_t value;
759 StrToInt(thresholds[i], value);
760 fanSensorInfo.insert(std::make_pair(sensors[i], value));
761 }
762 fanFaultInfoMap.insert(std::make_pair(faultNum, fanSensorInfo));
763 cur = cur->next;
764 }
765
766 return true;
767 }
768 } // namespace PowerMgr
769 } // namespace OHOS
770