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