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