• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "xml_parser.h"
16 #include <algorithm>
17 
18 namespace OHOS::Rosen {
LoadConfiguration()19 int32_t XMLParser::LoadConfiguration()
20 {
21     if (!xmlDocument_) {
22         HGM_LOGI("XMLParser opening xml file");
23         xmlDocument_ = xmlReadFile(CONFIG_FILE, nullptr, 0);
24     }
25 
26     if (!xmlDocument_) {
27         HGM_LOGE("XMLParser xmlReadFile failed");
28         return XML_FILE_LOAD_FAIL;
29     }
30 
31     if (!mParsedData_) {
32         HGM_LOGI("XMLParser initializing parsed data");
33         mParsedData_ = std::make_unique<ParsedConfigData>();
34     }
35     return EXEC_SUCCESS;
36 }
37 
Parse()38 int32_t XMLParser::Parse()
39 {
40     HGM_LOGD("XMLParser Parse");
41     if (!xmlDocument_) {
42         HGM_LOGE("XMLParser xmlDocument_ is empty, should do LoadConfiguration first");
43         return HGM_ERROR;
44     }
45     xmlNode *root = xmlDocGetRootElement(xmlDocument_);
46     if (root == nullptr) {
47         HGM_LOGE("XMLParser xmlDocGetRootElement failed");
48         return XML_GET_ROOT_FAIL;
49     }
50 
51     if (ParseInternal(*root) == false) {
52         return XML_PARSE_INTERNAL_FAIL;
53     }
54     return EXEC_SUCCESS;
55 }
56 
Destroy()57 void XMLParser::Destroy()
58 {
59     HGM_LOGD("XMLParser Destroying the parser");
60     if (xmlDocument_ != nullptr) {
61         xmlFreeDoc(xmlDocument_);
62         xmlDocument_ = nullptr;
63     }
64 }
65 
GetHgmXmlNodeAsInt(xmlNode & node) const66 int32_t XMLParser::GetHgmXmlNodeAsInt(xmlNode &node) const
67 {
68     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Param"))) {
69         return HGM_XML_PARAM;
70     }
71     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Params"))) {
72         return HGM_XML_PARAMS;
73     }
74     HGM_LOGD("XMLParser failed to identify a xml node : %{public}s", node.name);
75     return HGM_XML_UNDEFINED;
76 }
77 
ParseInternal(xmlNode & node)78 bool XMLParser::ParseInternal(xmlNode &node)
79 {
80     HGM_LOGD("XMLParser parsing an internal node");
81     xmlNode *currNode = &node;
82     if (currNode->xmlChildrenNode == nullptr) {
83         HGM_LOGD("XMLParser stop parsing internal, no children nodes");
84         return false;
85     }
86     currNode = currNode->xmlChildrenNode;
87     int32_t parseSuccess = EXEC_SUCCESS;
88 
89     for (; currNode; currNode = currNode->next) {
90         if (currNode->type != XML_ELEMENT_NODE) {
91             continue;
92         }
93         if (parseSuccess != EXEC_SUCCESS) {
94             return false;
95         }
96 
97         if (GetHgmXmlNodeAsInt(*currNode) == HGM_XML_PARAM) {
98             parseSuccess = ParseParam(*currNode);
99         } else if (GetHgmXmlNodeAsInt(*currNode) == HGM_XML_PARAMS) {
100             parseSuccess = ParseParams(*currNode);
101         }
102     }
103     return true;
104 }
105 
ParseParam(xmlNode & node)106 int32_t XMLParser::ParseParam(xmlNode &node)
107 {
108     HGM_LOGI("XMLParser parsing a parameter");
109     if (!mParsedData_) {
110         HGM_LOGE("XMLParser mParsedData_ is not initialized");
111         return HGM_ERROR;
112     }
113 
114     std::string paraName = ExtractPropertyValue("name", node);
115     if (paraName == "default_refreshrate_mode") {
116         HGM_LOGD("XMLParser parsing default_refreshrate_mode");
117         std::string mode = ExtractPropertyValue("value", node);
118         mParsedData_->defaultRefreshRateMode_ = mode;
119     }
120 
121     if (paraName == "general_config_enable") {
122         HGM_LOGD("XMLParser parsing general_config_enable");
123         std::string parsed = ExtractPropertyValue("value", node);
124         mParsedData_->isDynamicFrameRateEnable_ = parsed;
125     }
126 
127     HGM_LOGD("XMLParser parsing general_config_enable finish: %{public}s",
128         mParsedData_->isDynamicFrameRateEnable_.c_str());
129     return EXEC_SUCCESS;
130 }
131 
ParseParams(xmlNode & node)132 int32_t XMLParser::ParseParams(xmlNode &node)
133 {
134     std::string paraName = ExtractPropertyValue("name", node);
135     if (paraName.empty()) {
136         HGM_LOGD("XMLParser No name provided for %{public}s", node.name);
137         return XML_PARSE_INTERNAL_FAIL;
138     }
139     if (!mParsedData_) {
140         HGM_LOGE("XMLParser mParsedData_ is not initialized");
141         return HGM_ERROR;
142     }
143 
144     if (paraName == "detailed_strategies") {
145         if (ParseStrat(node) != EXEC_SUCCESS) {
146             HGM_LOGD("XMLParser failed to parse detailed_strategies");
147         }
148         return EXEC_SUCCESS;
149     }
150 
151     if (paraName == "customer_setting_config") {
152         if (ParseSetting(node, mParsedData_->customerSettingConfig_) != EXEC_SUCCESS) {
153             HGM_LOGD("XMLParser failed to parse customer_setting_config");
154         }
155         return EXEC_SUCCESS;
156     }
157 
158     if (paraName == "bundle_name_black_list") {
159         if (ParseSetting(node, mParsedData_->bundle_black_list_) != EXEC_SUCCESS) {
160             HGM_LOGD("XMLParser failed to parse bundle_black_list_");
161         }
162         return EXEC_SUCCESS;
163     }
164 
165     if (paraName == "bundle_name_white_list") {
166         if (ParseSetting(node, mParsedData_->bundle_white_list_) != EXEC_SUCCESS) {
167             HGM_LOGD("XMLParser failed to parse bundle_white_list_");
168         }
169         return EXEC_SUCCESS;
170     }
171 
172     if (paraName == "animation_dynamic_settings") {
173         if (ParseSetting(node, mParsedData_->animationDynamicStrats_) != EXEC_SUCCESS) {
174             HGM_LOGD("XMLParser failed to parse animation_dynamic_settings");
175         }
176         return EXEC_SUCCESS;
177     }
178 
179     if (paraName == "property_animation_dynamic_settings") {
180         if (ParserAnimationDynamicSetting(node) != EXEC_SUCCESS) {
181             HGM_LOGD("XMLParser failed to parse property_animation_dynamic_settings");
182         }
183         return EXEC_SUCCESS;
184     }
185 
186     HGM_LOGD("XMLParser parsing params finish");
187     return XML_PARSE_INTERNAL_FAIL;
188 }
189 
ParseStrat(xmlNode & node)190 int32_t XMLParser::ParseStrat(xmlNode &node)
191 {
192     xmlNode *currNode = &node;
193     if (currNode->xmlChildrenNode == nullptr) {
194         HGM_LOGD("XMLParser stop parsing strats, no children nodes");
195         return HGM_ERROR;
196     }
197     if (!mParsedData_) {
198         HGM_LOGE("XMLParser mParsedData_ is not initialized");
199         return HGM_ERROR;
200     }
201 
202     currNode = currNode->xmlChildrenNode;
203     for (; currNode; currNode = currNode->next) {
204         if (currNode->type != XML_ELEMENT_NODE) {
205             continue;
206         }
207 
208         ParsedConfigData::detailedStrat strat;
209         strat.name = ExtractPropertyValue("name", *currNode);
210         strat.isDynamic = ExtractPropertyValue("isDynamic", *currNode);
211         strat.min = ExtractPropertyValue("min", *currNode);
212         strat.max = ExtractPropertyValue("max", *currNode);
213         mParsedData_->detailedStrategies_[strat.name] = strat;
214     }
215 
216     return EXEC_SUCCESS;
217 }
218 
ParseSetting(xmlNode & node,std::unordered_map<std::string,std::string> & config)219 int32_t XMLParser::ParseSetting(xmlNode &node, std::unordered_map<std::string, std::string> &config)
220 {
221     HGM_LOGD("XMLParser parsing strats");
222     xmlNode *currNode = &node;
223     if (currNode->xmlChildrenNode == nullptr) {
224         HGM_LOGD("XMLParser stop parsing settings, no children nodes");
225         return HGM_ERROR;
226     }
227     currNode = currNode->xmlChildrenNode;
228 
229     for (; currNode; currNode = currNode->next) {
230         if (currNode->type != XML_ELEMENT_NODE) {
231             continue;
232         }
233 
234         std::string name = "";
235         std::string value = "";
236         name = ExtractPropertyValue("name", *currNode);
237         value = ExtractPropertyValue("value", *currNode);
238         if (name.empty() || value.empty()) {
239             return XML_PARSE_INTERNAL_FAIL;
240         }
241         config[name] = value;
242     }
243 
244     return EXEC_SUCCESS;
245 }
246 
ParserAnimationDynamicSetting(xmlNode & node)247 int32_t XMLParser::ParserAnimationDynamicSetting(xmlNode &node)
248 {
249     xmlNode *currNode = &node;
250     if (currNode->xmlChildrenNode == nullptr) {
251         return HGM_ERROR;
252     }
253     currNode = currNode->xmlChildrenNode;
254     for (; currNode; currNode = currNode->next) {
255         auto dynamicSettingType = ExtractPropertyValue("name", *currNode);
256         if (mParsedData_->dynamicSetting_.find(dynamicSettingType) == mParsedData_->dynamicSetting_.end()) {
257             continue;
258         }
259         for (xmlNode *thresholdNode = currNode->xmlChildrenNode; thresholdNode; thresholdNode = thresholdNode->next) {
260             if (thresholdNode->type != XML_ELEMENT_NODE) {
261                 continue;
262             }
263             auto name = ExtractPropertyValue("name", *thresholdNode);
264             auto min = ExtractPropertyValue("min", *thresholdNode);
265             auto max = ExtractPropertyValue("max", *thresholdNode);
266             auto preferred_fps = ExtractPropertyValue("preferred_fps", *thresholdNode);
267             if (!IsNumber(min) || !IsNumber(max) || !IsNumber(preferred_fps)) {
268                 mParsedData_->dynamicSetting_[dynamicSettingType].clear();
269                 break;
270             }
271             ParsedConfigData::AnimationDynamicSetting animationDynamicSetting;
272             animationDynamicSetting.min = std::stoi(ExtractPropertyValue("min", *thresholdNode));
273             animationDynamicSetting.max = std::stoi(ExtractPropertyValue("max", *thresholdNode));
274             animationDynamicSetting.preferred_fps = std::stoi(ExtractPropertyValue("preferred_fps", *thresholdNode));
275             mParsedData_->dynamicSetting_[dynamicSettingType][name] = animationDynamicSetting;
276         }
277     }
278     return EXEC_SUCCESS;
279 }
280 
ExtractPropertyValue(const std::string & propName,xmlNode & node)281 std::string XMLParser::ExtractPropertyValue(const std::string &propName, xmlNode &node)
282 {
283     HGM_LOGD("XMLParser extracting value : %{public}s", propName.c_str());
284     std::string propValue = "";
285     xmlChar *tempValue = nullptr;
286 
287     if (xmlHasProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
288         tempValue = xmlGetProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()));
289     }
290 
291     if (tempValue != nullptr) {
292         HGM_LOGD("XMLParser not aempty tempValue");
293         propValue = reinterpret_cast<const char*>(tempValue);
294         xmlFree(tempValue);
295         tempValue = nullptr;
296     }
297 
298     return propValue;
299 }
300 
IsNumber(const std::string & str)301 bool XMLParser::IsNumber(const std::string &str)
302 {
303     if (str.length() == 0) {
304         return false;
305     }
306     auto number = static_cast<uint32_t>(std::count_if(str.begin(), str.end(), [](unsigned char c) {
307         return std::isdigit(c);
308     }));
309     return number == str.length() || (str.compare(0, 1, "-") == 0 && number == str.length() - 1);
310 }
311 
312 } // namespace OHOS::Rosen