1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci#include "display_manager_config.h" 16e0dac50fSopenharmony_ci 17e0dac50fSopenharmony_ci#include <climits> 18e0dac50fSopenharmony_ci#include <cstdint> 19e0dac50fSopenharmony_ci#include <cstdlib> 20e0dac50fSopenharmony_ci#include <libxml/globals.h> 21e0dac50fSopenharmony_ci#include <libxml/xmlstring.h> 22e0dac50fSopenharmony_ci#include <map> 23e0dac50fSopenharmony_ci#include <string> 24e0dac50fSopenharmony_ci#include <utility> 25e0dac50fSopenharmony_ci#include <vector> 26e0dac50fSopenharmony_ci 27e0dac50fSopenharmony_ci#include "config_policy_utils.h" 28e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 29e0dac50fSopenharmony_ci 30e0dac50fSopenharmony_ci 31e0dac50fSopenharmony_cinamespace OHOS::Rosen { 32e0dac50fSopenharmony_cinamespace { 33e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayManagerConfig"}; 34e0dac50fSopenharmony_ci} 35e0dac50fSopenharmony_ci 36e0dac50fSopenharmony_cistd::map<std::string, bool> DisplayManagerConfig::enableConfig_; 37e0dac50fSopenharmony_cistd::map<std::string, std::vector<int>> DisplayManagerConfig::intNumbersConfig_; 38e0dac50fSopenharmony_cistd::map<std::string, std::string> DisplayManagerConfig::stringConfig_; 39e0dac50fSopenharmony_ci 40e0dac50fSopenharmony_cistd::vector<std::string> DisplayManagerConfig::Split(std::string str, std::string pattern) 41e0dac50fSopenharmony_ci{ 42e0dac50fSopenharmony_ci std::vector<std::string> result; 43e0dac50fSopenharmony_ci str += pattern; 44e0dac50fSopenharmony_ci size_t length = str.size(); 45e0dac50fSopenharmony_ci for (size_t i = 0; i < length; i++) { 46e0dac50fSopenharmony_ci size_t position = str.find(pattern, i); 47e0dac50fSopenharmony_ci if (position < length) { 48e0dac50fSopenharmony_ci std::string tmp = str.substr(i, position - i); 49e0dac50fSopenharmony_ci result.push_back(tmp); 50e0dac50fSopenharmony_ci i = position + pattern.size() - 1; 51e0dac50fSopenharmony_ci } 52e0dac50fSopenharmony_ci } 53e0dac50fSopenharmony_ci return result; 54e0dac50fSopenharmony_ci} 55e0dac50fSopenharmony_ci 56e0dac50fSopenharmony_cibool inline DisplayManagerConfig::IsNumber(std::string str) 57e0dac50fSopenharmony_ci{ 58e0dac50fSopenharmony_ci for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) { 59e0dac50fSopenharmony_ci if (str.at(i) < '0' || str.at(i) > '9') { 60e0dac50fSopenharmony_ci return false; 61e0dac50fSopenharmony_ci } 62e0dac50fSopenharmony_ci } 63e0dac50fSopenharmony_ci return true; 64e0dac50fSopenharmony_ci} 65e0dac50fSopenharmony_ci 66e0dac50fSopenharmony_cistd::string DisplayManagerConfig::GetConfigPath(const std::string& configFileName) 67e0dac50fSopenharmony_ci{ 68e0dac50fSopenharmony_ci char buf[PATH_MAX + 1]; 69e0dac50fSopenharmony_ci char* configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX + 1); 70e0dac50fSopenharmony_ci char tmpPath[PATH_MAX + 1] = { 0 }; 71e0dac50fSopenharmony_ci if (!configPath || strlen(configPath) == 0 || strlen(configPath) > PATH_MAX || !realpath(configPath, tmpPath)) { 72e0dac50fSopenharmony_ci WLOGFI("[DmConfig] can not get customization config file"); 73e0dac50fSopenharmony_ci return "/system/" + configFileName; 74e0dac50fSopenharmony_ci } 75e0dac50fSopenharmony_ci return std::string(tmpPath); 76e0dac50fSopenharmony_ci} 77e0dac50fSopenharmony_ci 78e0dac50fSopenharmony_cibool DisplayManagerConfig::LoadConfigXml() 79e0dac50fSopenharmony_ci{ 80e0dac50fSopenharmony_ci auto configFilePath = GetConfigPath("etc/window/resources/display_manager_config.xml"); 81e0dac50fSopenharmony_ci xmlDocPtr docPtr = nullptr; 82e0dac50fSopenharmony_ci { 83e0dac50fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mutex_); 84e0dac50fSopenharmony_ci docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS); 85e0dac50fSopenharmony_ci } 86e0dac50fSopenharmony_ci WLOGFI("[DmConfig] filePath: %{public}s", configFilePath.c_str()); 87e0dac50fSopenharmony_ci if (docPtr == nullptr) { 88e0dac50fSopenharmony_ci WLOGFE("[DmConfig] load xml error!"); 89e0dac50fSopenharmony_ci return false; 90e0dac50fSopenharmony_ci } 91e0dac50fSopenharmony_ci 92e0dac50fSopenharmony_ci xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr); 93e0dac50fSopenharmony_ci if (rootPtr == nullptr || rootPtr->name == nullptr || 94e0dac50fSopenharmony_ci xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) { 95e0dac50fSopenharmony_ci WLOGFE("[DmConfig] get root element failed!"); 96e0dac50fSopenharmony_ci xmlFreeDoc(docPtr); 97e0dac50fSopenharmony_ci return false; 98e0dac50fSopenharmony_ci } 99e0dac50fSopenharmony_ci 100e0dac50fSopenharmony_ci for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) { 101e0dac50fSopenharmony_ci if (!IsValidNode(*curNodePtr)) { 102e0dac50fSopenharmony_ci WLOGFE("DmConfig]: invalid node!"); 103e0dac50fSopenharmony_ci continue; 104e0dac50fSopenharmony_ci } 105e0dac50fSopenharmony_ci 106e0dac50fSopenharmony_ci auto nodeName = curNodePtr->name; 107e0dac50fSopenharmony_ci if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("isWaterfallDisplay")) || 108e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("isWaterfallAreaCompressionEnableWhenHorizontal"))) { 109e0dac50fSopenharmony_ci ReadEnableConfigInfo(curNodePtr); 110e0dac50fSopenharmony_ci continue; 111e0dac50fSopenharmony_ci } 112e0dac50fSopenharmony_ci if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("dpi")) || 113e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("defaultDeviceRotationOffset")) || 114e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("cutoutArea")) || 115e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("curvedScreenBoundary")) || 116e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("waterfallAreaCompressionSizeWhenHorzontal")) || 117e0dac50fSopenharmony_ci !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("buildInDefaultOrientation"))) { 118e0dac50fSopenharmony_ci ReadIntNumbersConfigInfo(curNodePtr); 119e0dac50fSopenharmony_ci continue; 120e0dac50fSopenharmony_ci } 121e0dac50fSopenharmony_ci if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("defaultDisplayCutoutPath"))) { 122e0dac50fSopenharmony_ci ReadStringConfigInfo(curNodePtr); 123e0dac50fSopenharmony_ci continue; 124e0dac50fSopenharmony_ci } 125e0dac50fSopenharmony_ci } 126e0dac50fSopenharmony_ci xmlFreeDoc(docPtr); 127e0dac50fSopenharmony_ci return true; 128e0dac50fSopenharmony_ci} 129e0dac50fSopenharmony_ci 130e0dac50fSopenharmony_cibool DisplayManagerConfig::IsValidNode(const xmlNode& currNode) 131e0dac50fSopenharmony_ci{ 132e0dac50fSopenharmony_ci if (currNode.name == nullptr || currNode.type == XML_COMMENT_NODE) { 133e0dac50fSopenharmony_ci return false; 134e0dac50fSopenharmony_ci } 135e0dac50fSopenharmony_ci return true; 136e0dac50fSopenharmony_ci} 137e0dac50fSopenharmony_ci 138e0dac50fSopenharmony_civoid DisplayManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) 139e0dac50fSopenharmony_ci{ 140e0dac50fSopenharmony_ci xmlChar* context = xmlNodeGetContent(currNode); 141e0dac50fSopenharmony_ci if (context == nullptr) { 142e0dac50fSopenharmony_ci WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); 143e0dac50fSopenharmony_ci return; 144e0dac50fSopenharmony_ci } 145e0dac50fSopenharmony_ci 146e0dac50fSopenharmony_ci std::vector<int> numbersVec; 147e0dac50fSopenharmony_ci std::string numbersStr = reinterpret_cast<const char*>(context); 148e0dac50fSopenharmony_ci if (numbersStr.empty()) { 149e0dac50fSopenharmony_ci xmlFree(context); 150e0dac50fSopenharmony_ci return; 151e0dac50fSopenharmony_ci } 152e0dac50fSopenharmony_ci auto numbers = Split(numbersStr, " "); 153e0dac50fSopenharmony_ci for (auto& num : numbers) { 154e0dac50fSopenharmony_ci if (!IsNumber(num)) { 155e0dac50fSopenharmony_ci WLOGFE("[DmConfig] read number error: nodeName:(%{public}s)", currNode->name); 156e0dac50fSopenharmony_ci xmlFree(context); 157e0dac50fSopenharmony_ci return; 158e0dac50fSopenharmony_ci } 159e0dac50fSopenharmony_ci numbersVec.emplace_back(std::stoi(num)); 160e0dac50fSopenharmony_ci } 161e0dac50fSopenharmony_ci 162e0dac50fSopenharmony_ci std::string nodeName = reinterpret_cast<const char *>(currNode->name); 163e0dac50fSopenharmony_ci intNumbersConfig_[nodeName] = numbersVec; 164e0dac50fSopenharmony_ci xmlFree(context); 165e0dac50fSopenharmony_ci} 166e0dac50fSopenharmony_ci 167e0dac50fSopenharmony_civoid DisplayManagerConfig::ReadEnableConfigInfo(const xmlNodePtr& currNode) 168e0dac50fSopenharmony_ci{ 169e0dac50fSopenharmony_ci xmlChar* enable = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("enable")); 170e0dac50fSopenharmony_ci if (enable == nullptr) { 171e0dac50fSopenharmony_ci WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); 172e0dac50fSopenharmony_ci return; 173e0dac50fSopenharmony_ci } 174e0dac50fSopenharmony_ci 175e0dac50fSopenharmony_ci std::string nodeName = reinterpret_cast<const char *>(currNode->name); 176e0dac50fSopenharmony_ci if (!xmlStrcmp(enable, reinterpret_cast<const xmlChar*>("true"))) { 177e0dac50fSopenharmony_ci enableConfig_[nodeName] = true; 178e0dac50fSopenharmony_ci } else { 179e0dac50fSopenharmony_ci enableConfig_[nodeName] = false; 180e0dac50fSopenharmony_ci } 181e0dac50fSopenharmony_ci xmlFree(enable); 182e0dac50fSopenharmony_ci} 183e0dac50fSopenharmony_ci 184e0dac50fSopenharmony_civoid DisplayManagerConfig::ReadStringConfigInfo(const xmlNodePtr& currNode) 185e0dac50fSopenharmony_ci{ 186e0dac50fSopenharmony_ci xmlChar* context = xmlNodeGetContent(currNode); 187e0dac50fSopenharmony_ci if (context == nullptr) { 188e0dac50fSopenharmony_ci WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); 189e0dac50fSopenharmony_ci return; 190e0dac50fSopenharmony_ci } 191e0dac50fSopenharmony_ci 192e0dac50fSopenharmony_ci std::string inputString = reinterpret_cast<const char*>(context); 193e0dac50fSopenharmony_ci std::string nodeName = reinterpret_cast<const char*>(currNode->name); 194e0dac50fSopenharmony_ci stringConfig_[nodeName] = inputString; 195e0dac50fSopenharmony_ci xmlFree(context); 196e0dac50fSopenharmony_ci} 197e0dac50fSopenharmony_ci 198e0dac50fSopenharmony_ciconst std::map<std::string, bool>& DisplayManagerConfig::GetEnableConfig() 199e0dac50fSopenharmony_ci{ 200e0dac50fSopenharmony_ci return enableConfig_; 201e0dac50fSopenharmony_ci} 202e0dac50fSopenharmony_ci 203e0dac50fSopenharmony_ciconst std::map<std::string, std::vector<int>>& DisplayManagerConfig::GetIntNumbersConfig() 204e0dac50fSopenharmony_ci{ 205e0dac50fSopenharmony_ci return intNumbersConfig_; 206e0dac50fSopenharmony_ci} 207e0dac50fSopenharmony_ci 208e0dac50fSopenharmony_ciconst std::map<std::string, std::string>& DisplayManagerConfig::GetStringConfig() 209e0dac50fSopenharmony_ci{ 210e0dac50fSopenharmony_ci return stringConfig_; 211e0dac50fSopenharmony_ci} 212e0dac50fSopenharmony_ci 213e0dac50fSopenharmony_civoid DisplayManagerConfig::DumpConfig() 214e0dac50fSopenharmony_ci{ 215e0dac50fSopenharmony_ci for (auto& enable : enableConfig_) { 216e0dac50fSopenharmony_ci WLOGFI("[DmConfig] Enable: %{public}s %{public}u", enable.first.c_str(), enable.second); 217e0dac50fSopenharmony_ci } 218e0dac50fSopenharmony_ci for (auto& numbers : intNumbersConfig_) { 219e0dac50fSopenharmony_ci WLOGFI("[DmConfig] Numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); 220e0dac50fSopenharmony_ci for (auto& num : numbers.second) { 221e0dac50fSopenharmony_ci WLOGFI("[DmConfig] Num: %{public}d", num); 222e0dac50fSopenharmony_ci } 223e0dac50fSopenharmony_ci } 224e0dac50fSopenharmony_ci for (auto& string : stringConfig_) { 225e0dac50fSopenharmony_ci WLOGFI("[DmConfig] String: %{public}s", string.first.c_str()); 226e0dac50fSopenharmony_ci } 227e0dac50fSopenharmony_ci} 228e0dac50fSopenharmony_ci} // namespace OHOS::Rosen 229