• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_config_file_parser.h"
17 
18 #include "string_operation.h"
19 
20 namespace OHOS {
21 namespace PowerMgr {
22 namespace {
23 static const std::string VENDOR_THERMAL_SRV_CONFIG_XML = "/vendor/etc/thermal_config/thermal_service_config.xml";
24 static const std::string SYSTEM_THERMAL_SRV_CONFIG_XML = "/system/etc/thermal_config/thermal_service_config.xml";
25 } // namespace
Init()26 bool ThermalConfigFileParser::Init()
27 {
28     if (!LoadThermalSrvConfigXml(VENDOR_THERMAL_SRV_CONFIG_XML)) {
29         THERMAL_HILOGE(LABEL_TEST, "Failed to load vendor thermal config xml file");
30         if (!LoadThermalSrvConfigXml(SYSTEM_THERMAL_SRV_CONFIG_XML)) {
31             THERMAL_HILOGE(LABEL_TEST, "Failed to load system thermal config xml file");
32             return false;
33         }
34     }
35     return true;
36 }
37 
GetActionEnableEvent(const std::string & actionName)38 bool ThermalConfigFileParser::GetActionEnableEvent(const std::string& actionName)
39 {
40     for (auto iter : actionItem_) {
41         if (iter.name.compare(actionName) == 0 ||
42             actionName.find(iter.name) != std::string::npos) {
43             return iter.enableEvent;
44         }
45     }
46     return false;
47 }
48 
GetActionStrict(const std::string & actionName)49 bool ThermalConfigFileParser::GetActionStrict(const std::string& actionName)
50 {
51     for (auto iter : actionItem_) {
52         if (iter.name.compare(actionName) == 0 ||
53             actionName.find(iter.name) != std::string::npos) {
54             return iter.strict;
55         }
56     }
57     return false;
58 }
59 
GetActionPolicy(const std::string & name,uint32_t level,std::vector<PolicyAction> & policy)60 bool ThermalConfigFileParser::GetActionPolicy(const std::string& name, uint32_t level,
61     std::vector<PolicyAction>& policy)
62 {
63     auto vPolicyCfg = policyConfigMap_.find(name);
64     if (vPolicyCfg != policyConfigMap_.end()) {
65         for (auto cfgIter : vPolicyCfg->second) {
66             if (cfgIter.level == level) {
67                 policy = cfgIter.vPolicyAction;
68                 return true;
69             }
70         }
71     }
72     return false;
73 }
74 
GetStateItem()75 std::vector<StateItem> ThermalConfigFileParser::GetStateItem()
76 {
77     return stateItem_;
78 }
79 
LoadThermalSrvConfigXml(const std::string & path)80 bool ThermalConfigFileParser::LoadThermalSrvConfigXml(const std::string& path)
81 {
82     if (!ParseXmlFile(path)) {
83         return false;
84     }
85     return true;
86 }
87 
ParseXmlFile(const std::string & path)88 bool ThermalConfigFileParser::ParseXmlFile(const std::string& path)
89 {
90     std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
91         xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
92     if (docPtr == nullptr) {
93         THERMAL_HILOGE(LABEL_TEST, "ParseXMLFile::Init failed, read file failed.");
94         return false;
95     }
96 
97     auto rootNode = xmlDocGetRootElement(docPtr.get());
98     if (rootNode == nullptr) {
99         THERMAL_HILOGE(LABEL_TEST, "ParseXMLFile::Get root node failed.");
100         return false;
101     }
102 
103     for (auto node = rootNode->children; node; node = node->next) {
104         if (node == nullptr) {
105             continue;
106         }
107         if (!xmlStrcmp(node->name, BAD_CAST"base")) {
108             ParseBaseNode(node);
109         } else if (!xmlStrcmp(node->name, BAD_CAST"level")) {
110             ParseLevelNode(node);
111         } else if (!xmlStrcmp(node->name, BAD_CAST"state")) {
112             ParseStateNode(node);
113         } else if (!xmlStrcmp(node->name, BAD_CAST"action")) {
114             ParseActionNode(node);
115         } else if (!xmlStrcmp(node->name, BAD_CAST"policy")) {
116             ParsePolicyNode(node);
117         } else if (!xmlStrcmp(node->name, BAD_CAST"idle")) {
118             ParseIdleNode(node);
119         }
120     }
121     return true;
122 }
123 
ParseBaseNode(xmlNodePtr node)124 void ThermalConfigFileParser::ParseBaseNode(xmlNodePtr node)
125 {
126     auto curNode = node->xmlChildrenNode;
127     while (curNode != nullptr) {
128         BaseItem item;
129         xmlChar* xmlTag = xmlGetProp(curNode, BAD_CAST"tag");
130         if (xmlTag != nullptr) {
131             item.tag = (char *)xmlTag;
132             xmlFree(xmlTag);
133         }
134 
135         xmlChar* xmlValue = xmlGetProp(curNode, BAD_CAST"value");
136         if (xmlValue != nullptr) {
137             item.value = (char *)xmlValue;
138             xmlFree(xmlValue);
139         }
140         baseInfoMap_.emplace(item.tag, item.value);
141         curNode = curNode->next;
142         THERMAL_HILOGD(LABEL_TEST, "tag: %{public}s, value:%{public}s",
143             item.tag.c_str(), item.value.c_str());
144     }
145 }
146 
ParseLevelNode(xmlNodePtr node)147 void ThermalConfigFileParser::ParseLevelNode(xmlNodePtr node)
148 {
149     auto curNode = node->xmlChildrenNode;
150     while (curNode != nullptr) {
151         std::string name;
152         std::shared_ptr<ThermalConfigSensorCluster> sc = std::make_shared<ThermalConfigSensorCluster>();
153         xmlChar* xmlName = xmlGetProp(curNode, BAD_CAST"name");
154         if (xmlName != nullptr) {
155             name = (char *)xmlName;
156             xmlFree(xmlName);
157         }
158         ParseAuxSensorInfo(curNode, sc);
159         ParseSensorInfo(curNode, sc);
160         xmlChar* desc = xmlGetProp(curNode, BAD_CAST("desc"));
161         if (desc != nullptr) {
162             std::string descValue = (char *)desc;
163             if (atoi(descValue.c_str()) == 1) {
164                 sc->SetDescFlag(true);
165             }
166             xmlFree(desc);
167         }
168         sensorClusterMap_.emplace(std::pair(name, sc));
169         curNode = curNode->next;
170     }
171 }
172 
ParseStateNode(xmlNodePtr node)173 void ThermalConfigFileParser::ParseStateNode(xmlNodePtr node)
174 {
175     auto curNode = node->xmlChildrenNode;
176     while (curNode != nullptr) {
177         StateItem si;
178         xmlChar* xmlName = xmlGetProp(curNode, BAD_CAST"name");
179         if (xmlName != nullptr) {
180             si.name = (char *)xmlName;
181             xmlFree(xmlName);
182         }
183 
184         xmlChar* param = xmlGetProp(curNode, BAD_CAST("param"));
185         if (param != nullptr) {
186             si.params =(char *)param;
187             si.isExistParam = true;
188             xmlFree(param);
189         }
190         stateItem_.push_back(si);
191         THERMAL_HILOGI(LABEL_TEST, "si.name: %{public}s, si.params %{public}s",
192             si.name.c_str(), si.params.c_str());
193         curNode = curNode->next;
194     }
195 }
196 
ParseActionNode(xmlNodePtr node)197 void ThermalConfigFileParser::ParseActionNode(xmlNodePtr node)
198 {
199     auto curNode = node->xmlChildrenNode;
200     while (curNode != nullptr) {
201         if (!xmlStrcmp(curNode->name, BAD_CAST"item")) {
202             ActionItem ai;
203             xmlChar* xmlName = xmlGetProp(curNode, BAD_CAST"name");
204             if (xmlName != nullptr) {
205                 ai.name = (char *)xmlName;
206                 xmlFree(xmlName);
207             }
208             xmlChar* param = xmlGetProp(curNode, BAD_CAST("param"));
209             if (param != nullptr) {
210                 ai.params = (char *) param;
211                 xmlFree(param);
212             }
213             xmlChar* protocol = xmlGetProp(curNode, BAD_CAST("protocol"));
214             if (protocol != nullptr) {
215                 ai.protocol = (char *) protocol;
216                 xmlFree(protocol);
217             }
218             xmlChar* strict = xmlGetProp(curNode, BAD_CAST("strict"));
219             if (strict != nullptr) {
220                 std::string strictValue = (char *)strict;
221                 ai.strict = atoi(strictValue.c_str()) == 1 ? true : false;
222                 xmlFree(strict);
223             }
224             xmlChar* event = xmlGetProp(curNode, BAD_CAST("event"));
225             if (event != nullptr) {
226                 std::string eventValue = (char *)event;
227                 ai.enableEvent = atoi(eventValue.c_str()) == 1 ? true : false;
228                 xmlFree(event);
229             }
230             THERMAL_HILOGD(LABEL_TEST,
231                 "ai.name: %{public}s, ai.strict: %{public}d, ai.params: %{public}s, ai.strict: %{public}s, "    \
232                 "ai.enableEvent: %{public}d",
233                 ai.name.c_str(), ai.strict, ai.params.c_str(), ai.protocol.c_str(), ai.enableEvent);
234 
235             actionItem_.push_back(ai);
236         }
237         curNode = curNode->next;
238     }
239 }
240 
ParsePolicyNode(xmlNodePtr node)241 void ThermalConfigFileParser::ParsePolicyNode(xmlNodePtr node)
242 {
243     auto curNode = node->xmlChildrenNode;
244     while (curNode != nullptr) {
245         PolicyConfig policyConfig;
246         std::string clusterName;
247         xmlChar* xmlName = xmlGetProp(curNode, BAD_CAST"name");
248         if (xmlName != nullptr) {
249             clusterName = (char *)xmlName;
250             xmlFree(xmlName);
251         }
252 
253         xmlChar* xmlLevel = xmlGetProp(curNode, BAD_CAST"level");
254         if (xmlLevel != nullptr) {
255             uint32_t level = static_cast<uint32_t>(atoi((char *)xmlLevel));
256             policyConfig.level = level;
257             THERMAL_HILOGD(LABEL_TEST, "policyConfig.name: %{public}s, policyConfig.level:%{public}d",
258                 clusterName.c_str(), level);
259             xmlFree(xmlLevel);
260         }
261 
262         ParsePolicySubnode(curNode, policyConfig);
263 
264         const auto& clusterIter = policyConfigMap_.find(clusterName);
265         THERMAL_HILOGD(LABEL_TEST, "clusterName: %{public}s", clusterName.c_str());
266         if (clusterIter == policyConfigMap_.end()) {
267             std::vector<PolicyConfig> policyList;
268             policyList.push_back(policyConfig);
269             policyConfigMap_.emplace(clusterName, policyList);
270         } else {
271             clusterIter->second.push_back(policyConfig);
272         }
273         curNode = curNode->next;
274     }
275 }
276 
ParseIdleNode(xmlNodePtr node)277 void ThermalConfigFileParser::ParseIdleNode(xmlNodePtr node)
278 {
279     IdleState idleState;
280     for (auto subNode = node->children; subNode != nullptr; subNode = subNode->next) {
281         if (!xmlStrcmp(subNode->name, BAD_CAST"thermallevel")) {
282             xmlChar* value = xmlNodeGetContent(subNode);
283             if (value != nullptr) {
284                 idleState.level = atoi((char *)value);
285                 xmlFree(value);
286             }
287         } else if (!xmlStrcmp(subNode->name, BAD_CAST"soc")) {
288             xmlChar* value = xmlNodeGetContent(subNode);
289             if (value != nullptr) {
290                 idleState.soc = atoi((char *)value);
291                 xmlFree(value);
292             }
293         } else if (!xmlStrcmp(subNode->name, BAD_CAST"charging")) {
294             xmlChar* value = xmlNodeGetContent(subNode);
295             if (value != nullptr) {
296                 idleState.charging = atoi((char *)value);
297                 xmlFree(value);
298             }
299         } else if (!xmlStrcmp(subNode->name, BAD_CAST"current")) {
300             xmlChar* value = xmlNodeGetContent(subNode);
301             if (value != nullptr) {
302                 idleState.current = atoi((char *)value);
303                 xmlFree(value);
304             }
305         } else {
306             THERMAL_HILOGD(LABEL_TEST, "not supported node, name=%{public}s", subNode->name);
307         }
308     }
309     THERMAL_HILOGI(LABEL_TEST, "level=%{public}d, soc=%{public}d, charging=%{public}d, current=%{public}d",
310                    idleState.level, idleState.soc, idleState.charging, idleState.current);
311 }
312 
ParseAuxSensorInfo(const xmlNode * cur,std::shared_ptr<ThermalConfigSensorCluster> & sc)313 void ThermalConfigFileParser::ParseAuxSensorInfo(const xmlNode* cur, std::shared_ptr<ThermalConfigSensorCluster>& sc)
314 {
315     xmlChar* auxSensorInfo = xmlGetProp(cur, BAD_CAST"aux_sensor");
316     if (auxSensorInfo != nullptr) {
317         std::vector<std::string> auxSensorList;
318         AuxSensorInfoMap auxSensorLevelInfo;
319         std::string auxSensor = (char *)auxSensorInfo;
320         sc->SetAuxFlag(true);
321         StringOperation::SplitString(auxSensor, auxSensorList, ",");
322         for (uint32_t i = 0; i < auxSensorList.size(); i++) {
323             std::string sensorType = auxSensorList[i];
324             if (auxSensorList[i].empty()) {
325                 continue;
326             }
327             THERMAL_HILOGD(LABEL_TEST, "aux_sensor item: %{public}s", sensorType.c_str());
328             auxSensorLevelInfo.emplace(sensorType, ParseAuxSensorSubnodeInfo(cur, auxSensorList, i));
329         }
330         sc->SetAuxSensorLevelInfo(auxSensorLevelInfo);
331         xmlFree(auxSensorInfo);
332     }
333 }
334 
ParseSensorInfo(const xmlNode * cur,std::shared_ptr<ThermalConfigSensorCluster> & sc)335 void ThermalConfigFileParser::ParseSensorInfo(const xmlNode* cur, std::shared_ptr<ThermalConfigSensorCluster>& sc)
336 {
337     SensorInfoMap sensorLevelInfo;
338     std::vector<std::string> sensors;
339     xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor");
340     if (xmlSensor != nullptr) {
341         StringOperation::SplitString((char *)xmlSensor, sensors, ",");
342         for (uint32_t i = 0; i < sensors.size(); i++) {
343             std::string sensorType = sensors.at(i);
344             std::vector<LevelItem> vItem;
345             ParseSensorSubnodeInfo(cur, vItem, sensors, i, sc);
346             sensorLevelInfo.emplace(std::pair(sensorType, vItem));
347         }
348         sc->SetSensorLevelInfo(sensorLevelInfo);
349         xmlFree(xmlSensor);
350     }
351 }
352 
ParseAuxSensorSubnodeInfo(const xmlNode * cur,std::vector<std::string> & auxSensorList,const uint32_t i)353 std::vector<AuxLevelItem> ThermalConfigFileParser::ParseAuxSensorSubnodeInfo(const xmlNode* cur,
354     std::vector<std::string>& auxSensorList, const uint32_t i)
355 {
356     std::vector<AuxLevelItem> auxItems;
357     for (auto subNode = cur->children; subNode != nullptr; subNode = subNode->next) {
358         if (subNode == nullptr) {
359             continue;
360         }
361         std::string tempRanges;
362         AuxLevelItem auxlevelItem;
363         if (ParseAuxSensorSubnodeInfoTrigerRange(subNode, auxSensorList, tempRanges, i) == false) {
364             break;
365         }
366 
367         std::vector<std::string> tempRiseRanges;
368         StringOperation::SplitString(tempRanges, tempRiseRanges, "_");
369         auxlevelItem.lowerTemp = atoi(tempRiseRanges[0].c_str());
370         auxlevelItem.upperTemp = atoi(tempRiseRanges[1].c_str());
371         xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
372         if (xmlLevel != nullptr) {
373             auxlevelItem.level = atoi((char *)xmlLevel);
374             xmlFree(xmlLevel);
375         }
376         THERMAL_HILOGD(LABEL_TEST, "aux_trigger_range: %{public}s",
377             tempRanges.c_str());
378         THERMAL_HILOGD(LABEL_TEST, "lowerTemp: %{public}d, upperTemp: %{public}d",
379             auxlevelItem.lowerTemp, auxlevelItem.upperTemp);
380         auxItems.push_back(auxlevelItem);
381     }
382     return auxItems;
383 }
384 
ParseAuxSensorSubnodeInfoTrigerRange(const xmlNode * subNode,std::vector<std::string> & auxSensorList,std::string & tempRanges,const uint32_t i)385 bool ThermalConfigFileParser::ParseAuxSensorSubnodeInfoTrigerRange(const xmlNode* subNode,
386     std::vector<std::string>& auxSensorList, std::string& tempRanges, const uint32_t i)
387 {
388     xmlChar* xmlTriggerRange = xmlGetProp(subNode, BAD_CAST("aux_trigger_range"));
389     if (xmlTriggerRange != nullptr) {
390         std::string auxTriggerRange = (char *)xmlTriggerRange;
391         if (!auxTriggerRange.empty()) {
392             std::vector<std::string> auxTempranges;
393             StringOperation::SplitString(auxTriggerRange, auxTempranges, ",");
394             if (auxSensorList.size() > auxTempranges.size()) {
395                 THERMAL_HILOGI(LABEL_TEST, "The auxiliary sensor does not match the threshold range");
396                 xmlFree(xmlTriggerRange);
397                 return false;
398             }
399             tempRanges = auxTempranges[i];
400         }
401         xmlFree(xmlTriggerRange);
402     }
403     return true;
404 }
405 
ParseSensorSubnodeInfo(const xmlNode * cur,std::vector<LevelItem> & vItem,std::vector<std::string> & sensors,const uint32_t i,std::shared_ptr<ThermalConfigSensorCluster> & sc)406 void ThermalConfigFileParser::ParseSensorSubnodeInfo(const xmlNode* cur, std::vector<LevelItem>& vItem,
407     std::vector<std::string>& sensors, const uint32_t i, std::shared_ptr<ThermalConfigSensorCluster>& sc)
408 {
409     for (auto subNode = cur->children; subNode; subNode = subNode->next) {
410         if (subNode == nullptr) {
411             continue;
412         }
413         LevelItem levelItem;
414         std::vector<std::string> thresholds;
415         std::vector<std::string> thresholdClrs;
416         std::vector<std::string> rates;
417         xmlChar* xmlThreshold = xmlGetProp(subNode, BAD_CAST("threshold"));
418         if (xmlThreshold != nullptr) {
419             StringOperation::SplitString((char *)xmlThreshold, thresholds, ",");
420             xmlFree(xmlThreshold);
421         }
422         xmlChar* xmlThresholdClr = xmlGetProp(subNode, BAD_CAST("threshold_clr"));
423         if (xmlThresholdClr != nullptr) {
424             StringOperation::SplitString((char *)xmlThresholdClr, thresholdClrs, ",");
425             xmlFree(xmlThresholdClr);
426         }
427         if (sensors.size() > thresholds.size() || sensors.size() > thresholdClrs.size()) {
428             THERMAL_HILOGI(LABEL_TEST, "The sensor does not match the threshold range");
429             break;
430         }
431         xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
432         if (xmlLevel != nullptr) {
433             levelItem.level = static_cast<uint32_t>(atoi(((char *)xmlLevel)));
434             xmlFree(xmlLevel);
435         }
436 
437         levelItem.threshold = atoi(thresholds.at(i).c_str());
438         levelItem.thresholdClr = atoi(thresholdClrs.at(i).c_str());
439         xmlChar* tempRiseRates = xmlGetProp(subNode, BAD_CAST("temp_rise_rate"));
440         if (tempRiseRates != nullptr) {
441             sc->SetRateFlag(true);
442             StringOperation::SplitString((char *)tempRiseRates, rates, ",");
443             if (sensors.size() > rates.size()) {
444                 break;
445             }
446             levelItem.tempRiseRate = atof(rates.at(i).c_str());
447         }
448         vItem.push_back(levelItem);
449         xmlFree(tempRiseRates);
450     }
451 }
452 
ParsePolicySubnode(const xmlNode * cur,PolicyConfig & policyConfig)453 void ThermalConfigFileParser::ParsePolicySubnode(const xmlNode* cur, PolicyConfig& policyConfig)
454 {
455     for (auto subNode = cur->children; subNode != nullptr; subNode = subNode->next) {
456         if (subNode == nullptr) {
457             continue;
458         }
459         PolicyAction policyAction;
460         policyAction.actionName = (char *)subNode->name;
461         xmlChar* xmlActionValue = xmlNodeGetContent(subNode);
462         if (xmlActionValue != nullptr) {
463             policyAction.actionValue = (char *)xmlActionValue;
464             THERMAL_HILOGD(LABEL_TEST,
465                 "policyAction.actionNodeName: %{public}s, policyAction.value:%{public}s",
466                 policyAction.actionName.c_str(), policyAction.actionValue.c_str());
467             xmlFree(xmlActionValue);
468         }
469 
470         if (subNode->properties == nullptr) {
471             THERMAL_HILOGD(LABEL_TEST, "action prop is nullptr");
472             policyAction.isProp = false;
473             policyConfig.vPolicyAction.push_back(policyAction);
474             continue;
475         }
476         for (auto actionProp = subNode->properties; actionProp != nullptr; actionProp = actionProp->next) {
477             std::string propName = (char *)actionProp->name;
478             xmlChar* xmlPropValue = xmlGetProp(subNode, actionProp->name);
479             if (xmlPropValue != nullptr) {
480                 std::string propValue = (char *)xmlPropValue;
481                 THERMAL_HILOGD(LABEL_TEST, "propName.name: %{public}s, propValue:%{public}s",
482                     propName.c_str(), propValue.c_str());
483                 policyAction.mActionProp.emplace(std::pair(propName, propValue));
484                 xmlFree(xmlPropValue);
485             }
486             policyAction.isProp = true;
487         }
488         policyConfig.vPolicyAction.push_back(policyAction);
489     }
490 }
491 } // namespace PowerMgr
492 } // namespace OHOS
493