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