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 #include "config_policy_utils.h"
19
20 namespace OHOS::Rosen {
21 namespace {
22 constexpr uint32_t FPS_MAX = 120; // for hgm_idle_detector: default max fps of third framework
23 constexpr uint32_t XML_STRING_MAX_LENGTH = 8;
24 }
25
LoadConfiguration(const char * fileDir)26 int32_t XMLParser::LoadConfiguration(const char* fileDir)
27 {
28 HGM_LOGI("XMLParser opening xml file");
29 xmlDocument_ = xmlReadFile(fileDir, nullptr, 0);
30 if (!xmlDocument_) {
31 HGM_LOGE("XMLParser xmlReadFile failed");
32 return XML_FILE_LOAD_FAIL;
33 }
34
35 if (!mParsedData_) {
36 mParsedData_ = std::make_unique<PolicyConfigData>();
37 }
38
39 return EXEC_SUCCESS;
40 }
41
Parse()42 int32_t XMLParser::Parse()
43 {
44 HGM_LOGD("XMLParser Parse");
45 if (!xmlDocument_) {
46 HGM_LOGE("XMLParser xmlDocument_ is empty, should do LoadConfiguration first");
47 return HGM_ERROR;
48 }
49 xmlNode *root = xmlDocGetRootElement(xmlDocument_);
50 if (root == nullptr) {
51 HGM_LOGE("XMLParser xmlDocGetRootElement failed");
52 return XML_GET_ROOT_FAIL;
53 }
54
55 if (ParseInternal(*root) == false) {
56 return XML_PARSE_INTERNAL_FAIL;
57 }
58 return EXEC_SUCCESS;
59 }
60
Destroy()61 void XMLParser::Destroy()
62 {
63 HGM_LOGD("XMLParser Destroying the parser");
64 if (xmlDocument_ != nullptr) {
65 xmlFreeDoc(xmlDocument_);
66 xmlDocument_ = nullptr;
67 }
68 }
69
GetHgmXmlNodeAsInt(xmlNode & node)70 int32_t XMLParser::GetHgmXmlNodeAsInt(xmlNode& node)
71 {
72 if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Param"))) {
73 return HGM_XML_PARAM;
74 }
75 if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Params"))) {
76 return HGM_XML_PARAMS;
77 }
78 HGM_LOGD("XMLParser failed to identify a xml node : %{public}s", node.name);
79 return HGM_XML_UNDEFINED;
80 }
81
ParseInternal(xmlNode & node)82 bool XMLParser::ParseInternal(xmlNode& node)
83 {
84 HGM_LOGD("XMLParser parsing an internal node");
85 xmlNode *currNode = &node;
86 if (currNode->xmlChildrenNode == nullptr) {
87 HGM_LOGD("XMLParser stop parsing internal, no children nodes");
88 return false;
89 }
90 currNode = currNode->xmlChildrenNode;
91 int32_t parseSuccess = EXEC_SUCCESS;
92
93 for (; currNode; currNode = currNode->next) {
94 if (currNode->type != XML_ELEMENT_NODE) {
95 continue;
96 }
97 if (parseSuccess != EXEC_SUCCESS) {
98 return false;
99 }
100 int xmlParamType = GetHgmXmlNodeAsInt(*currNode);
101 if (xmlParamType == HGM_XML_PARAM) {
102 parseSuccess = ParseParam(*currNode);
103 } else if (xmlParamType == HGM_XML_PARAMS) {
104 parseSuccess = ParseParams(*currNode);
105 }
106 }
107 return true;
108 }
109
ParseParam(xmlNode & node)110 int32_t XMLParser::ParseParam(xmlNode& node)
111 {
112 HGM_LOGI("XMLParser parsing a parameter");
113 if (!mParsedData_) {
114 HGM_LOGE("XMLParser mParsedData_ is not initialized");
115 return HGM_ERROR;
116 }
117
118 std::string paraName = ExtractPropertyValue("name", node);
119 if (paraName == "default_refreshrate_mode") {
120 HGM_LOGD("XMLParser parsing default_refreshrate_mode");
121 std::string mode = ExtractPropertyValue("value", node);
122 mParsedData_->defaultRefreshRateMode_ = mode;
123
124 HGM_LOGI("HgmXMLParser ParseParam default_refreshrate_mode %{public}s",
125 mParsedData_->defaultRefreshRateMode_.c_str());
126 }
127
128 return EXEC_SUCCESS;
129 }
130
ParseSubSequentParams(xmlNode & node,std::string & paraName)131 int32_t XMLParser::ParseSubSequentParams(xmlNode& node, std::string& paraName)
132 {
133 int32_t setResult = EXEC_SUCCESS;
134
135 if (paraName == "additional_touch_rate_config") {
136 ParseAppBufferList(node);
137 } else if (paraName == "refreshRate_strategy_config") {
138 setResult = ParseStrategyConfig(node);
139 } else if (paraName == "refreshRate_virtual_display_config") {
140 if (ExtractPropertyValue("switch", node) == "1") {
141 setResult = ParseSimplex(node, mParsedData_->virtualDisplayConfigs_, "strategy");
142 mParsedData_->virtualDisplaySwitch_ = true;
143 } else {
144 mParsedData_->virtualDisplayConfigs_.clear();
145 mParsedData_->virtualDisplaySwitch_ = false;
146 }
147 } else if (paraName == "safe_vote") {
148 // "1": enable
149 mParsedData_->safeVoteEnabled = ExtractPropertyValue("switch", node) == "1";
150 } else if (paraName == "screen_strategy_config") {
151 setResult = ParseSimplex(node, mParsedData_->screenStrategyConfigs_, "type");
152 } else if (paraName == "screen_config") {
153 setResult = ParseScreenConfig(node);
154 } else if (paraName == "rs_video_frame_rate_vote_config") {
155 setResult = ParseVideoFrameVoteConfig(node);
156 } else if (paraName == "source_tuning_for_yuv420") {
157 setResult = ParseSimplex(node, mParsedData_->sourceTuningConfig_);
158 } else if (paraName == "rs_solid_color_layer_config") {
159 setResult = ParseSimplex(node, mParsedData_->solidLayerConfig_);
160 } else if (paraName == "video_call_layer_config") {
161 setResult = ParseSimplex(node, mParsedData_->videoCallLayerConfig_);
162 } else {
163 setResult = EXEC_SUCCESS;
164 }
165
166 return setResult;
167 }
168
ParseParams(xmlNode & node)169 int32_t XMLParser::ParseParams(xmlNode& node)
170 {
171 std::string paraName = ExtractPropertyValue("name", node);
172 if (paraName.empty()) {
173 return XML_PARSE_INTERNAL_FAIL;
174 }
175 if (!mParsedData_) {
176 HGM_LOGE("XMLParser mParsedData_ is not initialized");
177 return HGM_ERROR;
178 }
179
180 int32_t setResult = EXEC_SUCCESS;
181 if (paraName == "refresh_rate_4settings") {
182 std::unordered_map<std::string, std::string> refreshRateForSettings;
183 setResult = ParseSimplex(node, refreshRateForSettings);
184 if (setResult != EXEC_SUCCESS) {
185 mParsedData_->xmlCompatibleMode_ = true;
186 setResult = ParseSimplex(node, refreshRateForSettings, "id");
187 }
188 mParsedData_->refreshRateForSettings_.clear();
189 for (auto &[name, id]: refreshRateForSettings) {
190 if (IsNumber(name) && IsNumber(id)) {
191 mParsedData_->refreshRateForSettings_.emplace_back(
192 std::pair<int32_t, int32_t>(std::stoi(name), std::stoi(id)));
193 }
194 }
195 std::sort(mParsedData_->refreshRateForSettings_.begin(), mParsedData_->refreshRateForSettings_.end(),
196 [=] (auto rateId0, auto rateId1) { return rateId0.first < rateId1.first; });
197 } else {
198 setResult = ParseSubSequentParams(node, paraName);
199 }
200
201 if (setResult != EXEC_SUCCESS) {
202 HGM_LOGI("XMLParser failed to ParseParams %{public}s", paraName.c_str());
203 }
204 return EXEC_SUCCESS;
205 }
206
ParseVideoFrameVoteConfig(xmlNode & node)207 int32_t XMLParser::ParseVideoFrameVoteConfig(xmlNode& node)
208 {
209 mParsedData_->videoFrameRateVoteSwitch_ = ExtractPropertyValue("switch", node) == "1";
210 return ParseSimplex(node, mParsedData_->videoFrameRateList_);
211 }
212
ParseStrategyConfig(xmlNode & node)213 int32_t XMLParser::ParseStrategyConfig(xmlNode& node)
214 {
215 HGM_LOGD("XMLParser parsing strategyConfig");
216 xmlNode *currNode = &node;
217 if (currNode->xmlChildrenNode == nullptr) {
218 HGM_LOGD("XMLParser stop parsing strategyConfig, no children nodes");
219 return HGM_ERROR;
220 }
221
222 // re-parse
223 mParsedData_->strategyConfigs_.clear();
224 currNode = currNode->xmlChildrenNode;
225 for (; currNode; currNode = currNode->next) {
226 if (currNode->type != XML_ELEMENT_NODE) {
227 continue;
228 }
229
230 auto name = ExtractPropertyValue("name", *currNode);
231 auto min = ExtractPropertyValue("min", *currNode);
232 auto max = ExtractPropertyValue("max", *currNode);
233 auto dynamicMode = ExtractPropertyValue("dynamicMode", *currNode);
234 auto pointerMode = ExtractPropertyValue("pointerMode", *currNode);
235 auto idleFps = ExtractPropertyValue("idleFps", *currNode);
236 auto isFactor = ExtractPropertyValue("isFactor", *currNode) == "1"; // 1:true, other:false
237 auto drawMin = ExtractPropertyValue("drawMin", *currNode);
238 auto drawMax = ExtractPropertyValue("drawMax", *currNode);
239 auto down = ExtractPropertyValue("down", *currNode);
240 auto supportAS = ExtractPropertyValue("supportAS", *currNode);
241 if (!IsNumber(min) || !IsNumber(max) || !IsNumber(dynamicMode)) {
242 return HGM_ERROR;
243 }
244
245 PolicyConfigData::StrategyConfig strategy;
246 strategy.min = std::stoi(min);
247 strategy.max = std::stoi(max);
248 strategy.dynamicMode = static_cast<DynamicModeType>(std::stoi(dynamicMode));
249 strategy.pointerMode = IsNumber(pointerMode) ?
250 static_cast<PointerModeType>(std::stoi(pointerMode)) :
251 PointerModeType::POINTER_DISENABLED;
252 strategy.idleFps = IsNumber(idleFps) ?
253 std::clamp(std::stoi(idleFps), strategy.min, strategy.max) :
254 std::max(strategy.min, static_cast<int32_t>(OLED_60_HZ));
255 strategy.isFactor = isFactor;
256 strategy.drawMin = IsNumber(drawMin) ? std::stoi(drawMin) : 0;
257 strategy.drawMax = IsNumber(drawMax) ? std::stoi(drawMax) : 0;
258 strategy.down = IsNumber(down) ? std::stoi(down) : strategy.max;
259 strategy.supportAS = IsNumber(supportAS) ? std::stoi(supportAS) : 0;
260 ParseBufferStrategyList(*currNode, strategy);
261 mParsedData_->strategyConfigs_[name] = strategy;
262 HGM_LOGI("HgmXMLParser ParseStrategyConfig name=%{public}s min=%{public}d drawMin=%{public}d",
263 name.c_str(), mParsedData_->strategyConfigs_[name].min, mParsedData_->strategyConfigs_[name].drawMin);
264 }
265
266 return EXEC_SUCCESS;
267 }
268
ParseAppBufferList(xmlNode & node)269 void XMLParser::ParseAppBufferList(xmlNode& node)
270 {
271 HGM_LOGD("XMLParser parsing ParseAppBufferList");
272 xmlNode *currNode = &node;
273 if (currNode->xmlChildrenNode == nullptr) {
274 HGM_LOGD("XMLParser stop parsing ParseAppBufferList, no children nodes");
275 return;
276 }
277
278 mParsedData_->appBufferList_.clear();
279 currNode = currNode->xmlChildrenNode;
280 for (; currNode; currNode = currNode->next) {
281 if (currNode->type != XML_ELEMENT_NODE) {
282 continue;
283 }
284 auto name = ExtractPropertyValue("name", *currNode);
285 mParsedData_->appBufferList_.push_back(name);
286 }
287 }
288
ParseBufferStrategyList(xmlNode & node,PolicyConfigData::StrategyConfig & strategy)289 void XMLParser::ParseBufferStrategyList(xmlNode& node, PolicyConfigData::StrategyConfig& strategy)
290 {
291 if (mParsedData_->appBufferList_.empty()) {
292 return;
293 }
294 for (auto& name : mParsedData_->appBufferList_) {
295 auto fpsStr = ExtractPropertyValue(name, node);
296 if (fpsStr == "") {
297 strategy.bufferFpsMap[name] = FPS_MAX;
298 } else if (IsNumber(fpsStr)) {
299 auto fpsNum = std::stoi(fpsStr);
300 if (fpsNum >= 0) {
301 strategy.bufferFpsMap[name] = fpsNum;
302 }
303 }
304 }
305 }
306
ParseScreenConfig(xmlNode & node)307 int32_t XMLParser::ParseScreenConfig(xmlNode& node)
308 {
309 HGM_LOGD("XMLParser parsing screenConfig");
310 xmlNode *currNode = &node;
311 if (currNode->xmlChildrenNode == nullptr) {
312 HGM_LOGD("XMLParser stop parsing screenConfig, no children nodes");
313 return HGM_ERROR;
314 }
315
316 auto type = ExtractPropertyValue("type", *currNode);
317 PolicyConfigData::ScreenConfig screenConfig;
318 currNode = currNode->xmlChildrenNode;
319 for (; currNode; currNode = currNode->next) {
320 if (currNode->type != XML_ELEMENT_NODE) {
321 continue;
322 }
323 auto name = ExtractPropertyValue("name", *currNode);
324 if (name == "supported_mode") {
325 PolicyConfigData::SupportedModeConfig supportedModeConfig;
326 if (ParseSupportedModeConfig(*currNode, supportedModeConfig) != EXEC_SUCCESS) {
327 HGM_LOGI("XMLParser failed to ParseScreenConfig %{public}s", name.c_str());
328 }
329 mParsedData_->supportedModeConfigs_[type] = supportedModeConfig;
330 continue;
331 }
332 PolicyConfigData::ScreenSetting screenSetting;
333 auto id = ExtractPropertyValue("id", *currNode);
334 screenSetting.strategy = ExtractPropertyValue("strategy", *currNode);
335 for (xmlNode *thresholdNode = currNode->xmlChildrenNode; thresholdNode; thresholdNode = thresholdNode->next) {
336 ParseSubScreenConfig(*thresholdNode, screenSetting);
337 }
338 screenConfig[id] = screenSetting;
339 HGM_LOGI("HgmXMLParser ParseScreenConfig id=%{public}s", id.c_str());
340 }
341 if (size_t pos = type.find(HGM_CONFIG_TYPE_THERMAL_SUFFIX); pos != std::string::npos) {
342 auto defaultScreenConfig = mParsedData_->screenConfigs_.find(type.substr(0, pos));
343 if (defaultScreenConfig != mParsedData_->screenConfigs_.end()) {
344 ReplenishMissThermalConfig(defaultScreenConfig->second, screenConfig);
345 } else {
346 HGM_LOGE("XMLParser failed to ReplenishMissThermalConfig %{public}s", type.c_str());
347 return EXEC_SUCCESS;
348 }
349 }
350 mParsedData_->screenConfigs_[type] = screenConfig;
351 return EXEC_SUCCESS;
352 }
353
ParseSubScreenConfig(xmlNode & node,PolicyConfigData::ScreenSetting & screenSetting)354 int32_t XMLParser::ParseSubScreenConfig(xmlNode& node, PolicyConfigData::ScreenSetting& screenSetting)
355 {
356 xmlNode *thresholdNode = &node;
357 if (thresholdNode->type != XML_ELEMENT_NODE) {
358 return HGM_ERROR;
359 }
360 auto name = ExtractPropertyValue("name", *thresholdNode);
361 int32_t setResult = EXEC_SUCCESS;
362 if (name == "LTPO_config") {
363 setResult = ParseSimplex(*thresholdNode, screenSetting.ltpoConfig);
364 } else if (name == "property_animation_dynamic_settings") {
365 setResult = ParseDynamicSetting(*thresholdNode, screenSetting.animationDynamicSettings);
366 } else if (name == "ace_scene_dynamic_settings") {
367 setResult = ParseDynamicSetting(*thresholdNode, screenSetting.aceSceneDynamicSettings);
368 } else if (name == "small_size_property_animation_dynamic_settings") {
369 setResult = ParseSmallSizeDynamicSetting(*thresholdNode, screenSetting);
370 } else if (name == "scene_list") {
371 setResult = ParseSceneList(*thresholdNode, screenSetting.sceneList);
372 } else if (name == "game_scene_list") {
373 setResult = ParseSimplex(*thresholdNode, screenSetting.gameSceneList);
374 } else if (name == "anco_scene_list") {
375 setResult = ParseSceneList(*thresholdNode, screenSetting.ancoSceneList);
376 } else if (name == "app_list") {
377 ParseMultiAppStrategy(*thresholdNode, screenSetting);
378 } else if (name == "app_types") {
379 setResult = ParseAppTypes(*thresholdNode, screenSetting.appTypes);
380 } else if (name == "rs_animation_power_config") {
381 setResult = ParseSimplex(*thresholdNode, screenSetting.animationPowerConfig);
382 } else if (name == "ui_power_config") {
383 setResult = ParseSimplex(*thresholdNode, screenSetting.uiPowerConfig);
384 } else if (name == "component_power_config") {
385 setResult = ParsePowerStrategy(*thresholdNode, screenSetting.componentPowerConfig);
386 } else if (name == "app_page_url_config") {
387 setResult = ParsePageUrlStrategy(*thresholdNode, screenSetting.pageUrlConfig);
388 } else if (name == "performance_config") {
389 setResult = ParsePerformanceConfig(*thresholdNode, screenSetting.performanceConfig);
390 } else {
391 setResult = EXEC_SUCCESS;
392 }
393
394 if (setResult != EXEC_SUCCESS) {
395 HGM_LOGI("XMLParser failed to ParseScreenConfig %{public}s", name.c_str());
396 }
397 return setResult;
398 }
399
ParseSimplex(xmlNode & node,std::unordered_map<std::string,std::string> & config,const std::string & valueName,const std::string & keyName,const bool canBeEmpty)400 int32_t XMLParser::ParseSimplex(xmlNode& node, std::unordered_map<std::string, std::string>& config,
401 const std::string& valueName, const std::string& keyName,
402 const bool canBeEmpty)
403 {
404 HGM_LOGD("XMLParser parsing simplex");
405 xmlNode *currNode = &node;
406 if (currNode->xmlChildrenNode == nullptr) {
407 HGM_LOGD("XMLParser stop parsing simplex, no children nodes");
408 return HGM_ERROR;
409 }
410
411 // re-parse
412 config.clear();
413 currNode = currNode->xmlChildrenNode;
414 for (; currNode; currNode = currNode->next) {
415 if (currNode->type != XML_ELEMENT_NODE) {
416 continue;
417 }
418
419 auto key = ExtractPropertyValue(keyName, *currNode);
420 auto value = ExtractPropertyValue(valueName, *currNode);
421 if (key.empty()) {
422 return XML_PARSE_INTERNAL_FAIL;
423 }
424
425 if (value.empty()) {
426 if (canBeEmpty) {
427 continue;
428 }
429 return XML_PARSE_INTERNAL_FAIL;
430 }
431
432 config[key] = value;
433
434 HGM_LOGI("HgmXMLParser ParseSimplex %{public}s=%{public}s %{public}s=%{public}s",
435 keyName.c_str(), key.c_str(), valueName.c_str(), config[key].c_str());
436 }
437
438 return EXEC_SUCCESS;
439 }
440
ParsePowerStrategy(xmlNode & node,std::unordered_map<std::string,int32_t> & powerConfig)441 int32_t XMLParser::ParsePowerStrategy(xmlNode& node, std::unordered_map<std::string, int32_t>& powerConfig)
442 {
443 std::unordered_map<std::string, std::string> configs;
444 auto result = ParseSimplex(node, configs);
445 powerConfig.clear();
446 if (result != EXEC_SUCCESS) {
447 HGM_LOGI("XMLParser failed to powerConfig component_power_config");
448 return result;
449 }
450 for (const auto &item: configs) {
451 if (!IsNumber(item.second)) {
452 continue;
453 }
454 powerConfig[item.first] = std::stoi(item.second.c_str());
455 }
456 return EXEC_SUCCESS;
457 }
458
ParseSmallSizeDynamicSetting(xmlNode & node,PolicyConfigData::ScreenSetting & screenSetting)459 int32_t XMLParser::ParseSmallSizeDynamicSetting(xmlNode& node, PolicyConfigData::ScreenSetting& screenSetting)
460 {
461 auto area = ExtractPropertyValue("area", node);
462 auto length = ExtractPropertyValue("length", node);
463 if (!IsNumber(area) || !IsNumber(length)) {
464 return HGM_ERROR;
465 }
466 screenSetting.smallSizeArea = std::stoi(area);
467 screenSetting.smallSizeLength = std::stoi(length);
468 return ParseDynamicSetting(node, screenSetting.smallSizeAnimationDynamicSettings);
469 }
470
ParseDynamicSetting(xmlNode & node,PolicyConfigData::DynamicSettingMap & dynamicSettingMap)471 int32_t XMLParser::ParseDynamicSetting(xmlNode& node, PolicyConfigData::DynamicSettingMap& dynamicSettingMap)
472 {
473 HGM_LOGD("XMLParser parsing dynamicSetting");
474 xmlNode *currNode = &node;
475 if (currNode->xmlChildrenNode == nullptr) {
476 HGM_LOGD("XMLParser stop parsing dynamicSetting, no children nodes");
477 return HGM_ERROR;
478 }
479
480 // re-parse
481 dynamicSettingMap.clear();
482 currNode = currNode->xmlChildrenNode;
483 for (; currNode; currNode = currNode->next) {
484 auto dynamicSettingType = ExtractPropertyValue("name", *currNode);
485 PolicyConfigData::DynamicSetting dynamicSetting;
486 dynamicSettingMap[dynamicSettingType] = dynamicSetting;
487 for (xmlNode *thresholdNode = currNode->xmlChildrenNode; thresholdNode; thresholdNode = thresholdNode->next) {
488 if (thresholdNode->type != XML_ELEMENT_NODE) {
489 continue;
490 }
491 auto name = ExtractPropertyValue("name", *thresholdNode);
492 auto min = ExtractPropertyValue("min", *thresholdNode);
493 auto max = ExtractPropertyValue("max", *thresholdNode);
494 auto preferred_fps = ExtractPropertyValue("preferred_fps", *thresholdNode);
495 if (!IsNumber(min) || !IsNumber(max) || !IsNumber(preferred_fps)) {
496 dynamicSettingMap[dynamicSettingType].clear();
497 break;
498 }
499 PolicyConfigData::DynamicConfig dynamicConfig;
500 dynamicConfig.min = std::stoi(min);
501 dynamicConfig.max = std::stoi(max);
502 dynamicConfig.preferred_fps = std::stoi(preferred_fps);
503 dynamicSettingMap[dynamicSettingType][name] = dynamicConfig;
504
505 HGM_LOGI("HgmXMLParser ParseDynamicSetting dynamicType=%{public}s name=%{public}s min=%{public}d",
506 dynamicSettingType.c_str(), name.c_str(), dynamicSettingMap[dynamicSettingType][name].min);
507 }
508 }
509 return EXEC_SUCCESS;
510 }
511
ParseSceneList(xmlNode & node,PolicyConfigData::SceneConfigMap & sceneList)512 int32_t XMLParser::ParseSceneList(xmlNode& node, PolicyConfigData::SceneConfigMap& sceneList)
513 {
514 HGM_LOGD("XMLParser parsing sceneList");
515 xmlNode *currNode = &node;
516 if (currNode->xmlChildrenNode == nullptr) {
517 HGM_LOGD("XMLParser stop parsing sceneList, no children nodes");
518 return HGM_ERROR;
519 }
520
521 // re-parse
522 sceneList.clear();
523 currNode = currNode->xmlChildrenNode;
524 for (; currNode; currNode = currNode->next) {
525 if (currNode->type != XML_ELEMENT_NODE) {
526 continue;
527 }
528 PolicyConfigData::SceneConfig sceneConfig;
529 auto name = ExtractPropertyValue("name", *currNode);
530 sceneConfig.strategy = ExtractPropertyValue("strategy", *currNode);
531 sceneConfig.priority = ExtractPropertyValue("priority", *currNode);
532 sceneConfig.doNotAutoClear = ExtractPropertyValue("doNotAutoClear", *currNode) == "1";
533 sceneConfig.disableSafeVote = ExtractPropertyValue("disableSafeVote", *currNode) == "1";
534 sceneList[name] = sceneConfig;
535 HGM_LOGI("HgmXMLParser ParseSceneList name=%{public}s strategy=%{public}s priority=%{public}s \
536 doNotAutoClear=%{public}s disableSafeVote=%{public}s", name.c_str(),
537 sceneList[name].strategy.c_str(), sceneList[name].priority.c_str(),
538 sceneList[name].doNotAutoClear ? "true" : "false",
539 sceneList[name].disableSafeVote ? "true" : "false");
540 }
541
542 return EXEC_SUCCESS;
543 }
544
ParseSupportedModeConfig(xmlNode & node,PolicyConfigData::SupportedModeConfig & supportedModeConfig)545 int32_t XMLParser::ParseSupportedModeConfig(xmlNode& node, PolicyConfigData::SupportedModeConfig& supportedModeConfig)
546 {
547 HGM_LOGD("XMLParser parsing supportedModeConfig");
548 xmlNode *currNode = &node;
549 if (currNode->xmlChildrenNode == nullptr) {
550 HGM_LOGD("XMLParser stop parsing supportedModeConfig, no children nodes");
551 return HGM_ERROR;
552 }
553
554 // re-parse
555 supportedModeConfig.clear();
556 currNode = currNode->xmlChildrenNode;
557 for (; currNode; currNode = currNode->next) {
558 if (currNode->type != XML_ELEMENT_NODE) {
559 continue;
560 }
561 std::vector<uint32_t> supportedModeVec;
562 auto name = ExtractPropertyValue("name", *currNode);
563 auto value = ExtractPropertyValue("value", *currNode);
564 supportedModeVec = StringToVector(value);
565
566 supportedModeConfig[name] = supportedModeVec;
567 HGM_LOGI("HgmXMLParser ParseSupportedModeConfig name=%{public}s value=%{public}s",
568 name.c_str(), value.c_str());
569 }
570 return EXEC_SUCCESS;
571 }
572
ParseMultiAppStrategy(xmlNode & node,PolicyConfigData::ScreenSetting & screenSetting)573 int32_t XMLParser::ParseMultiAppStrategy(xmlNode& node, PolicyConfigData::ScreenSetting& screenSetting)
574 {
575 auto multiAppStrategy = ExtractPropertyValue("multi_app_strategy", node);
576 if (multiAppStrategy == "focus") {
577 screenSetting.multiAppStrategyType = MultiAppStrategyType::FOLLOW_FOCUS;
578 } else if (multiAppStrategy.find("strategy_") != std::string::npos) {
579 screenSetting.multiAppStrategyType = MultiAppStrategyType::USE_STRATEGY_NUM;
580 screenSetting.multiAppStrategyName = multiAppStrategy.substr(
581 std::string("strategy_").size(), multiAppStrategy.size());
582 } else {
583 screenSetting.multiAppStrategyType = MultiAppStrategyType::USE_MAX;
584 }
585 ParseSimplex(node, screenSetting.gameAppNodeList, "nodeName", "name", true);
586 return ParseSimplex(node, screenSetting.appList, "strategy");
587 }
588
589
ParseAppTypes(xmlNode & node,std::unordered_map<int32_t,std::string> & appTypes)590 int32_t XMLParser::ParseAppTypes(xmlNode& node, std::unordered_map<int32_t, std::string>& appTypes)
591 {
592 HGM_LOGD("XMLParser parsing appTypes");
593 xmlNode *currNode = &node;
594 if (currNode->xmlChildrenNode == nullptr) {
595 HGM_LOGD("XMLParser stop parsing appTypes, no children nodes");
596 return HGM_ERROR;
597 }
598
599 // re-parse
600 appTypes.clear();
601 currNode = currNode->xmlChildrenNode;
602 for (; currNode; currNode = currNode->next) {
603 if (currNode->type != XML_ELEMENT_NODE) {
604 continue;
605 }
606 auto name = ExtractPropertyValue("name", *currNode);
607 if (!IsNumber(name)) {
608 continue;
609 }
610 auto strategy = ExtractPropertyValue("strategy", *currNode);
611 appTypes[std::stoi(name)] = strategy;
612 HGM_LOGI("HgmXMLParser ParseAppTypes name=%{public}s strategy=%{public}s", name.c_str(), strategy.c_str());
613 }
614
615 return EXEC_SUCCESS;
616 }
617
ReplenishMissThermalConfig(const PolicyConfigData::ScreenConfig & screenConfigDefault,PolicyConfigData::ScreenConfig & screenConfig)618 int32_t XMLParser::ReplenishMissThermalConfig(const PolicyConfigData::ScreenConfig& screenConfigDefault,
619 PolicyConfigData::ScreenConfig& screenConfig)
620 {
621 HGM_LOGD("HgmXMLParser ReplenishMissThermalConfig");
622 for (const auto& [id, screenSettingDefalut] : screenConfigDefault) {
623 if (screenConfig.find(id) == screenConfig.end()) {
624 screenConfig[id] = screenSettingDefalut;
625 }
626 }
627
628 return EXEC_SUCCESS;
629 }
630
ParsePerformanceConfig(xmlNode & node,std::unordered_map<std::string,std::string> & performanceConfig)631 int32_t XMLParser::ParsePerformanceConfig(
632 xmlNode& node, std::unordered_map<std::string, std::string>& performanceConfig)
633 {
634 HGM_LOGD("XMLParser parsing performanceConfig");
635 xmlNode *currNode = &node;
636 if (currNode->xmlChildrenNode == nullptr) {
637 HGM_LOGD("XMLParser stop parsing performanceConfig, no children nodes");
638 return HGM_ERROR;
639 }
640
641 // re-parse
642 performanceConfig.clear();
643 currNode = currNode->xmlChildrenNode;
644 for (; currNode; currNode = currNode->next) {
645 if (currNode->type != XML_ELEMENT_NODE) {
646 continue;
647 }
648 auto name = ExtractPropertyValue("name", *currNode);
649 auto value = ExtractPropertyValue("value", *currNode);
650 performanceConfig[std::move(name)] = std::move(value);
651 HGM_LOGI("HgmXMLParser performanceConfig name=%{public}s strategy=%{public}s", name.c_str(), value.c_str());
652 }
653
654 return EXEC_SUCCESS;
655 }
656
ExtractPropertyValue(const std::string & propName,xmlNode & node)657 std::string XMLParser::ExtractPropertyValue(const std::string& propName, xmlNode& node)
658 {
659 HGM_LOGD("XMLParser extracting value : %{public}s", propName.c_str());
660 std::string propValue = "";
661 xmlChar *tempValue = nullptr;
662
663 if (xmlHasProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
664 tempValue = xmlGetProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()));
665 }
666
667 if (tempValue != nullptr) {
668 HGM_LOGD("XMLParser not aempty tempValue");
669 propValue = reinterpret_cast<const char*>(tempValue);
670 xmlFree(tempValue);
671 tempValue = nullptr;
672 }
673
674 return propValue;
675 }
676
IsNumber(const std::string & str)677 bool XMLParser::IsNumber(const std::string& str)
678 {
679 if (str.length() == 0 || str.length() > XML_STRING_MAX_LENGTH) {
680 return false;
681 }
682 auto number = static_cast<uint32_t>(std::count_if(str.begin(), str.end(), [](unsigned char c) {
683 return std::isdigit(c);
684 }));
685 return number == str.length() || (str.compare(0, 1, "-") == 0 && number == str.length() - 1);
686 }
687
StringToVector(const std::string & str,const std::string & pattern)688 std::vector<uint32_t> XMLParser::StringToVector(const std::string &str, const std::string &pattern)
689 {
690 std::vector<std::string> vstr;
691 std::string::size_type wordBegin = 0;
692 std::string::size_type wordEnd = str.find(pattern);
693 while (wordEnd != std::string::npos) {
694 vstr.push_back(str.substr(wordBegin, wordEnd - wordBegin));
695 wordBegin = wordEnd + pattern.size();
696 wordEnd = str.find(pattern, wordBegin);
697 }
698 if (wordBegin != str.length()) {
699 vstr.push_back(str.substr(wordBegin));
700 }
701
702 std::vector<uint32_t> vec;
703 for (const auto& s : vstr) {
704 if (!IsNumber(s)) {
705 continue;
706 }
707 vec.emplace_back(std::stoi(s));
708 }
709 return vec;
710 }
711
ParsePageUrlStrategy(xmlNode & node,std::unordered_map<std::string,PolicyConfigData::PageUrlConfig> & pageUrlConfigMap)712 int32_t XMLParser::ParsePageUrlStrategy(xmlNode& node,
713 std::unordered_map<std::string, PolicyConfigData::PageUrlConfig>& pageUrlConfigMap)
714 {
715 pageUrlConfigMap.clear();
716 HGM_LOGD("XMLParser parsing PageUrlConfig");
717 xmlNode *currNode = &node;
718 if (currNode->xmlChildrenNode == nullptr) {
719 HGM_LOGE("XMLParser stop parsing PageUrlConfig, no children nodes");
720 return HGM_ERROR;
721 }
722
723 currNode = currNode->xmlChildrenNode;
724 for (; currNode; currNode = currNode->next) {
725 if (currNode->type != XML_ELEMENT_NODE) {
726 continue;
727 }
728 if (currNode->xmlChildrenNode == nullptr) {
729 HGM_LOGE("XMLParser stop parsing Package, no children nodes");
730 return HGM_ERROR;
731 }
732
733 xmlNode *childNode = currNode->xmlChildrenNode;
734 PolicyConfigData::PageUrlConfig pageUrlConfig;
735 for (; childNode; childNode = childNode->next) {
736 if (childNode->type != XML_ELEMENT_NODE) {
737 continue;
738 }
739 auto name = ExtractPropertyValue("name", *childNode);
740 auto strategy = ExtractPropertyValue("strategy", *childNode);
741 mParsedData_->pageNameList_.push_back(name);
742 pageUrlConfig[name] = strategy;
743 }
744 auto packageName = ExtractPropertyValue("name", *currNode);
745 pageUrlConfigMap[packageName] = pageUrlConfig;
746 }
747 return EXEC_SUCCESS;
748 }
749 } // namespace OHOS::Rosen