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 #include "theme_pack_manager.h"
16 
17 #include "auto_mutex.h"
18 #include <dirent.h>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include "hilog_wrapper.h"
23 #include "theme_pack_resource.h"
24 #include <securec.h>
25 #include "utils/utils.h"
26 
27 namespace OHOS {
28 namespace Global {
29 namespace Resource {
30 constexpr int FIRST_ELEMENT = 0;
31 constexpr int SECOND_ELEMENT = 1;
32 constexpr int THIRED_ELEMENT = 2;
33 static std::shared_ptr<ThemePackManager> themeMgr = nullptr;
34 static std::once_flag themeMgrFlag;
35 constexpr uint32_t SYSTEM_ID_BEGIN = 117440512; // 0x07000000
36 constexpr uint32_t SYSTEM_ID_END = 134217727; // 0x07FFFFFF
37 const std::string themeFlagA = "data/themes/a/app/flag";
38 const std::string themeFlagB = "data/themes/b/app/flag";
39 const std::string themeSkinA = "/data/themes/a/app/skin";
40 const std::string themeSkinB = "/data/themes/b/app/skin";
41 const std::string themeIconsA = "/data/themes/a/app/icons";
42 const std::string themeIconsB = "/data/themes/b/app/icons";
43 const std::string absoluteThemeFlagA = "data/service/el1/public/themes/<currentUserId>/a/app/flag";
44 const std::string absoluteThemeFlagB = "data/service/el1/public/themes/<currentUserId>/b/app/flag";
45 const std::string absoluteThemeSkinA = "/data/service/el1/public/themes/<currentUserId>/a/app/skin";
46 const std::string absoluteThemeSkinB = "/data/service/el1/public/themes/<currentUserId>/b/app/skin";
47 const std::string absoluteThemeIconsA = "/data/service/el1/public/themes/<currentUserId>/a/app/icons";
48 const std::string absoluteThemeIconsB = "/data/service/el1/public/themes/<currentUserId>/b/app/icons";
ThemePackManager()49 ThemePackManager::ThemePackManager()
50 {}
51 
~ThemePackManager()52 ThemePackManager::~ThemePackManager()
53 {
54     skinResource_.clear();
55     iconResource_.clear();
56     iconMaskValues_.clear();
57     useCountMap_.clear();
58 }
59 
GetThemePackManager()60 std::shared_ptr<ThemePackManager> ThemePackManager::GetThemePackManager()
61 {
62     std::call_once(themeMgrFlag, [&] {
63         themeMgr = std::shared_ptr<ThemePackManager>(new ThemePackManager());
64     });
65     return themeMgr;
66 }
67 
GetRootDir(const std::string & strCurrentDir)68 std::vector<std::string> ThemePackManager::GetRootDir(const std::string &strCurrentDir)
69 {
70     std::vector<std::string> vDir;
71 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
72     DIR *dir;
73     struct dirent *pDir;
74     if ((dir = opendir(strCurrentDir.c_str())) == nullptr) {
75         return vDir;
76     }
77     while ((pDir = readdir(dir)) != nullptr) {
78         if (strcmp(pDir->d_name, ".") == 0 || strcmp(pDir->d_name, "..") == 0) {
79             continue;
80         } else if (pDir->d_type == 4) { // 4 means dir
81             std::string strNextDir = strCurrentDir + "/" + pDir->d_name;
82             vDir.emplace_back(strNextDir);
83         } else if (pDir->d_type == 8) { // 8 means file
84             std::string filePath = strCurrentDir + "/" + pDir->d_name;
85             if (filePath.find("icon_mask") != std::string::npos) {
86                 themeMask = filePath;
87             }
88         }
89     }
90     closedir(dir);
91 #endif
92     return vDir;
93 }
94 
ClearSkinResource()95 void ThemePackManager::ClearSkinResource()
96 {
97     for (auto it = skinResource_.begin(); it != skinResource_.end();) {
98         if ((*it) == nullptr) {
99             continue;
100         }
101         // 1 means get the enable theme
102         if (!(*it)->IsNewResource()) {
103             it = skinResource_.erase(it);
104         } else {
105             ++it;
106         }
107     }
108 }
109 
LoadThemeSkinResource(const std::string & bundleName,const std::string & moduleName,const std::vector<std::string> & rootDirs,int32_t userId)110 void ThemePackManager::LoadThemeSkinResource(const std::string &bundleName, const std::string &moduleName,
111     const std::vector<std::string> &rootDirs, int32_t userId)
112 {
113     AutoMutex mutex(this->lockSkin_);
114     ChangeSkinResourceStatus(userId);
115     if (rootDirs.empty()) {
116         ClearSkinResource();
117         return;
118     }
119     for (const auto &dir : rootDirs) {
120         auto pos = dir.rfind('/');
121         if (pos == std::string::npos) {
122             RESMGR_HILOGE(RESMGR_TAG, "invalid dir = %{public}s in LoadThemeSkinResource", dir.c_str());
123             continue;
124         }
125         std::string tempBundleName = dir.substr(pos + 1);
126         if (tempBundleName != bundleName && tempBundleName != "systemRes") {
127             continue;
128         }
129         auto pThemeResource = ThemeResource::LoadThemeResource(dir);
130         if (pThemeResource != nullptr) {
131             this->skinResource_.emplace_back(pThemeResource);
132         }
133     }
134     ClearSkinResource();
135 }
136 
LoadThemeRes(const std::string & bundleName,const std::string & moduleName,int32_t userId)137 void ThemePackManager::LoadThemeRes(const std::string &bundleName, const std::string &moduleName, int32_t userId)
138 {
139     UpdateUserId(userId);
140     std::vector<std::string> rootDirs;
141     std::vector<std::string> iconDirs;
142     if (Utils::IsFileExist(themeFlagA)) {
143         rootDirs = GetRootDir(themeSkinA);
144         iconDirs = GetRootDir(themeIconsA);
145     } else if (Utils::IsFileExist(themeFlagB)) {
146         rootDirs = GetRootDir(themeSkinB);
147         iconDirs = GetRootDir(themeIconsB);
148     } else {
149         LoadSAThemeRes(bundleName, moduleName, userId, rootDirs, iconDirs);
150     }
151     LoadThemeSkinResource(bundleName, moduleName, rootDirs, userId);
152     LoadThemeIconsResource(bundleName, moduleName, iconDirs, userId);
153     return;
154 }
155 
LoadSAThemeRes(const std::string & bundleName,const std::string & moduleName,int32_t userId,std::vector<std::string> & rootDirs,std::vector<std::string> & iconDirs)156 void ThemePackManager::LoadSAThemeRes(const std::string &bundleName, const std::string &moduleName,
157     int32_t userId, std::vector<std::string> &rootDirs, std::vector<std::string> &iconDirs)
158 {
159     if (Utils::IsFileExist(ReplaceUserIdInPath(absoluteThemeFlagA, userId))) {
160         rootDirs = GetRootDir(ReplaceUserIdInPath(absoluteThemeSkinA, userId));
161         iconDirs = GetRootDir(ReplaceUserIdInPath(absoluteThemeIconsA, userId));
162     } else if (Utils::IsFileExist(ReplaceUserIdInPath(absoluteThemeFlagB, userId))) {
163         rootDirs = GetRootDir(ReplaceUserIdInPath(absoluteThemeSkinB, userId));
164         iconDirs = GetRootDir(ReplaceUserIdInPath(absoluteThemeIconsB, userId));
165     }
166     return;
167 }
168 
ReplaceUserIdInPath(const std::string & originalPath,int32_t userId)169 const std::string ThemePackManager::ReplaceUserIdInPath(const std::string &originalPath, int32_t userId)
170 {
171     std::string result = originalPath;
172     auto found = result.find("<currentUserId>");
173     if (found != std::string::npos) {
174         result.replace(found, 15, std::to_string(userId)); // 15 is the length of "<currentUserId>"
175     }
176     return result;
177 }
178 
FindThemeResource(const std::pair<std::string,std::string> & bundleInfo,std::vector<std::shared_ptr<IdItem>> idItems,const ResConfigImpl & resConfig,int32_t userId,bool isThemeSystemResEnable)179 const std::string ThemePackManager::FindThemeResource(const std::pair<std::string, std::string> &bundleInfo,
180     std::vector<std::shared_ptr<IdItem>> idItems, const ResConfigImpl &resConfig, int32_t userId,
181     bool isThemeSystemResEnable)
182 {
183     std::string result;
184     for (size_t i = 0; i < idItems.size(); i++) {
185         std::string resName = idItems[i]->GetItemResName();
186         uint32_t id = idItems[i]->GetItemResId();
187         ResType resType = idItems[i]->GetItemResType();
188         if (id >= SYSTEM_ID_BEGIN && id <= SYSTEM_ID_END) {
189             if (resType == ResType::COLOR && !isThemeSystemResEnable) {
190                 break;
191             }
192             std::pair<std::string, std::string> tempInfo("systemRes", "entry");
193             result = GetThemeResource(tempInfo, resType, resName, resConfig, userId);
194         } else {
195             result = GetThemeResource(bundleInfo, resType, resName, resConfig, userId);
196         }
197         if (!result.empty()) {
198             break;
199         }
200     }
201     return result;
202 }
203 
GetThemeResource(const std::pair<std::string,std::string> & bundInfo,const ResType & resType,const std::string & resName,const ResConfigImpl & resConfig,int32_t userId)204 const std::string ThemePackManager::GetThemeResource(const std::pair<std::string, std::string> &bundInfo,
205     const ResType &resType, const std::string &resName, const ResConfigImpl &resConfig, int32_t userId)
206 {
207     auto themeQualifierValue = GetThemeQualifierValue(bundInfo, resType, resName, resConfig, userId);
208     if (themeQualifierValue == nullptr) {
209         RESMGR_HILOGD(RESMGR_TAG, "themeQualifierValue == nullptr");
210         return std::string("");
211     }
212     return themeQualifierValue->GetResValue();
213 }
214 
GetThemeResourceList(const std::pair<std::string,std::string> & bundInfo,const ResType & resType,const std::string & resName,int32_t userId)215 std::vector<std::shared_ptr<ThemeResource::ThemeValue> > ThemePackManager::GetThemeResourceList(
216     const std::pair<std::string, std::string> &bundInfo, const ResType &resType, const std::string &resName,
217     int32_t userId)
218 {
219     AutoMutex mutex(this->lockSkin_);
220     std::vector<std::shared_ptr<ThemeResource::ThemeValue> > result;
221     for (size_t i = 0; i < skinResource_.size(); ++i) {
222         auto pThemeResource = skinResource_[i];
223         if (pThemeResource == nullptr) {
224             continue;
225         }
226         if (!IsSameResourceByUserId(pThemeResource->GetThemePath(), userId)) {
227             continue;
228         }
229         std::string bundleName = pThemeResource->GetThemeResBundleName(pThemeResource->themePath_);
230         if (bundleName != bundInfo.first) {
231             continue;
232         }
233         result = pThemeResource->GetThemeValues(bundInfo, resType, resName);
234     }
235     return result;
236 }
237 
GetThemeQualifierValue(const std::pair<std::string,std::string> & bundInfo,const ResType & resType,const std::string & resName,const ResConfigImpl & resConfig,int32_t userId)238 const std::shared_ptr<ThemeResource::ThemeQualifierValue> ThemePackManager::GetThemeQualifierValue(
239     const std::pair<std::string, std::string> &bundInfo, const ResType &resType,
240     const std::string &resName, const ResConfigImpl &resConfig, int32_t userId)
241 {
242     auto candidates = this->GetThemeResourceList(bundInfo, resType, resName, userId);
243     if (candidates.size() == 0) {
244         return nullptr;
245     }
246     return GetBestMatchThemeResource(candidates, resConfig);
247 }
248 
GetBestMatchThemeResource(const std::vector<std::shared_ptr<ThemeResource::ThemeValue>> & candidates,const ResConfigImpl & resConfig)249 const std::shared_ptr<ThemeResource::ThemeQualifierValue> ThemePackManager::GetBestMatchThemeResource(
250     const std::vector<std::shared_ptr<ThemeResource::ThemeValue> > &candidates, const ResConfigImpl &resConfig)
251 {
252     std::shared_ptr<ThemeResource::ThemeQualifierValue> result = nullptr;
253     std::shared_ptr<ThemeConfig> bestThemeConfig = nullptr;
254     for (auto iter = candidates.rbegin(); iter != candidates.rend(); iter++) {
255         const std::vector<std::shared_ptr<ThemeResource::ThemeQualifierValue> > ThemePaths =
256             (*iter)->GetThemeLimitPathsConst();
257         size_t len = ThemePaths.size();
258         for (size_t i = 0; i < len; i++) {
259             std::shared_ptr<ThemeResource::ThemeQualifierValue> path = ThemePaths[i];
260             auto themeConfig = path->GetThemeConfig();
261             if (!ThemeConfig::Match(themeConfig, resConfig)) {
262                 continue;
263             }
264             if (bestThemeConfig == nullptr) {
265                 bestThemeConfig = themeConfig;
266                 result = path;
267                 continue;
268             }
269             if (!bestThemeConfig->BestMatch(themeConfig, resConfig)) {
270                 bestThemeConfig = themeConfig;
271                 result = path;
272             }
273         }
274     }
275     return result;
276 }
277 
ClearIconResource()278 void ThemePackManager::ClearIconResource()
279 {
280     for (auto it = iconResource_.begin(); it != iconResource_.end();) {
281         if ((*it) == nullptr) {
282             continue;
283         }
284         // 1 means get the enable theme
285         if (!(*it)->IsNewResource()) {
286             it = iconResource_.erase(it);
287         } else {
288             ++it;
289         }
290     }
291     iconMaskValues_.clear();
292 }
293 
LoadThemeIconsResource(const std::string & bundleName,const std::string & moduleName,const std::vector<std::string> & rootDirs,int32_t userId)294 void ThemePackManager::LoadThemeIconsResource(const std::string &bundleName, const std::string &moduleName,
295     const std::vector<std::string> &rootDirs, int32_t userId)
296 {
297     AutoMutex mutex(this->lockIcon_);
298     ChangeIconResourceStatus(userId);
299     if (rootDirs.empty()) {
300         ClearIconResource();
301         return;
302     }
303     for (const auto &dir : rootDirs) {
304         auto pos = dir.rfind('/');
305         if (pos == std::string::npos) {
306             RESMGR_HILOGE(RESMGR_TAG, "invalid dir = %{public}s in LoadThemeIconsResource", dir.c_str());
307             continue;
308         }
309         auto pThemeResource = ThemeResource::LoadThemeIconResource(dir);
310         if (pThemeResource != nullptr) {
311             this->iconResource_.emplace_back(pThemeResource);
312         }
313     }
314     ClearIconResource();
315 }
316 
FindThemeIconResource(const std::pair<std::string,std::string> & bundleInfo,const std::string & iconName,int32_t userId,const std::string & abilityName)317 const std::string ThemePackManager::FindThemeIconResource(const std::pair<std::string, std::string> &bundleInfo,
318     const std::string &iconName, int32_t userId, const std::string &abilityName)
319 {
320     AutoMutex mutex(this->lockIcon_);
321     std::string result;
322     for (size_t i = 0; i < iconResource_.size(); i++) {
323         auto pThemeResource = iconResource_[i];
324         if (pThemeResource == nullptr) {
325             continue;
326         }
327         if (!IsSameResourceByUserId(pThemeResource->GetThemePath(), userId)) {
328             continue;
329         }
330         result = pThemeResource->GetThemeAppIcon(bundleInfo, iconName, abilityName);
331         if (!result.empty()) {
332             break;
333         }
334     }
335     return result;
336 }
337 
UpdateThemeId(uint32_t newThemeId)338 bool ThemePackManager::UpdateThemeId(uint32_t newThemeId)
339 {
340     AutoMutex mutex(this->lockThemeId_);
341     if (newThemeId != 0 && newThemeId != themeId_) {
342         RESMGR_HILOGI(RESMGR_TAG, "update theme, themeId_= %{public}d, newThemeId= %{public}d", themeId_, newThemeId);
343         themeId_ = newThemeId;
344         return true;
345     }
346     return false;
347 }
348 
IsFirstLoadResource()349 bool ThemePackManager::IsFirstLoadResource()
350 {
351     if (isFirstCreate) {
352         isFirstCreate = false;
353         return true;
354     }
355     return false;
356 }
357 
HasIconInTheme(const std::string & bundleName,int32_t userId)358 bool ThemePackManager::HasIconInTheme(const std::string &bundleName, int32_t userId)
359 {
360     AutoMutex mutex(this->lockIcon_);
361     bool result = false;
362     for (size_t i = 0; i < iconResource_.size(); i++) {
363         auto pThemeResource = iconResource_[i];
364         if (pThemeResource == nullptr) {
365             continue;
366         }
367         if (!IsSameResourceByUserId(pThemeResource->GetThemePath(), userId)) {
368             continue;
369         }
370         result = pThemeResource->HasIconInTheme(bundleName);
371         if (result) {
372             break;
373         }
374     }
375     return result;
376 }
377 
GetOtherIconsInfo(const std::string & iconName,std::unique_ptr<uint8_t[]> & outValue,size_t & len,bool isGlobalMask,int32_t userId)378 RState ThemePackManager::GetOtherIconsInfo(const std::string &iconName,
379     std::unique_ptr<uint8_t[]> &outValue, size_t &len, bool isGlobalMask, int32_t userId)
380 {
381     AutoMutex mutex(this->lockIconValue_);
382     std::string iconPath;
383     std::string iconTag;
384     if (iconName.find("icon_mask") != std::string::npos && isGlobalMask) {
385         iconPath = themeMask;
386         iconTag = "global_" + iconName;
387     } else {
388         std::pair<std::string, std::string> bundleInfo;
389         bundleInfo.first = "other_icons";
390         iconPath = FindThemeIconResource(bundleInfo, iconName, userId);
391         iconTag = "other_icons_" + iconName;
392     }
393 
394     if (iconPath.empty()) {
395         RESMGR_HILOGE(RESMGR_TAG, "no found, iconName = %{public}s", iconName.c_str());
396         return ERROR_CODE_RES_NOT_FOUND_BY_NAME;
397     }
398 
399     outValue = Utils::LoadResourceFile(iconPath, len);
400     if (outValue != nullptr && len != 0) {
401         auto tmpInfo = std::make_unique<uint8_t[]>(len);
402         errno_t ret = memcpy_s(tmpInfo.get(), len, outValue.get(), len);
403         if (ret != 0) {
404             RESMGR_HILOGE(RESMGR_TAG, "save fail, iconName = %{public}s, ret = %{public}d", iconName.c_str(), ret);
405             return SUCCESS;
406         }
407         iconMaskValues_.emplace_back(std::make_tuple(iconTag, std::move(tmpInfo), len));
408         return SUCCESS;
409     }
410     return ERROR_CODE_RES_NOT_FOUND_BY_NAME;
411 }
412 
GetThemeIconFromCache(const std::string & iconTag,std::unique_ptr<uint8_t[]> & outValue,size_t & len)413 RState ThemePackManager::GetThemeIconFromCache(
414     const std::string &iconTag, std::unique_ptr<uint8_t[]> &outValue, size_t &len)
415 {
416     AutoMutex mutex(this->lockIconValue_);
417     if (iconMaskValues_.empty()) {
418         return NOT_FOUND;
419     }
420 
421     for (const auto &iconValue : iconMaskValues_) {
422         std::string tag = std::get<FIRST_ELEMENT>(iconValue);
423         if (iconTag != tag) {
424             continue;
425         }
426         size_t length = std::get<THIRED_ELEMENT>(iconValue);
427         auto iconInfo = std::make_unique<uint8_t[]>(length);
428         auto tmpInfo = std::get<SECOND_ELEMENT>(iconValue).get();
429         errno_t ret = memcpy_s(iconInfo.get(), length, tmpInfo, length);
430         if (ret != 0) {
431             RESMGR_HILOGE(RESMGR_TAG, "get icon info fail, ret = %{public}d", ret);
432             continue;
433         }
434         len = length;
435         outValue = std::move(iconInfo);
436         return SUCCESS;
437     }
438     return NOT_FOUND;
439 }
440 
IsUpdateByUserId(int32_t userId)441 bool ThemePackManager::IsUpdateByUserId(int32_t userId)
442 {
443     AutoMutex mutex(this->lockUserId_);
444     return userId != 0 && currentUserId_ != userId;
445 }
446 
UpdateUserId(int32_t userId)447 void ThemePackManager::UpdateUserId(int32_t userId)
448 {
449     AutoMutex mutex(this->lockUserId_);
450     if (userId != 0 && currentUserId_ != userId) {
451         RESMGR_HILOGI(RESMGR_TAG,
452             "update userId, currentUserId_= %{public}d, userId= %{public}d", currentUserId_, userId);
453         currentUserId_ = userId;
454     }
455 }
456 
IsSameResourceByUserId(const std::string & path,int32_t userId)457 bool ThemePackManager::IsSameResourceByUserId(const std::string &path, int32_t userId)
458 {
459     std::string absolutePath("/data/service/el1/public/themes/");
460     if (path.empty() || path.find(absolutePath) == std::string::npos) {
461         return true;
462     }
463     auto pos = path.find("/", absolutePath.length());
464     if (pos == std::string::npos) {
465         return true;
466     }
467     auto subStr = path.substr(absolutePath.length(), pos - absolutePath.length());
468     int tmpId = -1;
469     if (!Utils::convertToInteger(subStr, tmpId)) {
470         return true;
471     }
472     return tmpId == userId;
473 }
474 
ChangeSkinResourceStatus(int32_t userId)475 void ThemePackManager::ChangeSkinResourceStatus(int32_t userId)
476 {
477     for (size_t i = 0; i < skinResource_.size(); ++i) {
478         auto pThemeResource = skinResource_[i];
479         if (pThemeResource == nullptr) {
480             continue;
481         }
482         if (IsSameResourceByUserId(pThemeResource->GetThemePath(), userId)) {
483             pThemeResource->SetNewResource(false);
484         }
485     }
486 }
487 
ChangeIconResourceStatus(int32_t userId)488 void ThemePackManager::ChangeIconResourceStatus(int32_t userId)
489 {
490     for (size_t i = 0; i < iconResource_.size(); ++i) {
491         auto pThemeResource = iconResource_[i];
492         if (pThemeResource == nullptr) {
493             continue;
494         }
495         if (IsSameResourceByUserId(pThemeResource->GetThemePath(), userId)) {
496             pThemeResource->SetNewResource(false);
497         }
498     }
499 }
500 
SetFlagByUserId(int32_t userId)501 void ThemePackManager::SetFlagByUserId(int32_t userId)
502 {
503     AutoMutex mutex(this->lockUseCount_);
504     auto iter = useCountMap_.find(userId);
505     if (iter != useCountMap_.end()) {
506         useCountMap_[userId] = iter->second + 1;
507         return;
508     }
509     useCountMap_[userId] = 1;
510 }
511 
CheckFlagByUserId(int32_t userId)512 void ThemePackManager::CheckFlagByUserId(int32_t userId)
513 {
514     AutoMutex mutex(this->lockUseCount_);
515     auto iter = useCountMap_.find(userId);
516     if (iter == useCountMap_.end()) {
517         return;
518     }
519     if (iter->second > 1) {
520         useCountMap_[userId] = iter->second - 1;
521         return;
522     }
523     useCountMap_.erase(userId);
524     ReleaseSkinResource(userId);
525     ReleaseIconResource(userId);
526     if (useCountMap_.empty() || !IsUpdateByUserId(userId)) {
527         UpdateUserId(-1); // reset user id
528     }
529 }
530 
ReleaseSkinResource(int32_t userId)531 void ThemePackManager::ReleaseSkinResource(int32_t userId)
532 {
533     AutoMutex mutex(this->lockSkin_);
534     ChangeSkinResourceStatus(userId);
535     ClearSkinResource();
536 }
537 
ReleaseIconResource(int32_t userId)538 void ThemePackManager::ReleaseIconResource(int32_t userId)
539 {
540     AutoMutex mutex(this->lockIcon_);
541     ChangeIconResourceStatus(userId);
542     ClearIconResource();
543 }
544 } // namespace Resource
545 } // namespace Global
546 } // namespace OHOS
547