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