• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "display_manager_config.h"
16 
17 #include <climits>
18 #include <cstdint>
19 #include <cstdlib>
20 #include <libxml/globals.h>
21 #include <libxml/xmlstring.h>
22 #include <map>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 #include "config_policy_utils.h"
28 #include "window_manager_hilog.h"
29 
30 
31 namespace OHOS::Rosen {
32 namespace {
33     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayManagerConfig"};
34 }
35 
36 std::map<std::string, bool> DisplayManagerConfig::enableConfig_;
37 std::map<std::string, std::vector<int>> DisplayManagerConfig::intNumbersConfig_;
38 std::map<std::string, std::string> DisplayManagerConfig::stringConfig_;
39 
Split(std::string str,std::string pattern)40 std::vector<std::string> DisplayManagerConfig::Split(std::string str, std::string pattern)
41 {
42     std::vector<std::string> result;
43     str += pattern;
44     int32_t length = static_cast<int32_t>(str.size());
45     for (int32_t i = 0; i < length; i++) {
46         int32_t position = static_cast<int32_t>(str.find(pattern, i));
47         if (position < length) {
48             std::string tmp = str.substr(i, position - i);
49             result.push_back(tmp);
50             i = position + static_cast<int32_t>(pattern.size()) - 1;
51         }
52     }
53     return result;
54 }
55 
IsNumber(std::string str)56 bool inline DisplayManagerConfig::IsNumber(std::string str)
57 {
58     for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) {
59         if (str.at(i) < '0' || str.at(i) > '9') {
60             return false;
61         }
62     }
63     return true;
64 }
65 
GetConfigPath(const std::string & configFileName)66 std::string DisplayManagerConfig::GetConfigPath(const std::string& configFileName)
67 {
68     char buf[PATH_MAX + 1];
69     char* configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX + 1);
70     char tmpPath[PATH_MAX + 1] = { 0 };
71     if (!configPath || strlen(configPath) == 0 || strlen(configPath) > PATH_MAX || !realpath(configPath, tmpPath)) {
72         WLOGFI("[DmConfig] can not get customization config file");
73         return "/system/" + configFileName;
74     }
75     return std::string(tmpPath);
76 }
77 
LoadConfigXml()78 bool DisplayManagerConfig::LoadConfigXml()
79 {
80     auto configFilePath = GetConfigPath("etc/window/resources/display_manager_config.xml");
81     xmlDocPtr docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS);
82     WLOGFI("[DmConfig] filePath: %{public}s", configFilePath.c_str());
83     if (docPtr == nullptr) {
84         WLOGFE("[DmConfig] load xml error!");
85         return false;
86     }
87 
88     xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
89     if (rootPtr == nullptr || rootPtr->name == nullptr ||
90         xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
91         WLOGFE("[DmConfig] get root element failed!");
92         xmlFreeDoc(docPtr);
93         return false;
94     }
95 
96     for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
97         if (!IsValidNode(*curNodePtr)) {
98             WLOGFE("DmConfig]: invalid node!");
99             continue;
100         }
101 
102         auto nodeName = curNodePtr->name;
103         if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("isWaterfallDisplay")) ||
104             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("isWaterfallAreaCompressionEnableWhenHorizontal"))) {
105             ReadEnableConfigInfo(curNodePtr);
106             continue;
107         }
108         if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("dpi")) ||
109             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("defaultDeviceRotationOffset")) ||
110             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("cutoutArea")) ||
111             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("curvedScreenBoundary")) ||
112             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("waterfallAreaCompressionSizeWhenHorzontal")) ||
113             !xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("buildInDefaultOrientation"))) {
114             ReadIntNumbersConfigInfo(curNodePtr);
115             continue;
116         }
117         if (!xmlStrcmp(nodeName, reinterpret_cast<const xmlChar*>("defaultDisplayCutoutPath"))) {
118             ReadStringConfigInfo(curNodePtr);
119             continue;
120         }
121     }
122     xmlFreeDoc(docPtr);
123     return true;
124 }
125 
IsValidNode(const xmlNode & currNode)126 bool DisplayManagerConfig::IsValidNode(const xmlNode& currNode)
127 {
128     if (currNode.name == nullptr || currNode.type == XML_COMMENT_NODE) {
129         return false;
130     }
131     return true;
132 }
133 
ReadIntNumbersConfigInfo(const xmlNodePtr & currNode)134 void DisplayManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode)
135 {
136     xmlChar* context = xmlNodeGetContent(currNode);
137     if (context == nullptr) {
138         WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
139         return;
140     }
141 
142     std::vector<int> numbersVec;
143     std::string numbersStr = reinterpret_cast<const char*>(context);
144     if (numbersStr.empty()) {
145         xmlFree(context);
146         return;
147     }
148     auto numbers = Split(numbersStr, " ");
149     for (auto& num : numbers) {
150         if (!IsNumber(num)) {
151             WLOGFE("[DmConfig] read number error: nodeName:(%{public}s)", currNode->name);
152             xmlFree(context);
153             return;
154         }
155         numbersVec.emplace_back(std::stoi(num));
156     }
157 
158     std::string nodeName = reinterpret_cast<const char *>(currNode->name);
159     intNumbersConfig_[nodeName] = numbersVec;
160     xmlFree(context);
161 }
162 
ReadEnableConfigInfo(const xmlNodePtr & currNode)163 void DisplayManagerConfig::ReadEnableConfigInfo(const xmlNodePtr& currNode)
164 {
165     xmlChar* enable = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("enable"));
166     if (enable == nullptr) {
167         WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
168         return;
169     }
170 
171     std::string nodeName = reinterpret_cast<const char *>(currNode->name);
172     if (!xmlStrcmp(enable, reinterpret_cast<const xmlChar*>("true"))) {
173         enableConfig_[nodeName] = true;
174     } else {
175         enableConfig_[nodeName] = false;
176     }
177     xmlFree(enable);
178 }
179 
ReadStringConfigInfo(const xmlNodePtr & currNode)180 void DisplayManagerConfig::ReadStringConfigInfo(const xmlNodePtr& currNode)
181 {
182     xmlChar* context = xmlNodeGetContent(currNode);
183     if (context == nullptr) {
184         WLOGFE("[DmConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
185         return;
186     }
187 
188     std::string inputString = reinterpret_cast<const char*>(context);
189     std::string nodeName = reinterpret_cast<const char*>(currNode->name);
190     stringConfig_[nodeName] = inputString;
191     xmlFree(context);
192 }
193 
GetEnableConfig()194 const std::map<std::string, bool>& DisplayManagerConfig::GetEnableConfig()
195 {
196     return enableConfig_;
197 }
198 
GetIntNumbersConfig()199 const std::map<std::string, std::vector<int>>& DisplayManagerConfig::GetIntNumbersConfig()
200 {
201     return intNumbersConfig_;
202 }
203 
GetStringConfig()204 const std::map<std::string, std::string>& DisplayManagerConfig::GetStringConfig()
205 {
206     return stringConfig_;
207 }
208 
DumpConfig()209 void DisplayManagerConfig::DumpConfig()
210 {
211     for (auto& enable : enableConfig_) {
212         WLOGFI("[DmConfig] Enable: %{public}s %{public}u", enable.first.c_str(), enable.second);
213     }
214     for (auto& numbers : intNumbersConfig_) {
215         WLOGFI("[DmConfig] Numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size());
216         for (auto& num : numbers.second) {
217             WLOGFI("[DmConfig] Num: %{public}d", num);
218         }
219     }
220     for (auto& string : stringConfig_) {
221         WLOGFI("[DmConfig] String: %{public}s", string.first.c_str());
222     }
223 }
224 } // namespace OHOS::Rosen
225