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