13c3173acSopenharmony_ci/* 23c3173acSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 33c3173acSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43c3173acSopenharmony_ci * you may not use this file except in compliance with the License. 53c3173acSopenharmony_ci * You may obtain a copy of the License at 63c3173acSopenharmony_ci * 73c3173acSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83c3173acSopenharmony_ci * 93c3173acSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103c3173acSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113c3173acSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123c3173acSopenharmony_ci * See the License for the specific language governing permissions and 133c3173acSopenharmony_ci * limitations under the License. 143c3173acSopenharmony_ci */ 153c3173acSopenharmony_ci#include <cstdlib> 163c3173acSopenharmony_ci#include <string> 173c3173acSopenharmony_ci#include <climits> 183c3173acSopenharmony_ci 193c3173acSopenharmony_ci#include "config_reader.h" 203c3173acSopenharmony_ci#include "config_policy_utils.h" 213c3173acSopenharmony_ci#include "concurrent_task_log.h" 223c3173acSopenharmony_ci#include "parameters.h" 233c3173acSopenharmony_ci 243c3173acSopenharmony_ciusing namespace std; 253c3173acSopenharmony_ci 263c3173acSopenharmony_cinamespace OHOS { 273c3173acSopenharmony_cinamespace ConcurrentTask { 283c3173acSopenharmony_cinamespace { 293c3173acSopenharmony_ci const std::string XML_TAG_QOS_CONFIG = "qosconfig"; 303c3173acSopenharmony_ci const std::string XML_TAG_QOS_AUTH = "auth"; 313c3173acSopenharmony_ci const std::string XML_TAG_UIDLIST = "uidlist"; 323c3173acSopenharmony_ci const std::string XML_TAG_UID = "uid"; 333c3173acSopenharmony_ci const std::string XML_TAG_BUNDLENAMELIST = "bundlenamelist"; 343c3173acSopenharmony_ci const std::string XML_TAG_BUNDLENAME = "bundlename"; 353c3173acSopenharmony_ci const std::string XML_TAG_POWER_MODE = "powermode"; 363c3173acSopenharmony_ci const std::string XML_TAG_SWITCH = "switch"; 373c3173acSopenharmony_ci const std::string XML_TAG_FPS = "fps"; 383c3173acSopenharmony_ci const std::string XML_TAG_DEGRADATION_FPS = "degradationfps"; 393c3173acSopenharmony_ci const std::string XML_TAG_FPS_HIGH = "120"; 403c3173acSopenharmony_ci const std::string XML_TAG_FPS_MEDIUM = "90"; 413c3173acSopenharmony_ci const std::string XML_TAG_FPS_STANDARD = "60"; 423c3173acSopenharmony_ci constexpr int FPS_OFFSET = 10000; 433c3173acSopenharmony_ci} 443c3173acSopenharmony_ci 453c3173acSopenharmony_cibool ConfigReader::IsValidNode(const xmlNode* currNode) 463c3173acSopenharmony_ci{ 473c3173acSopenharmony_ci if (!currNode) { 483c3173acSopenharmony_ci return false; 493c3173acSopenharmony_ci } 503c3173acSopenharmony_ci if (!currNode->name || currNode->type == XML_COMMENT_NODE) { 513c3173acSopenharmony_ci return false; 523c3173acSopenharmony_ci } 533c3173acSopenharmony_ci return true; 543c3173acSopenharmony_ci} 553c3173acSopenharmony_ci 563c3173acSopenharmony_cibool ConfigReader::FillinUidInfo(const xmlNode* currNode) 573c3173acSopenharmony_ci{ 583c3173acSopenharmony_ci if (!IsValidNode(currNode)) { 593c3173acSopenharmony_ci CONCUR_LOGE("FillinUidInfo:: currNode is nullptr!"); 603c3173acSopenharmony_ci return false; 613c3173acSopenharmony_ci } 623c3173acSopenharmony_ci xmlNodePtr currNodePtr = currNode->xmlChildrenNode; 633c3173acSopenharmony_ci for (; currNodePtr; currNodePtr = currNodePtr->next) { 643c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_UID.c_str())) == 0) { 653c3173acSopenharmony_ci xmlChar *attrValue = xmlGetProp(currNodePtr, reinterpret_cast<const xmlChar*>(XML_TAG_UID.c_str())); 663c3173acSopenharmony_ci if (!attrValue) { 673c3173acSopenharmony_ci CONCUR_LOGE("FillinUidInfo:: uid null!"); 683c3173acSopenharmony_ci return false; 693c3173acSopenharmony_ci } 703c3173acSopenharmony_ci int64_t uid = atoi(reinterpret_cast<const char*>(attrValue)); 713c3173acSopenharmony_ci authProcUidConfigs_.insert(uid); 723c3173acSopenharmony_ci xmlFree(attrValue); 733c3173acSopenharmony_ci } 743c3173acSopenharmony_ci } 753c3173acSopenharmony_ci return true; 763c3173acSopenharmony_ci} 773c3173acSopenharmony_ci 783c3173acSopenharmony_cibool ConfigReader::FillinBundleNameInfo(const xmlNode* currNode) 793c3173acSopenharmony_ci{ 803c3173acSopenharmony_ci if (!IsValidNode(currNode)) { 813c3173acSopenharmony_ci CONCUR_LOGE("FillinBundleNameInfo:: currNode is nullptr!"); 823c3173acSopenharmony_ci return false; 833c3173acSopenharmony_ci } 843c3173acSopenharmony_ci xmlNodePtr currNodePtr = currNode->xmlChildrenNode; 853c3173acSopenharmony_ci for (; currNodePtr; currNodePtr = currNodePtr->next) { 863c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_BUNDLENAME.c_str())) == 0) { 873c3173acSopenharmony_ci xmlChar *attrValue = xmlGetProp(currNodePtr, reinterpret_cast<const xmlChar*>(XML_TAG_BUNDLENAME.c_str())); 883c3173acSopenharmony_ci if (!attrValue) { 893c3173acSopenharmony_ci CONCUR_LOGE("FillinBundleNameInfo:: bundleName null!"); 903c3173acSopenharmony_ci return false; 913c3173acSopenharmony_ci } 923c3173acSopenharmony_ci std::string bundleName = reinterpret_cast<const char*>(attrValue); 933c3173acSopenharmony_ci authProcBundleNameConfigs_.insert(bundleName); 943c3173acSopenharmony_ci xmlFree(attrValue); 953c3173acSopenharmony_ci } 963c3173acSopenharmony_ci } 973c3173acSopenharmony_ci return true; 983c3173acSopenharmony_ci} 993c3173acSopenharmony_ci 1003c3173acSopenharmony_civoid ConfigReader::ParseAuth(const xmlNode* currNode) 1013c3173acSopenharmony_ci{ 1023c3173acSopenharmony_ci xmlNodePtr currNodePtr = currNode->xmlChildrenNode; 1033c3173acSopenharmony_ci for (; currNodePtr; currNodePtr = currNodePtr->next) { 1043c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_UIDLIST.c_str())) == 0) { 1053c3173acSopenharmony_ci if (!FillinUidInfo(currNodePtr)) { 1063c3173acSopenharmony_ci CONCUR_LOGE("ParseAuth:: uid fill in authProcUidConfigs_ error!"); 1073c3173acSopenharmony_ci continue; 1083c3173acSopenharmony_ci } 1093c3173acSopenharmony_ci } 1103c3173acSopenharmony_ci 1113c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_BUNDLENAMELIST.c_str())) == 0) { 1123c3173acSopenharmony_ci if (!FillinBundleNameInfo(currNodePtr)) { 1133c3173acSopenharmony_ci CONCUR_LOGE("ParseAuth:: bundleName fill in authProcBundleNameConfigs_ error!"); 1143c3173acSopenharmony_ci continue; 1153c3173acSopenharmony_ci } 1163c3173acSopenharmony_ci } 1173c3173acSopenharmony_ci } 1183c3173acSopenharmony_ci} 1193c3173acSopenharmony_ci 1203c3173acSopenharmony_civoid ConfigReader::ParsePowerMode(const xmlNode* currNode) 1213c3173acSopenharmony_ci{ 1223c3173acSopenharmony_ci if (!IsValidNode(currNode)) { 1233c3173acSopenharmony_ci CONCUR_LOGE("ParsePowerMode:: currNode is nullptr!"); 1243c3173acSopenharmony_ci return; 1253c3173acSopenharmony_ci } 1263c3173acSopenharmony_ci xmlNodePtr currNodePtr = currNode->xmlChildrenNode; 1273c3173acSopenharmony_ci for (; currNodePtr; currNodePtr = currNodePtr->next) { 1283c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_SWITCH.c_str())) == 0) { 1293c3173acSopenharmony_ci char* switchValue = reinterpret_cast<char*>(xmlNodeGetContent(currNodePtr)); 1303c3173acSopenharmony_ci if (!switchValue) { 1313c3173acSopenharmony_ci CONCUR_LOGE("ParsePowerMode:: switch is null!"); 1323c3173acSopenharmony_ci continue; 1333c3173acSopenharmony_ci } 1343c3173acSopenharmony_ci if (strncmp(switchValue, "1", 1) == 0) { 1353c3173acSopenharmony_ci powerModeSchedSwitch_ = true; 1363c3173acSopenharmony_ci } else if (strncmp(switchValue, "0", 1) == 0) { 1373c3173acSopenharmony_ci powerModeSchedSwitch_ = false; 1383c3173acSopenharmony_ci } else { 1393c3173acSopenharmony_ci CONCUR_LOGE("ParsePowerMode:: invalid switch value!"); 1403c3173acSopenharmony_ci } 1413c3173acSopenharmony_ci xmlFree(switchValue); 1423c3173acSopenharmony_ci } 1433c3173acSopenharmony_ci 1443c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_DEGRADATION_FPS.c_str())) == 0) { 1453c3173acSopenharmony_ci char* fpsValue = reinterpret_cast<char*>(xmlGetProp(currNodePtr, 1463c3173acSopenharmony_ci reinterpret_cast<const xmlChar*>(XML_TAG_FPS.c_str()))); 1473c3173acSopenharmony_ci char* deFpsValue = reinterpret_cast<char*>(xmlNodeGetContent(currNodePtr)); 1483c3173acSopenharmony_ci if (fpsValue && deFpsValue && IsValidFps(fpsValue) && IsPositiveInt(deFpsValue)) { 1493c3173acSopenharmony_ci degradationFpsMap_.insert(std::make_pair(atoi(fpsValue), atoi(deFpsValue))); 1503c3173acSopenharmony_ci } else { 1513c3173acSopenharmony_ci CONCUR_LOGE("ParsePowerMode:: fps is null or invalid!"); 1523c3173acSopenharmony_ci } 1533c3173acSopenharmony_ci if (fpsValue) { 1543c3173acSopenharmony_ci xmlFree(fpsValue); 1553c3173acSopenharmony_ci } 1563c3173acSopenharmony_ci if (deFpsValue) { 1573c3173acSopenharmony_ci xmlFree(deFpsValue); 1583c3173acSopenharmony_ci } 1593c3173acSopenharmony_ci } 1603c3173acSopenharmony_ci } 1613c3173acSopenharmony_ci} 1623c3173acSopenharmony_ci 1633c3173acSopenharmony_cibool ConfigReader::LoadFromConfigFile(const std::string& configFile) 1643c3173acSopenharmony_ci{ 1653c3173acSopenharmony_ci // skip the empty string, else you will get empty node 1663c3173acSopenharmony_ci xmlDocPtr xmlDocPtr = xmlReadFile(configFile.c_str(), nullptr, 1673c3173acSopenharmony_ci XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); 1683c3173acSopenharmony_ci if (!xmlDocPtr) { 1693c3173acSopenharmony_ci CONCUR_LOGE("LoadFromConfigFile:: xmlReadFile error!"); 1703c3173acSopenharmony_ci return false; 1713c3173acSopenharmony_ci } 1723c3173acSopenharmony_ci xmlNodePtr rootNodePtr = xmlDocGetRootElement(xmlDocPtr); 1733c3173acSopenharmony_ci if (!rootNodePtr || !rootNodePtr->name || 1743c3173acSopenharmony_ci xmlStrcmp(rootNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_QOS_CONFIG.c_str())) != 0) { 1753c3173acSopenharmony_ci CONCUR_LOGE("LoadFromConfigFile:: root element tag error!"); 1763c3173acSopenharmony_ci xmlFreeDoc(xmlDocPtr); 1773c3173acSopenharmony_ci return false; 1783c3173acSopenharmony_ci } 1793c3173acSopenharmony_ci xmlNodePtr currNodePtr = rootNodePtr->xmlChildrenNode; 1803c3173acSopenharmony_ci for (; currNodePtr; currNodePtr = currNodePtr->next) { 1813c3173acSopenharmony_ci if (!IsValidNode(currNodePtr)) { 1823c3173acSopenharmony_ci CONCUR_LOGE("LoadFromConfigFile:: IsInvalidNode!"); 1833c3173acSopenharmony_ci continue; 1843c3173acSopenharmony_ci } 1853c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_QOS_AUTH.c_str())) == 0) { 1863c3173acSopenharmony_ci ParseAuth(currNodePtr); 1873c3173acSopenharmony_ci } 1883c3173acSopenharmony_ci if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_POWER_MODE.c_str())) == 0) { 1893c3173acSopenharmony_ci ParsePowerMode(currNodePtr); 1903c3173acSopenharmony_ci } 1913c3173acSopenharmony_ci } 1923c3173acSopenharmony_ci ConfigHilog(); 1933c3173acSopenharmony_ci xmlFreeDoc(xmlDocPtr); 1943c3173acSopenharmony_ci return true; 1953c3173acSopenharmony_ci} 1963c3173acSopenharmony_ci 1973c3173acSopenharmony_civoid ConfigReader::GetRealConfigPath(const char* configName, std::string& configPath) 1983c3173acSopenharmony_ci{ 1993c3173acSopenharmony_ci if (!configName) { 2003c3173acSopenharmony_ci CONCUR_LOGE("GetRealConfigPath:: configName is nullptr!"); 2013c3173acSopenharmony_ci return; 2023c3173acSopenharmony_ci } 2033c3173acSopenharmony_ci char buf[PATH_MAX] = {0}; 2043c3173acSopenharmony_ci char* configFilePath = GetOneCfgFile(configName, buf, PATH_MAX); 2053c3173acSopenharmony_ci char tmpPath[PATH_MAX] = {0}; 2063c3173acSopenharmony_ci if (!configFilePath || strlen(configFilePath) == 0 || strlen(configFilePath) > PATH_MAX || 2073c3173acSopenharmony_ci !realpath(configFilePath, tmpPath)) { 2083c3173acSopenharmony_ci CONCUR_LOGE("GetRealConfigPath:: get config file path error!"); 2093c3173acSopenharmony_ci configPath = ""; 2103c3173acSopenharmony_ci return; 2113c3173acSopenharmony_ci } 2123c3173acSopenharmony_ci configPath = tmpPath; 2133c3173acSopenharmony_ci} 2143c3173acSopenharmony_ci 2153c3173acSopenharmony_cibool ConfigReader::IsUidAuth(pid_t uid) 2163c3173acSopenharmony_ci{ 2173c3173acSopenharmony_ci if (authProcUidConfigs_.find(uid) != authProcUidConfigs_.end()) { 2183c3173acSopenharmony_ci return true; 2193c3173acSopenharmony_ci } 2203c3173acSopenharmony_ci return false; 2213c3173acSopenharmony_ci} 2223c3173acSopenharmony_ci 2233c3173acSopenharmony_cibool ConfigReader::IsBundleNameAuth(std::string& bundleName) 2243c3173acSopenharmony_ci{ 2253c3173acSopenharmony_ci if (authProcBundleNameConfigs_.find(bundleName) != authProcBundleNameConfigs_.end()) { 2263c3173acSopenharmony_ci return true; 2273c3173acSopenharmony_ci } 2283c3173acSopenharmony_ci return false; 2293c3173acSopenharmony_ci} 2303c3173acSopenharmony_ci 2313c3173acSopenharmony_cibool ConfigReader::GetPowerModeSchedSwitch() 2323c3173acSopenharmony_ci{ 2333c3173acSopenharmony_ci return powerModeSchedSwitch_; 2343c3173acSopenharmony_ci} 2353c3173acSopenharmony_ci 2363c3173acSopenharmony_ciint ConfigReader::GetDegratationFps(int fps) 2373c3173acSopenharmony_ci{ 2383c3173acSopenharmony_ci if (degradationFpsMap_.find(fps) == degradationFpsMap_.end()) { 2393c3173acSopenharmony_ci return fps + FPS_OFFSET; 2403c3173acSopenharmony_ci } 2413c3173acSopenharmony_ci return degradationFpsMap_[fps] + FPS_OFFSET; 2423c3173acSopenharmony_ci} 2433c3173acSopenharmony_ci 2443c3173acSopenharmony_cibool ConfigReader::IsValidFps(const std::string& fps) 2453c3173acSopenharmony_ci{ 2463c3173acSopenharmony_ci if (fps == XML_TAG_FPS_HIGH || fps == XML_TAG_FPS_MEDIUM || fps == XML_TAG_FPS_STANDARD) { 2473c3173acSopenharmony_ci return true; 2483c3173acSopenharmony_ci } 2493c3173acSopenharmony_ci return false; 2503c3173acSopenharmony_ci} 2513c3173acSopenharmony_ci 2523c3173acSopenharmony_cibool ConfigReader::IsPositiveInt(const std::string& intStr) 2533c3173acSopenharmony_ci{ 2543c3173acSopenharmony_ci int num = 0; 2553c3173acSopenharmony_ci try { 2563c3173acSopenharmony_ci num = stoi(intStr); 2573c3173acSopenharmony_ci } catch (...) { 2583c3173acSopenharmony_ci CONCUR_LOGE("Unexpected number format!"); 2593c3173acSopenharmony_ci return false; 2603c3173acSopenharmony_ci } 2613c3173acSopenharmony_ci return num > 0; 2623c3173acSopenharmony_ci} 2633c3173acSopenharmony_ci 2643c3173acSopenharmony_civoid ConfigReader::ConfigHilog() 2653c3173acSopenharmony_ci{ 2663c3173acSopenharmony_ci bool getConfigRead = OHOS::system::GetBoolParameter("persist.qos.configreadlog", false); 2673c3173acSopenharmony_ci if (getConfigRead) { 2683c3173acSopenharmony_ci for (auto iter : authProcUidConfigs_) { 2693c3173acSopenharmony_ci CONCUR_LOGI("authProcUidConfigs_ contain uid = %{public}d", (int32_t)iter); 2703c3173acSopenharmony_ci } 2713c3173acSopenharmony_ci for (auto iter : authProcBundleNameConfigs_) { 2723c3173acSopenharmony_ci CONCUR_LOGI("authProcBundleNameConfigs_ contain bundleName = %{public}s", iter.c_str()); 2733c3173acSopenharmony_ci } 2743c3173acSopenharmony_ci CONCUR_LOGI("powerModeSchedSwitch_ = %{public}d", powerModeSchedSwitch_); 2753c3173acSopenharmony_ci for (auto iter : degradationFpsMap_) { 2763c3173acSopenharmony_ci CONCUR_LOGI("fps = %{public}d degradationFps = %{public}d", iter.first, iter.second); 2773c3173acSopenharmony_ci } 2783c3173acSopenharmony_ci } 2793c3173acSopenharmony_ci} 2803c3173acSopenharmony_ci} 2813c3173acSopenharmony_ci}