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