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_kernel_config_file.h"
17 #include "thermal_common.h"
18 #include "thermal_kernel_service.h"
19 #include "string_ex.h"
20 #include "string_operation.h"
21 
22 namespace OHOS {
23 namespace PowerMgr {
24 namespace {
25 auto &service = ThermalKernelService::GetInstance();
26 std::vector<LevelAction> g_levelActionList;
27 const std::string DESCENDING_ORDER = "1";
28 }
Init(const std::string & path)29 bool ThermalKernelConfigFile::Init(const std::string &path)
30 {
31     THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
32     bool ret = false;
33     if (!baseInfo_) {
34         baseInfo_ = std::make_unique<ProtectorBaseInfo>();
35     }
36 
37     ret = ParseThermalKernelXML(path);
38     return ret;
39 }
40 
ParseThermalKernelXML(const std::string & path)41 bool ThermalKernelConfigFile::ParseThermalKernelXML(const std::string &path)
42 {
43     THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
44 
45     std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
46         xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
47     if (docPtr == nullptr) {
48         THERMAL_HILOGE(FEATURE_PROTECTOR, "Init failed, read file failed.");
49         return false;
50     }
51 
52     auto rootNode = xmlDocGetRootElement(docPtr.get());
53     if (rootNode == nullptr) {
54         THERMAL_HILOGE(FEATURE_PROTECTOR, "Get root node failed.");
55         return false;
56     }
57 
58     for (auto node = rootNode->children; node; node = node->next) {
59         if (node == nullptr) continue;
60         if (!xmlStrcmp(node->name, BAD_CAST"base")) {
61             ParserBaseNode(node);
62         } else if (!xmlStrcmp(node->name, BAD_CAST"control")) {
63             ParseControlNode(node);
64         }
65     }
66     return true;
67 }
68 
ParserBaseNode(xmlNodePtr node)69 void ThermalKernelConfigFile::ParserBaseNode(xmlNodePtr node)
70 {
71     auto cur = node->xmlChildrenNode;
72     std::vector<BaseItem> vBase;
73     while (cur != nullptr) {
74         BaseItem baseItem;
75         xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag");
76         xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value");
77         if (xmlTag != nullptr) {
78             baseItem.tag = reinterpret_cast<char*>(xmlTag);
79             xmlFree(xmlTag);
80         }
81         if (xmlValue != nullptr) {
82             baseItem.value = reinterpret_cast<char*>(xmlValue);
83             xmlFree(xmlValue);
84         }
85         vBase.push_back(baseItem);
86         cur = cur->next;
87     }
88     baseInfo_->SetBaseItem(vBase);
89 }
90 
ParseControlNode(xmlNodePtr node)91 void ThermalKernelConfigFile::ParseControlNode(xmlNodePtr node)
92 {
93     auto cur = node->xmlChildrenNode;
94     ThermalKernelPolicy::ThermalZoneMap tzInfoMap;
95     while (cur != nullptr) {
96         LevelAction levelAction;
97         std::string type;
98         std::shared_ptr<ProtectorThermalZoneInfo> tzinfo = std::make_shared<ProtectorThermalZoneInfo>();
99         xmlChar* xmlType = xmlGetProp(cur, BAD_CAST"type");
100         if (xmlType != nullptr) {
101             type = reinterpret_cast<char*>(xmlType);
102             xmlFree(xmlType);
103         }
104         xmlChar* xmlInterval = xmlGetProp(cur, BAD_CAST"interval");
105         if (xmlInterval != nullptr) {
106             int32_t interval = 0;
107             StrToInt(reinterpret_cast<char*>(xmlInterval), interval);
108             tzinfo->SetInterval(interval);
109             xmlFree(xmlInterval);
110         }
111 
112         xmlChar* desc = xmlGetProp(cur, BAD_CAST"desc");
113         if (desc != nullptr) {
114             std::string value = reinterpret_cast<char*>(desc);
115             if (TrimStr(value) == DESCENDING_ORDER) {
116                 tzinfo->SetDesc(true);
117             }
118             xmlFree(desc);
119         }
120 
121         std::vector<ThermalZoneInfoItem> tzItemList;
122         ParseSubNode(cur, tzItemList, type);
123 
124         tzinfo->SetThermalZoneItem(tzItemList);
125         tzInfoMap.emplace(std::pair(type, tzinfo));
126         cur = cur->next;
127     }
128     service.GetPolicy()->SetThermalZoneMap(tzInfoMap);
129     service.GetPolicy()->SetLevelAction(g_levelActionList);
130 }
131 
ParseSubNode(xmlNodePtr cur,std::vector<ThermalZoneInfoItem> & tzItemList,std::string & type)132 void ThermalKernelConfigFile::ParseSubNode(xmlNodePtr cur, std::vector<ThermalZoneInfoItem>& tzItemList,
133     std::string& type)
134 {
135     THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
136     LevelAction levelAction;
137     levelAction.name = type;
138 
139     for (auto subNode = cur->children; subNode; subNode = subNode->next) {
140         if (subNode == nullptr) {
141             continue;
142         }
143         if (xmlStrcmp(subNode->name, BAD_CAST"item") != 0) {
144             continue;
145         }
146 
147         ThermalZoneInfoItem tziItem;
148         xmlChar* xmlThreshold = xmlGetProp(subNode, BAD_CAST"threshold");
149         if (xmlThreshold != nullptr) {
150             StrToInt(reinterpret_cast<char*>(xmlThreshold), tziItem.threshold);
151             xmlFree(xmlThreshold);
152         }
153         xmlChar* xmlThresholdClr = xmlGetProp(subNode, BAD_CAST"threshold_clr");
154         if (xmlThresholdClr != nullptr) {
155             StrToInt(reinterpret_cast<char*>(xmlThresholdClr), tziItem.thresholdClr);
156             xmlFree(xmlThresholdClr);
157         }
158         xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST"level");
159         if (xmlLevel != nullptr) {
160             StringOperation::StrToUint(reinterpret_cast<char*>(xmlLevel), tziItem.level);
161             levelAction.level = tziItem.level;
162             xmlFree(xmlLevel);
163         }
164         for (auto subActionNode = subNode->children; subActionNode; subActionNode = subActionNode->next) {
165             ActionItem action;
166             action.name = reinterpret_cast<const char*>(subActionNode->name);
167             xmlChar* xmlValue = xmlNodeGetContent(subActionNode);
168             if (xmlValue != nullptr) {
169                 StringOperation::StrToUint(reinterpret_cast<char*>(xmlValue), action.value);
170                 xmlFree(xmlValue);
171             }
172             levelAction.vAction.push_back(action);
173         }
174         tzItemList.push_back(tziItem);
175         g_levelActionList.push_back(levelAction);
176     }
177 }
178 } // namespace PowerMgr
179 } // namespace OHOS
180