• 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 
16 #include "window_manager_config.h"
17 #include "config_policy_utils.h"
18 #include "window_helper.h"
19 #include "window_manager_hilog.h"
20 
21 namespace OHOS {
22 namespace Rosen {
23 namespace {
24     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowManagerConfig"};
25 }
26 
27 WindowManagerConfig::ConfigItem WindowManagerConfig::config_;
28 const WindowManagerConfig::ConfigItem WindowManagerConfig::ConfigItem::DEFAULT;
29 const std::map<std::string, WindowManagerConfig::ValueType> WindowManagerConfig::configItemTypeMap_ = {
30     { "maxAppWindowNumber",     WindowManagerConfig::ValueType::INTS },
31     { "maxUniRenderAppWindowNumber", WindowManagerConfig::ValueType::INTS },
32     { "modeChangeHotZones",     WindowManagerConfig::ValueType::INTS },
33     { "duration",               WindowManagerConfig::ValueType::INTS },
34     { "durationIn",             WindowManagerConfig::ValueType::INTS },
35     { "durationOut",            WindowManagerConfig::ValueType::INTS },
36     { "defaultWindowMode",      WindowManagerConfig::ValueType::INTS },
37     { "floatingBottomPosY",     WindowManagerConfig::ValueType::INTS },
38     { "defaultFloatingWindow",  WindowManagerConfig::ValueType::INTS },
39     { "windowAnimation",        WindowManagerConfig::ValueType::MAP },
40     { "keyboardAnimation",      WindowManagerConfig::ValueType::MAP },
41     { "timing",                 WindowManagerConfig::ValueType::MAP },
42     { "windowEffect",           WindowManagerConfig::ValueType::MAP },
43     { "appWindows",             WindowManagerConfig::ValueType::MAP },
44     { "cornerRadius",           WindowManagerConfig::ValueType::MAP },
45     { "shadow",                 WindowManagerConfig::ValueType::MAP },
46     { "focused",                WindowManagerConfig::ValueType::MAP },
47     { "unfocused",              WindowManagerConfig::ValueType::MAP },
48     { "curve",                  WindowManagerConfig::ValueType::POSITIVE_FLOATS },
49     { "splitRatios",            WindowManagerConfig::ValueType::POSITIVE_FLOATS },
50     { "exitSplitRatios",        WindowManagerConfig::ValueType::POSITIVE_FLOATS },
51     { "scale",                  WindowManagerConfig::ValueType::POSITIVE_FLOATS },
52     { "opacity",                WindowManagerConfig::ValueType::POSITIVE_FLOATS },
53     { "elevation",              WindowManagerConfig::ValueType::POSITIVE_FLOATS },
54     { "alpha",                  WindowManagerConfig::ValueType::POSITIVE_FLOATS },
55     { "rotation",               WindowManagerConfig::ValueType::FLOATS },
56     { "translate",              WindowManagerConfig::ValueType::FLOATS },
57     { "offsetX",                WindowManagerConfig::ValueType::FLOATS },
58     { "offsetY",                WindowManagerConfig::ValueType::FLOATS },
59     { "fullScreen",             WindowManagerConfig::ValueType::STRING },
60     { "split",                  WindowManagerConfig::ValueType::STRING },
61     { "float",                  WindowManagerConfig::ValueType::STRING },
62     { "color",                  WindowManagerConfig::ValueType::STRING },
63     { "decor",                  WindowManagerConfig::ValueType::UNDIFINED },
64     { "minimizeByOther",        WindowManagerConfig::ValueType::UNDIFINED },
65     { "stretchable",            WindowManagerConfig::ValueType::UNDIFINED },
66     { "remoteAnimation",        WindowManagerConfig::ValueType::UNDIFINED },
67 };
68 
ReadNumberStrings(const xmlNodePtr & node)69 std::vector<std::string> WindowManagerConfig::ReadNumberStrings(const xmlNodePtr& node)
70 {
71     xmlChar* context = xmlNodeGetContent(node);
72     if (context == nullptr) {
73         WLOGFE("[WmConfig] read xml node error: nodeName:(%{public}s)", node->name);
74         return std::vector<std::string>();
75     }
76 
77     std::string numbersStr = reinterpret_cast<const char*>(context);
78     xmlFree(context);
79     if (numbersStr.size() == 0) {
80         return std::vector<std::string>();
81     }
82     return WindowHelper::Split(numbersStr, " ");
83 }
84 
GetConfigPath(const std::string & configFileName)85 std::string WindowManagerConfig::GetConfigPath(const std::string& configFileName)
86 {
87     char buf[PATH_MAX + 1];
88     char* configPath = GetOneCfgFile(configFileName.c_str(), buf, PATH_MAX + 1);
89     char tmpPath[PATH_MAX + 1] = { 0 };
90     if (!configPath || strlen(configPath) == 0 || strlen(configPath) > PATH_MAX || !realpath(configPath, tmpPath)) {
91         WLOGFI("[WmConfig] can not get customization config file");
92         return "/system/" + configFileName;
93     }
94     return std::string(tmpPath);
95 }
96 
ReadConfig(const xmlNodePtr & rootPtr,std::map<std::string,ConfigItem> & mapValue)97 void WindowManagerConfig::ReadConfig(const xmlNodePtr& rootPtr, std::map<std::string, ConfigItem>& mapValue)
98 {
99     for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) {
100         if (!IsValidNode(*curNodePtr)) {
101             WLOGFE("[WmConfig]: invalid node!");
102             continue;
103         }
104         std::string nodeName = reinterpret_cast<const char*>(curNodePtr->name);
105         if (configItemTypeMap_.count(nodeName)) {
106             std::map<std::string, ConfigItem> p;
107             ReadProperty(curNodePtr, p);
108             if (p.size() > 0) {
109                 mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetProperty(p);
110             }
111             switch (configItemTypeMap_.at(nodeName)) {
112                 case ValueType::INTS: {
113                     std::vector<int> v;
114                     ReadIntNumbersConfigInfo(curNodePtr, v);
115                     mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
116                     break;
117                 }
118                 case ValueType::POSITIVE_FLOATS: {
119                     std::vector<float> v;
120                     ReadFloatNumbersConfigInfo(curNodePtr, v, false);
121                     mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
122                     break;
123                 }
124                 case ValueType::FLOATS: {
125                     std::vector<float> v;
126                     ReadFloatNumbersConfigInfo(curNodePtr, v, true);
127                     mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
128                     break;
129                 }
130                 case ValueType::MAP: {
131                     std::map<std::string, ConfigItem> v;
132                     ReadConfig(curNodePtr, v);
133                     mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
134                     break;
135                 }
136                 case ValueType::STRING: {
137                     std::string v;
138                     ReadStringConfigInfo(curNodePtr, v);
139                     mapValue[reinterpret_cast<const char*>(curNodePtr->name)].SetValue(v);
140                     break;
141                 }
142                 default:
143                     break;
144             }
145         }
146     }
147 }
148 
LoadConfigXml()149 bool WindowManagerConfig::LoadConfigXml()
150 {
151     auto configFilePath = GetConfigPath("etc/window/resources/window_manager_config.xml");
152     xmlDocPtr docPtr = xmlReadFile(configFilePath.c_str(), nullptr, XML_PARSE_NOBLANKS);
153     WLOGFI("[WmConfig] filePath: %{public}s", configFilePath.c_str());
154     if (docPtr == nullptr) {
155         WLOGFE("[WmConfig] load xml error!");
156         return false;
157     }
158 
159     xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
160     if (rootPtr == nullptr || rootPtr->name == nullptr ||
161         xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
162         WLOGFE("[WmConfig] get root element failed!");
163         xmlFreeDoc(docPtr);
164         return false;
165     }
166 
167     std::map<std::string, ConfigItem> configMap;
168     config_.SetValue(configMap);
169     ReadConfig(rootPtr, *config_.mapValue_);
170 
171     xmlFreeDoc(docPtr);
172     return true;
173 }
174 
IsValidNode(const xmlNode & currNode)175 bool WindowManagerConfig::IsValidNode(const xmlNode& currNode)
176 {
177     if (currNode.name == nullptr || currNode.type == XML_COMMENT_NODE) {
178         return false;
179     }
180     return true;
181 }
182 
ReadProperty(const xmlNodePtr & currNode,std::map<std::string,ConfigItem> & property)183 void WindowManagerConfig::ReadProperty(const xmlNodePtr& currNode,
184     std::map<std::string, ConfigItem>& property)
185 {
186     xmlChar* prop = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("enable"));
187     if (prop != nullptr) {
188         if (!xmlStrcmp(prop, reinterpret_cast<const xmlChar*>("true"))) {
189             property["enable"].SetValue(true);
190         } else if (!xmlStrcmp(prop, reinterpret_cast<const xmlChar*>("false"))) {
191             property["enable"].SetValue(false);
192         }
193         xmlFree(prop);
194     }
195 
196     prop = xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name"));
197     if (prop != nullptr) {
198         property["name"].SetValue(std::string(reinterpret_cast<const char*>(prop)));
199         xmlFree(prop);
200     }
201 }
202 
ReadIntNumbersConfigInfo(const xmlNodePtr & currNode,std::vector<int> & intsValue)203 void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode, std::vector<int>& intsValue)
204 {
205     auto numbers = ReadNumberStrings(currNode);
206     for (auto& num : numbers) {
207         if (!WindowHelper::IsNumber(num)) {
208             WLOGFE("[WmConfig] read int number error: nodeName:(%{public}s)", currNode->name);
209             return;
210         }
211         intsValue.push_back(std::stoi(num));
212     }
213 }
214 
ReadFloatNumbersConfigInfo(const xmlNodePtr & currNode,std::vector<float> & floatsValue,bool allowNeg)215 void WindowManagerConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode,
216     std::vector<float>& floatsValue, bool allowNeg)
217 {
218     auto numbers = ReadNumberStrings(currNode);
219     for (auto& num : numbers) {
220         if (!WindowHelper::IsFloatingNumber(num, allowNeg)) {
221             WLOGFE("[WmConfig] read float number error: nodeName:(%{public}s)", currNode->name);
222             return;
223         }
224         floatsValue.push_back(std::stof(num));
225     }
226 }
227 
ReadStringConfigInfo(const xmlNodePtr & currNode,std::string & stringValue)228 void WindowManagerConfig::ReadStringConfigInfo(const xmlNodePtr& currNode, std::string& stringValue)
229 {
230     xmlChar* context = xmlNodeGetContent(currNode);
231     if (context == nullptr) {
232         WLOGFE("[WmConfig] read xml node error: nodeName:(%{public}s)", currNode->name);
233         return;
234     }
235 
236     stringValue = std::string(reinterpret_cast<const char*>(context));
237     xmlFree(context);
238 }
239 
DumpConfig(const std::map<std::string,ConfigItem> & config)240 void WindowManagerConfig::DumpConfig(const std::map<std::string, ConfigItem>& config)
241 {
242     for (auto& conf : config) {
243         WLOGFI("[WmConfig] %{public}s", conf.first.c_str());
244         std::map<std::string, ConfigItem> propMap;
245         if (conf.second.property_) {
246             propMap = *conf.second.property_;
247         }
248         for (auto prop : propMap) {
249             switch (prop.second.type_) {
250                 case ValueType::BOOL:
251                     WLOGFI("[WmConfig] Prop: %{public}s %{public}u", prop.first.c_str(), prop.second.boolValue_);
252                     break;
253                 case ValueType::STRING:
254                     WLOGFI("[WmConfig] Prop: %{public}s %{public}s", prop.first.c_str(),
255                         prop.second.stringValue_.c_str());
256                     break;
257                 default:
258                     break;
259             }
260         }
261         switch (conf.second.type_) {
262             case ValueType::MAP:
263                 if (conf.second.mapValue_) {
264                     DumpConfig(*conf.second.mapValue_);
265                 }
266                 break;
267             case ValueType::BOOL:
268                 WLOGFI("[WmConfig] %{public}u", conf.second.boolValue_);
269                 break;
270             case ValueType::STRING:
271                 WLOGFI("[WmConfig] %{public}s", conf.second.stringValue_.c_str());
272                 break;
273             case ValueType::INTS:
274                 for (auto& num : *conf.second.intsValue_) {
275                     WLOGFI("[WmConfig] Num: %{public}d", num);
276                 }
277                 break;
278             case ValueType::FLOATS:
279                 for (auto& num : *conf.second.floatsValue_) {
280                     WLOGFI("[WmConfig] Num: %{public}f", num);
281                 }
282                 break;
283             default:
284                 break;
285         }
286     }
287 }
288 } // namespace Rosen
289 } // namespace OHOS
290