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