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