• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "hap_manager.h"
16 
17 #include <algorithm>
18 #include <fstream>
19 #include <climits>
20 #include <cstdlib>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <tuple>
24 #include <set>
25 #include "utils/errors.h"
26 #ifdef SUPPORT_GRAPHICS
27 #include <ohos/init_data.h>
28 #include <unicode/unistr.h>
29 #include <unicode/utypes.h>
30 #endif
31 
32 #include "hilog_wrapper.h"
33 
34 #include "hap_parser.h"
35 #include "utils/utils.h"
36 #include "res_common.h"
37 
38 #ifdef __WINNT__
39 #include <shlwapi.h>
40 #include <windows.h>
41 #else
42 #include <dlfcn.h>
43 #endif
44 
45 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
46 #include "hitrace_meter.h"
47 #include "hisysevent_adapter.h"
48 #include "file_mapper.h"
49 #include "extractor.h"
50 #endif
51 
52 namespace OHOS {
53 namespace Global {
54 namespace Resource {
55 #ifdef SUPPORT_GRAPHICS
56 constexpr uint32_t PLURAL_CACHE_MAX_COUNT = 3;
57 #endif
58 #if defined(__ARKUI_CROSS__)
59 const std::string RAW_FILE_PATH = "resources/rawfile/";
60 #endif
61 
62 using ReadLock = std::shared_lock<std::shared_mutex>;
63 using WriteLock = std::unique_lock<std::shared_mutex>;
64 
65 std::mutex g_rawFileLock;
66 
HapManager(std::shared_ptr<ResConfigImpl> resConfig,bool isSystem)67 HapManager::HapManager(std::shared_ptr<ResConfigImpl> resConfig, bool isSystem)
68     : resConfig_(resConfig), isSystem_(isSystem)
69 {
70     overrideResConfig_->SetColorMode(COLOR_MODE_NOT_SET);
71 }
72 
73 bool HapManager::icuInitialized = HapManager::Init();
74 
Init()75 bool HapManager::Init()
76 {
77 #ifdef SUPPORT_GRAPHICS
78 #ifdef __IDE_PREVIEW__
79 #ifdef __WINNT__
80     MEMORY_BASIC_INFORMATION mbi;
81     if (::VirtualQuery((LPCVOID)SetHwIcuDirectory, &mbi, sizeof(mbi)) != 0) {
82         char path[MAX_PATH] = { 0 };
83         GetModuleFileName((HMODULE)mbi.AllocationBase, path, MAX_PATH);
84         std::string tempPath(path);
85         auto pos = tempPath.rfind('\\');
86         if (pos != std::string::npos) {
87             u_setDataDirectory(tempPath.substr(0, pos).c_str());
88         }
89     }
90 #else
91     Dl_info info;
92     if (dladdr((void*)SetHwIcuDirectory, &info) != 0) {
93         std::string tempPath(info.dli_fname);
94         auto pos = tempPath.rfind('/');
95         if (pos != std::string::npos) {
96             u_setDataDirectory(tempPath.substr(0, pos).c_str());
97         }
98     }
99 #endif
100 #else
101 #if !defined(__ARKUI_CROSS__)
102     SetHwIcuDirectory();
103 #endif
104 #endif
105 #endif
106     return true;
107 }
108 
GetPluralRulesAndSelect(int quantity,bool isGetOverrideResource)109 std::string HapManager::GetPluralRulesAndSelect(int quantity, bool isGetOverrideResource)
110 {
111     std::string defaultRet("other");
112 #ifdef SUPPORT_GRAPHICS
113     WriteLock lock(this->mutex_);
114     std::shared_ptr<ResConfigImpl> config = getCompleteOverrideConfig(isGetOverrideResource);
115     if (config == nullptr || config->GetResLocale() == nullptr ||
116         config->GetResLocale()->GetLanguage() == nullptr) {
117         RESMGR_HILOGE(RESMGR_TAG, "GetPluralRules language is null!");
118         return defaultRet;
119     }
120     std::string language = config->GetResLocale()->GetLanguage();
121 
122     icu::PluralRules *pluralRules = nullptr;
123     for (uint32_t i = 0; i < plurRulesCache_.size(); i++) {
124         auto pair = plurRulesCache_[i];
125         if (language == pair.first) {
126             // cache hit
127             pluralRules = pair.second;
128             break;
129         }
130     }
131 
132     if (pluralRules == nullptr) {
133         // no cache hit
134         icu::Locale locale(language.c_str());
135         if (locale.isBogus()) {
136             RESMGR_HILOGE(RESMGR_TAG, "icu::Locale init error : %s", language.c_str());
137             return defaultRet;
138         }
139         UErrorCode status = U_ZERO_ERROR;
140         pluralRules = icu::PluralRules::forLocale(locale, status);
141         if (status != U_ZERO_ERROR) {
142             RESMGR_HILOGE(RESMGR_TAG, "icu::PluralRules::forLocale error : %d", status);
143             return defaultRet;
144         }
145         // after PluralRules created, we add it to cache, if > 3 delete oldest one
146         if (plurRulesCache_.size() >= PLURAL_CACHE_MAX_COUNT) {
147             RESMGR_HILOGD(RESMGR_TAG, "cache rotate delete plurRulesMap_ %s", plurRulesCache_[0].first.c_str());
148             delete (plurRulesCache_[0].second);
149             plurRulesCache_.erase(plurRulesCache_.begin());
150         }
151         auto plPair = std::make_pair(language, pluralRules);
152         plurRulesCache_.push_back(plPair);
153     }
154     std::string converted;
155     icu::UnicodeString us = pluralRules->select(quantity);
156     us.toUTF8String(converted);
157     return converted;
158 #else
159     return defaultRet;
160 #endif
161 }
162 
FindResourceById(uint32_t id,bool isGetOverrideResource)163 const std::shared_ptr<IdItem> HapManager::FindResourceById(uint32_t id, bool isGetOverrideResource)
164 {
165     auto qualifierValue = FindQualifierValueById(id, isGetOverrideResource);
166     if (qualifierValue == nullptr) {
167         return nullptr;
168     }
169     return qualifierValue->GetIdItem();
170 }
171 
FindResourceByName(const char * name,const ResType resType,bool isGetOverrideResource)172 const std::shared_ptr<IdItem> HapManager::FindResourceByName(
173     const char *name, const ResType resType, bool isGetOverrideResource)
174 {
175     auto qualifierValue = FindQualifierValueByName(name, resType, isGetOverrideResource);
176     if (qualifierValue == nullptr) {
177         return nullptr;
178     }
179     return qualifierValue->GetIdItem();
180 }
181 
FindQualifierValueByName(const char * name,const ResType resType,bool isGetOverrideResource,uint32_t density)182 const std::shared_ptr<HapResource::ValueUnderQualifierDir> HapManager::FindQualifierValueByName(
183     const char *name, const ResType resType, bool isGetOverrideResource, uint32_t density)
184 {
185     ReadLock lock(this->mutex_);
186     std::vector<std::shared_ptr<HapResource::IdValues>> candidates = this->GetResourceListByName(name, resType);
187     if (candidates.size() == 0) {
188         return nullptr;
189     }
190     return this->GetBestMatchResource(candidates, density, isGetOverrideResource);
191 }
192 
FindQualifierValueById(uint32_t id,bool isGetOverrideResource,uint32_t density)193 const std::shared_ptr<HapResource::ValueUnderQualifierDir> HapManager::FindQualifierValueById(uint32_t id,
194     bool isGetOverrideResource, uint32_t density)
195 {
196     ReadLock lock(this->mutex_);
197     std::vector<std::shared_ptr<HapResource::IdValues>> candidates = this->GetResourceList(id);
198     if (candidates.size() == 0) {
199         return nullptr;
200     }
201     return this->GetBestMatchResource(candidates, density, isGetOverrideResource);
202 }
203 
getCompleteOverrideConfig(bool isGetOverrideResource)204 std::shared_ptr<ResConfigImpl> HapManager::getCompleteOverrideConfig(bool isGetOverrideResource)
205 {
206     if (!isGetOverrideResource) {
207         return this->resConfig_;
208     }
209 
210     std::shared_ptr<ResConfigImpl> completeOverrideConfig = std::make_shared<ResConfigImpl>();
211     if (!completeOverrideConfig || !this->resConfig_ || !this->overrideResConfig_) {
212         RESMGR_HILOGE(RESMGR_TAG, "completeOverrideConfig or resConfig_ or overrideResConfig_ is nullptr");
213         return nullptr;
214     }
215 
216     if (!completeOverrideConfig->Copy(*this->resConfig_, true)) {
217         RESMGR_HILOGE(RESMGR_TAG, "getCompleteOverrideConfig copy failed");
218         return nullptr;
219     }
220 
221     if (this->overrideResConfig_->isLocaleInfoSet()
222         && !completeOverrideConfig->CopyLocaleAndPreferredLocale(*this->overrideResConfig_)) {
223         RESMGR_HILOGE(RESMGR_TAG, "getCompleteOverrideConfig CopyLocaleAndPreferredLocale failed");
224         return nullptr;
225     }
226     if (this->overrideResConfig_->GetDeviceType() != DEVICE_NOT_SET) {
227         completeOverrideConfig->SetDeviceType(this->overrideResConfig_->GetDeviceType());
228     }
229     if (this->overrideResConfig_->GetDirection() != DIRECTION_NOT_SET) {
230         completeOverrideConfig->SetDirection(this->overrideResConfig_->GetDirection());
231     }
232     if (this->overrideResConfig_->GetColorMode() != COLOR_MODE_NOT_SET) {
233         completeOverrideConfig->SetColorMode(this->overrideResConfig_->GetColorMode());
234     }
235     if (this->overrideResConfig_->GetInputDevice() != INPUTDEVICE_NOT_SET) {
236         completeOverrideConfig->SetInputDevice(this->overrideResConfig_->GetInputDevice());
237     }
238     if (this->overrideResConfig_->GetMcc() != MCC_UNDEFINED) {
239         completeOverrideConfig->SetMcc(this->overrideResConfig_->GetMcc());
240     }
241     if (this->overrideResConfig_->GetMnc() != MNC_UNDEFINED) {
242         completeOverrideConfig->SetMnc(this->overrideResConfig_->GetMnc());
243     }
244     if (this->overrideResConfig_->GetScreenDensity() != SCREEN_DENSITY_NOT_SET) {
245         completeOverrideConfig->SetScreenDensity(this->overrideResConfig_->GetScreenDensity());
246     }
247     return completeOverrideConfig;
248 }
249 
MatchBestResource(std::shared_ptr<ResConfigImpl> & bestResConfig,std::shared_ptr<HapResource::ValueUnderQualifierDir> & result,const std::vector<std::shared_ptr<HapResource::ValueUnderQualifierDir>> & paths,uint32_t density,std::shared_ptr<ResConfigImpl> currentResConfig)250 void HapManager::MatchBestResource(std::shared_ptr<ResConfigImpl> &bestResConfig,
251     std::shared_ptr<HapResource::ValueUnderQualifierDir> &result,
252     const std::vector<std::shared_ptr<HapResource::ValueUnderQualifierDir>> &paths,
253     uint32_t density, std::shared_ptr<ResConfigImpl> currentResConfig)
254 {
255     size_t len = paths.size();
256     size_t i = 0;
257     for (i = 0; i < len; i++) {
258         std::shared_ptr<HapResource::ValueUnderQualifierDir> path = paths[i];
259         const auto resConfig = path->GetResConfig();
260         if (!currentResConfig->Match(resConfig)) {
261             continue;
262         }
263         if (bestResConfig == nullptr) {
264             bestResConfig = resConfig;
265             result = paths[i];
266             continue;
267         }
268         if (!bestResConfig->IsMoreSuitable(resConfig, currentResConfig, density)) {
269             bestResConfig = resConfig;
270             result = paths[i];
271         }
272     }
273 }
274 
GetBestMatchResource(const std::vector<std::shared_ptr<HapResource::IdValues>> & candidates,uint32_t density,bool isGetOverrideResource)275 const std::shared_ptr<HapResource::ValueUnderQualifierDir> HapManager::GetBestMatchResource(
276     const std::vector<std::shared_ptr<HapResource::IdValues>> &candidates, uint32_t density, bool isGetOverrideResource)
277 {
278     std::shared_ptr<ResConfigImpl> bestResConfig = nullptr;
279     std::shared_ptr<ResConfigImpl> bestOverlayResConfig = nullptr;
280     std::shared_ptr<HapResource::ValueUnderQualifierDir> result = nullptr;
281     std::shared_ptr<HapResource::ValueUnderQualifierDir> overlayResult = nullptr;
282     const std::shared_ptr<ResConfigImpl> currentResConfig = getCompleteOverrideConfig(isGetOverrideResource);
283     if (!currentResConfig) {
284         return nullptr;
285     }
286     // When there are multiple overlays, reverse the search to find the first match resource.
287     for (auto iter = candidates.rbegin(); iter != candidates.rend(); iter++) {
288         const auto &paths = (*iter)->GetLimitPathsConst();
289         bool isOverlayHapResource = paths[0]->IsOverlay();
290         if (isOverlayHapResource) {
291             MatchBestResource(bestOverlayResConfig, overlayResult, paths, density, currentResConfig);
292         } else {
293             MatchBestResource(bestResConfig, result, paths, density, currentResConfig);
294         }
295     }
296     if (bestOverlayResConfig != nullptr && result != nullptr) {
297         if (bestOverlayResConfig->IsMoreSuitable(bestResConfig, currentResConfig, density)) {
298             return overlayResult;
299         }
300     }
301     return result;
302 }
303 
FindRawFile(const std::string & name,std::string & outValue)304 RState HapManager::FindRawFile(const std::string &name, std::string &outValue)
305 {
306 #ifdef __WINNT__
307     char seperator = '\\';
308 #else
309     char seperator = '/';
310 #endif
311     ReadLock lock(this->mutex_);
312     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
313         std::string indexPath = (*iter)->GetIndexPath();
314         auto index = indexPath.rfind(seperator);
315         if (index == std::string::npos) {
316             RESMGR_HILOGE(RESMGR_TAG, "index path format error, %s", indexPath.c_str());
317             continue;
318         }
319         std::string resourcesIndexPath = indexPath.substr(0, index);
320         char tmpPath[PATH_MAX] = {0};
321         std::string tempName = name;
322         const std::string rawFileDirName = "rawfile/";
323         if (tempName.length() <= rawFileDirName.length()
324             || (tempName.compare(0, rawFileDirName.length(), rawFileDirName) != 0)) {
325             tempName = rawFileDirName + tempName;
326         }
327 #ifdef __WINNT__
328         if (!PathCanonicalizeA(tmpPath, (resourcesIndexPath + "/resources/" + tempName).c_str())) {
329             continue;
330         }
331 #else
332         if (realpath((resourcesIndexPath + "/resources/" + tempName).c_str(), tmpPath) == nullptr) {
333             RESMGR_HILOGE(RESMGR_TAG, "FindRawFile path to realpath error");
334             continue;
335         }
336 #endif
337         const std::string realPath = tmpPath;
338         std::fstream inputFile;
339         inputFile.open(realPath, std::ios::in);
340         if (inputFile) {
341             outValue = realPath;
342             return SUCCESS;
343         }
344     }
345     return ERROR_CODE_RES_PATH_INVALID;
346 }
347 
UpdateResConfig(ResConfig & resConfig)348 RState HapManager::UpdateResConfig(ResConfig &resConfig)
349 {
350     WriteLock lock(this->mutex_);
351     this->resConfig_->Copy(resConfig);
352     return SUCCESS;
353 }
354 
UpdateOverrideResConfig(ResConfig & resConfig)355 RState HapManager::UpdateOverrideResConfig(ResConfig &resConfig)
356 {
357     WriteLock lock(this->mutex_);
358     this->overrideResConfig_->Copy(resConfig);
359     return SUCCESS;
360 }
361 
GetResConfig(ResConfig & resConfig)362 void HapManager::GetResConfig(ResConfig &resConfig)
363 {
364     ReadLock lock(this->mutex_);
365     resConfig.Copy(*(this->resConfig_), true);
366 }
367 
GetOverrideResConfig(ResConfig & resConfig)368 void HapManager::GetOverrideResConfig(ResConfig &resConfig)
369 {
370     ReadLock lock(this->mutex_);
371     resConfig.Copy(*(this->overrideResConfig_));
372 }
373 
AddResource(const char * path,const uint32_t & selectedTypes)374 bool HapManager::AddResource(const char *path, const uint32_t &selectedTypes)
375 {
376     WriteLock lock(this->mutex_);
377     return this->AddResourcePath(path, selectedTypes);
378 }
379 
AddResource(const std::string & path,const std::vector<std::string> & overlayPaths)380 bool HapManager::AddResource(const std::string &path, const std::vector<std::string> &overlayPaths)
381 {
382     WriteLock lock(this->mutex_);
383     std::vector<std::string> targetOverlay = loadedHapPaths_[path];
384     if (!targetOverlay.empty() && targetOverlay == overlayPaths) {
385         RESMGR_HILOGI(RESMGR_TAG, "the overlay for %{public}s already been loaded", path.c_str());
386         return true;
387     }
388     loadedHapPaths_[path] = overlayPaths;
389     std::unordered_map<std::string, std::shared_ptr<HapResource>> result = HapResource::LoadOverlays(path, overlayPaths,
390         resConfig_, isSystem_);
391     if (result.size() > 0) {
392         for (auto iter = result.begin(); iter != result.end(); iter++) {
393             this->hapResources_.push_back(iter->second);
394         }
395         return true;
396     }
397     return false;
398 }
399 
GetValidAppPath()400 std::string HapManager::GetValidAppPath()
401 {
402     std::string appPath;
403     ReadLock lock(this->mutex_);
404     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
405         const std::string tempPath = (*iter)->GetIndexPath();
406         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
407             continue;
408         }
409         appPath = tempPath;
410     }
411     return appPath;
412 }
413 
AddAppOverlay(const std::string & overlayPath)414 bool HapManager::AddAppOverlay(const std::string &overlayPath)
415 {
416     RESMGR_HILOGI(RESMGR_TAG, "AddAppOverlay overlayPath = %{public}s", overlayPath.c_str());
417     char outPath[PATH_MAX + 1] = {0};
418     Utils::CanonicalizePath(overlayPath.c_str(), outPath, PATH_MAX);
419     if (outPath[0] == '\0') {
420         RESMGR_HILOGE(RESMGR_TAG, "invalid overlayPath, %{public}s", overlayPath.c_str());
421         return false;
422     }
423     std::vector<std::string> overlayPaths;
424     overlayPaths.emplace_back(outPath);
425     std::string appPath = GetValidAppPath();
426     return AddResource(appPath, overlayPaths);
427 }
428 
RemoveAppOverlay(const std::string & overlayPath)429 bool HapManager::RemoveAppOverlay(const std::string &overlayPath)
430 {
431     RESMGR_HILOGI(RESMGR_TAG, "RemoveAppOverlay overlayPath = %{public}s", overlayPath.c_str());
432     char outPath[PATH_MAX + 1] = {0};
433     Utils::CanonicalizePath(overlayPath.c_str(), outPath, PATH_MAX);
434     if (outPath[0] == '\0') {
435         RESMGR_HILOGE(RESMGR_TAG, "invalid overlayPath, %{public}s", overlayPath.c_str());
436         return false;
437     }
438     std::vector<std::string> overlayPaths;
439     overlayPaths.emplace_back(outPath);
440     std::string appPath = GetValidAppPath();
441     return RemoveResource(appPath, overlayPaths);
442 }
443 
~HapManager()444 HapManager::~HapManager()
445 {
446 #ifdef SUPPORT_GRAPHICS
447     auto iter = plurRulesCache_.begin();
448     for (; iter != plurRulesCache_.end(); iter++) {
449         RESMGR_HILOGD(RESMGR_TAG, "delete plurRulesMap_ %s", iter->first.c_str());
450         if (iter->second != nullptr) {
451             auto ptr = iter->second;
452             delete (ptr);
453             iter->second = nullptr;
454         }
455     }
456 #endif
457 }
458 
GetResourceList(uint32_t ident) const459 std::vector<std::shared_ptr<HapResource::IdValues>> HapManager::GetResourceList(uint32_t ident) const
460 {
461     std::vector<std::shared_ptr<HapResource::IdValues>> result;
462     // one id only exit in one hap
463     for (size_t i = 0; i < hapResources_.size(); ++i) {
464         std::shared_ptr<HapResource> pResource = hapResources_[i];
465         const std::shared_ptr<HapResource::IdValues>out = pResource->GetIdValues(ident);
466         if (out != nullptr) {
467             result.emplace_back(out);
468         }
469     }
470     return result;
471 }
472 
GetResourceListByName(const char * name,const ResType resType) const473 std::vector<std::shared_ptr<HapResource::IdValues>> HapManager::GetResourceListByName(const char *name,
474     const ResType resType) const
475 {
476     std::vector<std::shared_ptr<HapResource::IdValues>> result;
477     // all match will return
478     for (size_t i = 0; i < hapResources_.size(); ++i) {
479         std::shared_ptr<HapResource> pResource = hapResources_[i];
480         const std::shared_ptr<HapResource::IdValues> out = pResource->GetIdValuesByName(std::string(name), resType);
481         if (out != nullptr) {
482             result.emplace_back(out);
483         }
484     }
485     return result;
486 }
487 
AddResourcePath(const char * path,const uint32_t & selectedTypes)488 bool HapManager::AddResourcePath(const char *path, const uint32_t &selectedTypes)
489 {
490     std::string sPath(path);
491     auto it = loadedHapPaths_.find(sPath);
492     if (it != loadedHapPaths_.end()) {
493         return false;
494     }
495     const std::shared_ptr<HapResource> pResource = HapResource::Load(path, resConfig_, isSystem_, false, selectedTypes);
496     if (pResource == nullptr) {
497         return false;
498     }
499     this->hapResources_.push_back(pResource);
500     this->loadedHapPaths_[sPath] = std::vector<std::string>();
501     return true;
502 }
503 
ReloadAll()504 RState HapManager::ReloadAll()
505 {
506     WriteLock lock(this->mutex_);
507     if (hapResources_.size() == 0) {
508         return SUCCESS;
509     }
510     std::vector<std::shared_ptr<HapResource>> newResources;
511     for (auto iter = loadedHapPaths_.begin(); iter != loadedHapPaths_.end(); iter++) {
512         std::vector<std::string> &overlayPaths = iter->second;
513         if (overlayPaths.size() == 0) {
514             const auto pResource = HapResource::Load(iter->first.c_str(), resConfig_);
515             if (pResource == nullptr) {
516                 newResources.clear();
517                 return HAP_INIT_FAILED;
518             }
519             newResources.push_back(pResource);
520             continue;
521         }
522         std::unordered_map<std::string, std::shared_ptr<HapResource>> result = HapResource::LoadOverlays(
523             iter->first.c_str(), overlayPaths, resConfig_);
524         if (result.size() == 0) {
525             continue;
526         }
527         for (auto iter = result.begin(); iter != result.end(); iter++) {
528             newResources.push_back(iter->second);
529         }
530     }
531     hapResources_.clear();
532     hapResources_ = newResources;
533     return SUCCESS;
534 }
535 
GetResourcePaths()536 std::vector<std::string> HapManager::GetResourcePaths()
537 {
538     std::vector<std::string> result;
539     ReadLock lock(this->mutex_);
540     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
541         std::string indexPath = (*iter)->GetIndexPath();
542         auto index = indexPath.rfind('/');
543         if (index == std::string::npos) {
544             RESMGR_HILOGE(RESMGR_TAG, "index path format error, %s", indexPath.c_str());
545             continue;
546         }
547 
548         result.emplace_back(indexPath.substr(0, index) + "/resources/");
549     }
550 
551     return result;
552 }
553 
GetImageType(const std::string fileName)554 std::string GetImageType(const std::string fileName)
555 {
556     auto pos = fileName.find_last_of('.');
557     std::string imgType;
558     if (pos != std::string::npos) {
559         imgType = fileName.substr(pos + 1);
560     }
561     return imgType;
562 }
563 
564 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
GetFilePathFromHap(std::shared_ptr<AbilityBase::Extractor> & extractor,const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,const ResType resType)565 std::string GetFilePathFromHap(std::shared_ptr<AbilityBase::Extractor> &extractor,
566     const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, const ResType resType)
567 {
568     std::string filePath;
569     const std::shared_ptr<IdItem> idItem = qd->GetIdItem();
570     if (idItem == nullptr || idItem->resType_ != resType) {
571         std::string hapPath = qd->GetIndexPath();
572         RESMGR_HILOGE(RESMGR_TAG, "actual resType = %{public}d, expect resType = %{public}d, hapPath = %{public}s",
573             idItem == nullptr ? -1 : idItem->resType_, resType, hapPath.c_str());
574         return filePath;
575     }
576     if (extractor->IsStageModel()) {
577         std::string tempFilePath(idItem->value_);
578         auto index = tempFilePath.find('/');
579         if (index == std::string::npos) {
580             RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", tempFilePath.c_str());
581             return filePath;
582         }
583         filePath = idItem->value_.substr(index + 1);
584     } else {
585         // FA mode
586         std::string tempFilePath("assets/");
587         tempFilePath.append(idItem->value_);
588         filePath = tempFilePath;
589     }
590     return filePath;
591 }
592 
GetAbilityExtractor(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd)593 std::shared_ptr<AbilityBase::Extractor> GetAbilityExtractor(
594     const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd)
595 {
596     std::string hapPath = qd->GetIndexPath();
597     bool isNewExtractor = false;
598     auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
599     return extractor;
600 }
601 #endif
602 
GetProfileData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)603 RState HapManager::GetProfileData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
604     std::unique_ptr<uint8_t[]> &outValue)
605 {
606 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
607     auto extractor = GetAbilityExtractor(qd);
608     if (extractor == nullptr) {
609         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
610         return NOT_FOUND;
611     }
612     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::PROF);
613     if (filePath.empty()) {
614         RESMGR_HILOGE(RESMGR_TAG, "get file path failed in GetProfileData");
615         return NOT_FOUND;
616     }
617     bool ret = extractor->ExtractToBufByName(filePath, outValue, len);
618     if (!ret) {
619         RESMGR_HILOGE(RESMGR_TAG, "failed to get config data from ability");
620         return NOT_FOUND;
621     }
622 #endif
623     return SUCCESS;
624 }
625 
GetMediaData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)626 RState HapManager::GetMediaData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
627     std::unique_ptr<uint8_t[]> &outValue)
628 {
629     std::string filePath = qd->GetIndexPath();
630     RState state;
631     if (Utils::ContainsTail(filePath, Utils::tailSet)) {
632         state = HapManager::GetMediaDataFromHap(qd, len, outValue);
633     } else {
634         state = HapManager::GetMediaDataFromIndex(qd, len, outValue);
635     }
636     return state;
637 }
638 
GetMediaDataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)639 RState HapManager::GetMediaDataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
640     std::unique_ptr<uint8_t[]> &outValue)
641 {
642 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
643     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
644     auto extractor = GetAbilityExtractor(qd);
645     if (extractor == nullptr) {
646         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
647         return NOT_FOUND;
648     }
649     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::MEDIA);
650     if (filePath.empty()) {
651         RESMGR_HILOGE(RESMGR_TAG, "get file path failed in GetMediaDataFromHap");
652         return NOT_FOUND;
653     }
654     bool ret = extractor->ExtractToBufByName(filePath, outValue, len);
655     if (!ret) {
656         RESMGR_HILOGE(RESMGR_TAG, "failed to get media data from ability");
657         return NOT_FOUND;
658     }
659 #endif
660     return SUCCESS;
661 }
662 
GetMediaDataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)663 RState HapManager::GetMediaDataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
664     std::unique_ptr<uint8_t[]> &outValue)
665 {
666     std::string filePath;
667     RState state = HapManager::GetFilePath(qd, ResType::MEDIA, filePath);
668     if (state != SUCCESS) {
669         return NOT_FOUND;
670     }
671     outValue = Utils::LoadResourceFile(filePath, len);
672     return SUCCESS;
673 }
674 
GetMediaBase64Data(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)675 RState HapManager::GetMediaBase64Data(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
676     std::string &outValue)
677 {
678     std::string filePath = qd->GetIndexPath();
679     RState state;
680     if (Utils::ContainsTail(filePath, Utils::tailSet)) {
681         state = HapManager::GetMediaBase64DataFromHap(qd, outValue);
682     } else {
683         state = HapManager::GetMediaBase64DataFromIndex(qd, outValue);
684     }
685     return state;
686 }
687 
GetMediaBase64DataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)688 RState HapManager::GetMediaBase64DataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
689     std::string &outValue)
690 {
691 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
692     auto extractor = GetAbilityExtractor(qd);
693     if (extractor == nullptr) {
694         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
695         return NOT_FOUND;
696     }
697     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::MEDIA);
698     std::unique_ptr<uint8_t[]> buffer;
699     size_t tmpLen;
700     bool ret = extractor->ExtractToBufByName(filePath, buffer, tmpLen);
701     if (!ret) {
702         RESMGR_HILOGE(RESMGR_TAG, "failed to get mediabase64 data from ability");
703         return NOT_FOUND;
704     }
705     std::string imgType = GetImageType(filePath);
706     Utils::EncodeBase64(buffer, tmpLen, imgType, outValue);
707 #endif
708     return SUCCESS;
709 }
710 
GetMediaBase64DataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)711 RState HapManager::GetMediaBase64DataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
712     std::string &outValue)
713 {
714     std::string filePath;
715     RState state = HapManager::GetFilePath(qd, ResType::MEDIA, filePath);
716     if (state != SUCCESS) {
717         return NOT_FOUND;
718     }
719     return Utils::GetMediaBase64Data(filePath, outValue);
720 }
721 
GetValidHapPath(std::string & hapPath)722 int32_t HapManager::GetValidHapPath(std::string &hapPath)
723 {
724     ReadLock lock(this->mutex_);
725     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
726         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
727             continue;
728         }
729         const std::string tempPath = (*iter)->GetIndexPath();
730         if (Utils::ContainsTail(tempPath, Utils::tailSet)) {
731             hapPath = tempPath;
732             return OK;
733         }
734     }
735     return NOT_FOUND;
736 }
737 
GetValidIndexPath(std::string & indexPath)738 int32_t HapManager::GetValidIndexPath(std::string &indexPath)
739 {
740     ReadLock lock(this->mutex_);
741     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
742         const std::string tempPath = (*iter)->GetIndexPath();
743         if (Utils::endWithTail(tempPath, "/systemres/resources.index")) {
744             continue;
745         }
746         indexPath = tempPath;
747         return OK;
748     }
749     return NOT_FOUND;
750 }
751 
FindRawFileFromHap(const std::string & rawFileName,size_t & len,std::unique_ptr<uint8_t[]> & outValue)752 RState HapManager::FindRawFileFromHap(const std::string &rawFileName, size_t &len,
753     std::unique_ptr<uint8_t[]> &outValue)
754 {
755     ReadLock lock(this->mutex_);
756     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
757         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
758             continue;
759         }
760         const std::string tempPath = (*iter)->GetIndexPath();
761         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
762             RState state = HapParser::ReadRawFileFromHap(tempPath, rawFileName, len, outValue);
763             if (state != SUCCESS) {
764                 continue;
765             }
766         } else { // if file path is uncompressed
767             std::string filePath;
768             HapManager::FindRawFile(rawFileName, filePath);
769             outValue = Utils::LoadResourceFile(filePath, len);
770             if (outValue == nullptr) {
771                 continue;
772             }
773         }
774         return SUCCESS;
775     }
776     return ERROR_CODE_RES_PATH_INVALID;
777 }
778 
FindRawFileDescriptorFromHap(const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)779 RState HapManager::FindRawFileDescriptorFromHap(const std::string &rawFileName,
780     ResourceManager::RawFileDescriptor &descriptor)
781 {
782     std::lock_guard<std::mutex> lock(g_rawFileLock);
783     auto it = rawFileDescriptor_.find(rawFileName);
784     if (it != rawFileDescriptor_.end()) {
785         descriptor.fd = rawFileDescriptor_[rawFileName].fd;
786         descriptor.length = rawFileDescriptor_[rawFileName].length;
787         descriptor.offset = rawFileDescriptor_[rawFileName].offset;
788         return SUCCESS;
789     }
790     RState state = GetRawFd(rawFileName, descriptor);
791     if (state == SUCCESS) {
792         rawFileDescriptor_[rawFileName] = descriptor;
793     }
794     return state;
795 }
796 
GetRawFd(const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)797 RState HapManager::GetRawFd(const std::string &rawFileName, ResourceManager::RawFileDescriptor &descriptor)
798 {
799     RState state;
800     ReadLock lock(this->mutex_);
801     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
802         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
803             continue;
804         }
805         const std::string tempPath = (*iter)->GetIndexPath();
806         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
807             state = HapParser::ReadRawFileDescriptor(tempPath.c_str(), rawFileName, descriptor);
808         } else { // if file path is uncompressed
809             state = HapManager::FindRawFileDescriptor(rawFileName, descriptor);
810         }
811         if (state != SUCCESS) {
812             continue;
813         }
814         return SUCCESS;
815     }
816     return ERROR_CODE_RES_PATH_INVALID;
817 }
818 
GetRawFileList(const std::string & rawDirPath,std::vector<std::string> & fileList)819 RState HapManager::GetRawFileList(const std::string &rawDirPath, std::vector<std::string> &fileList)
820 {
821     std::string hapOrIndexPath;
822     if (HapManager::GetValidHapPath(hapOrIndexPath) == OK) {
823         return HapParser::GetRawFileList(hapOrIndexPath, rawDirPath, fileList);
824     }
825     if (HapManager::GetValidIndexPath(hapOrIndexPath) == OK) {
826         return  HapParser::GetRawFileListUnCompressed(hapOrIndexPath, rawDirPath, fileList);
827     }
828     return ERROR_CODE_RES_PATH_INVALID;
829 }
830 
IsLoadHap(std::string & hapPath)831 bool HapManager::IsLoadHap(std::string &hapPath)
832 {
833     return HapManager::GetValidHapPath(hapPath) == OK ? true : false;
834 }
835 
GetFilePath(const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd,const ResType resType,std::string & outValue)836 RState HapManager::GetFilePath(const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd, const ResType resType,
837     std::string &outValue)
838 {
839     // not found or type invalid
840     if (vuqd == nullptr) {
841         return NOT_FOUND;
842     }
843     const std::shared_ptr<IdItem> idItem = vuqd->GetIdItem();
844     if (idItem == nullptr || idItem->resType_ != resType) {
845         return NOT_FOUND;
846     }
847     outValue = vuqd->GetResourcePath();
848 #if defined(__ARKUI_CROSS__)
849     auto index = idItem->value_.find('/');
850     if (index == std::string::npos) {
851         RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", idItem->value_.c_str());
852         return NOT_FOUND;
853     }
854     auto nameWithoutModule = idItem->value_.substr(index + 1);
855     outValue.append(nameWithoutModule);
856 #elif defined(__IDE_PREVIEW__)
857     if (Utils::IsFileExist(idItem->value_)) {
858         outValue = idItem->value_;
859         return SUCCESS;
860     }
861     auto index = idItem->value_.find('/');
862     if (index == std::string::npos) {
863         RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", idItem->value_.c_str());
864         return NOT_FOUND;
865     }
866     auto nameWithoutModule = idItem->value_.substr(index + 1);
867     outValue.append(nameWithoutModule);
868 #else
869     outValue.append(idItem->value_);
870 #endif
871     return SUCCESS;
872 }
873 
FindRawFileDescriptor(const std::string & name,ResourceManager::RawFileDescriptor & descriptor)874 RState HapManager::FindRawFileDescriptor(const std::string &name, ResourceManager::RawFileDescriptor &descriptor)
875 {
876     std::string paths = "";
877     RState rState = HapManager::FindRawFile(name, paths);
878     if (rState != SUCCESS) {
879         return rState;
880     }
881     char outPath[PATH_MAX + 1] = {0};
882     Utils::CanonicalizePath(paths.c_str(), outPath, PATH_MAX);
883     int fd = open(outPath, O_RDONLY);
884     if (fd > 0) {
885         long length = lseek(fd, 0, SEEK_END);
886         if (length == -1) {
887             close(fd);
888             return ERROR_CODE_RES_PATH_INVALID;
889         }
890         long begin = lseek(fd, 0, SEEK_SET);
891         if (begin == -1) {
892             close(fd);
893             return ERROR_CODE_RES_PATH_INVALID;
894         }
895         descriptor.fd = fd;
896         descriptor.length = length;
897         descriptor.offset = 0;
898         return SUCCESS;
899     }
900     return ERROR_CODE_RES_PATH_INVALID;
901 }
902 
CloseRawFileDescriptor(const std::string & name)903 RState HapManager::CloseRawFileDescriptor(const std::string &name)
904 {
905     std::lock_guard<std::mutex> lock(g_rawFileLock);
906     auto it = rawFileDescriptor_.find(name);
907     if (it == rawFileDescriptor_.end()) {
908         return ERROR_CODE_RES_PATH_INVALID;
909     }
910     int fd = rawFileDescriptor_[name].fd;
911     if (fd > 0) {
912         int result = close(fd);
913         if (result == -1) {
914             return ERROR_CODE_RES_PATH_INVALID;
915         }
916         rawFileDescriptor_.erase(name);
917         return SUCCESS;
918     }
919     return ERROR_CODE_RES_PATH_INVALID;
920 }
921 
RemoveResource(const std::string & path,const std::vector<std::string> & overlayPaths)922 bool HapManager::RemoveResource(const std::string &path, const std::vector<std::string> &overlayPaths)
923 {
924     WriteLock lock(this->mutex_);
925     RESMGR_HILOGI(RESMGR_TAG, "remove overlay for path, %{public}s", path.c_str());
926     if (loadedHapPaths_.find(path) == loadedHapPaths_.end()) {
927         return false;
928     }
929     std::vector<std::string> targetOverlay = loadedHapPaths_[path];
930     if (targetOverlay.empty()) {
931         RESMGR_HILOGE(RESMGR_TAG, "the %{public}s have not overlay", path.c_str());
932         return false;
933     }
934     char outPath[PATH_MAX] = {0};
935     for (auto iter = overlayPaths.begin(); iter != overlayPaths.end(); iter++) {
936         Utils::CanonicalizePath((*iter).c_str(), outPath, PATH_MAX);
937         if (outPath[0] == '\0') {
938             RESMGR_HILOGE(RESMGR_TAG, "invalid overlayPath, %{public}s", (*iter).c_str());
939             continue;
940         }
941         if (std::find(targetOverlay.begin(), targetOverlay.end(), outPath) != targetOverlay.end()) {
942             targetOverlay.erase(std::remove(targetOverlay.begin(), targetOverlay.end(), outPath),
943                 targetOverlay.end());
944         }
945         for (auto resIter = hapResources_.begin(); resIter != hapResources_.end();) {
946             if ((*resIter) == nullptr) {
947                 RESMGR_HILOGE(RESMGR_TAG, "hapResource is nullptr");
948                 return false;
949             }
950             std::string hapPath = (*resIter)->GetIndexPath();
951             if (hapPath == outPath) {
952                 resIter = hapResources_.erase(resIter);
953             } else {
954                 resIter++;
955             }
956         }
957     }
958     loadedHapPaths_[path] = targetOverlay;
959     return true;
960 }
961 
GetHapResource()962 std::vector<std::shared_ptr<HapResource>> HapManager::GetHapResource()
963 {
964     return hapResources_;
965 }
966 
AddSystemResource(const std::shared_ptr<HapManager> & systemHapManager)967 void HapManager::AddSystemResource(const std::shared_ptr<HapManager> &systemHapManager)
968 {
969     if (systemHapManager == nullptr) {
970         RESMGR_HILOGE(RESMGR_TAG, "add system resource failed, systemHapManager is nullptr");
971         return;
972     }
973     if (!systemHapManager->isSystem_) {
974         RESMGR_HILOGE(RESMGR_TAG, "add system resource failed, the added hapManager is not system");
975         return;
976     }
977     WriteLock lock(this->mutex_);
978     // add system resource to app resource vector
979     const std::vector<std::shared_ptr<HapResource>> &systemResources = systemHapManager->hapResources_;
980     for (size_t i = 0; i < systemResources.size(); i++) {
981         this->hapResources_.push_back(systemResources[i]);
982     }
983 
984     // add system loaded path to app loaded path map.
985     const std::unordered_map<std::string, std::vector<std::string>> &loadedSystemPaths =
986         systemHapManager->loadedHapPaths_;
987     for (auto iter = loadedSystemPaths.begin(); iter != loadedSystemPaths.end(); iter++) {
988         const std::vector<std::string> &overlayPaths = iter->second;
989         if (this->loadedHapPaths_.find(iter->first) == this->loadedHapPaths_.end()) {
990             this->loadedHapPaths_[iter->first] = overlayPaths;
991         }
992     }
993 }
994 
GetResourceLimitKeys()995 uint32_t HapManager::GetResourceLimitKeys()
996 {
997     ReadLock lock(this->mutex_);
998     uint32_t limitKeysValue = 0;
999     for (size_t i = 0; i < hapResources_.size(); i++) {
1000         limitKeysValue |= hapResources_[i]->GetResourceLimitKeys();
1001     }
1002     RESMGR_HILOGD(RESMGR_TAG, "hap manager limit key is %{public}u", limitKeysValue);
1003     return limitKeysValue;
1004 }
1005 
1006 std::unordered_map<std::string, ResType> ResTypeMap {
1007     {"integer", INTEGER},
1008     {"string", STRING},
1009     {"strarray", STRINGARRAY},
1010     {"intarray", INTARRAY},
1011     {"boolean", BOOLEAN},
1012     {"color", COLOR},
1013     {"theme", THEME},
1014     {"plural", PLURALS},
1015     {"float", FLOAT},
1016     {"media", MEDIA},
1017     {"profile", PROF},
1018     {"pattern", PATTERN},
1019 };
1020 
IsPrefix(std::string_view prefix,std::string_view full)1021 bool IsPrefix(std::string_view prefix, std::string_view full)
1022 {
1023     return prefix == full.substr(0, prefix.size());
1024 }
1025 
GetRealResId(const std::string & resType,const std::vector<std::unordered_map<ResType,uint32_t>> & candidates)1026 uint32_t GetRealResId(const std::string &resType,
1027     const std::vector<std::unordered_map<ResType, uint32_t>> &candidates)
1028 {
1029     for (auto candidate : candidates) {
1030         for (auto data : candidate) {
1031             if (ResTypeMap.find(resType) != ResTypeMap.end() && ResTypeMap[resType] == data.first) {
1032                 return data.second;
1033             }
1034         }
1035     }
1036     return 0;
1037 }
1038 
GetResTypeAndResName(const std::string & resTypeName)1039 std::tuple<std::string, std::string> GetResTypeAndResName(const std::string &resTypeName)
1040 {
1041     std::tuple<std::string, std::string> typeNameTuple;
1042     auto pos1 = resTypeName.find('.');
1043     auto pos2 = resTypeName.rfind('.');
1044     if (pos1 == std::string::npos || pos2 == std::string::npos) {
1045         return std::make_tuple("", "");
1046     }
1047     if (pos2 < pos1 + 1) {
1048         return std::make_tuple("", "");
1049     }
1050     const std::string resType = resTypeName.substr(pos1 + 1, pos2 - pos1 - 1);
1051     if (ResTypeMap.find(resType) == ResTypeMap.end()) {
1052         return std::make_tuple("", "");
1053     }
1054     const std::string resName = resTypeName.substr(pos2 + 1);
1055     if (resName.empty()) {
1056         return std::make_tuple("", "");
1057     }
1058     typeNameTuple = std::make_tuple(resType, resName);
1059     return typeNameTuple;
1060 }
1061 
GetResId(const std::string & resTypeName,uint32_t & resId)1062 RState HapManager::GetResId(const std::string &resTypeName, uint32_t &resId)
1063 {
1064     auto typeNameTuple = GetResTypeAndResName(resTypeName);
1065     const std::string resType =  std::get<0>(typeNameTuple);
1066     const std::string resName =  std::get<1>(typeNameTuple);
1067     if (resType.empty() || resName.empty()) {
1068         RESMGR_HILOGE(RESMGR_TAG, "invalid resTypeName = %{public}s", resTypeName.c_str());
1069         return NOT_FOUND;
1070     }
1071     bool isSystem = IsPrefix("sys", resTypeName);
1072     bool isApp = IsPrefix("app", resTypeName);
1073     if (!isSystem && !isApp) {
1074         RESMGR_HILOGE(RESMGR_TAG, "invalid resTypeName = %{public}s", resTypeName.c_str());
1075         return NOT_FOUND;
1076     }
1077     ReadLock lock(this->mutex_);
1078     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1079         bool isSystemResource = (*iter)->IsSystemResource();
1080         bool isOverlayResource = (*iter)->IsOverlayResource();
1081         if (isOverlayResource) {
1082             continue;
1083         }
1084         if (isSystem && !isSystemResource) {
1085             continue;
1086         }
1087         if (isApp && isSystemResource) {
1088             continue;
1089         }
1090         std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> nameTypeIdMap =
1091                 (*iter)->BuildNameTypeIdMapping();
1092         std::vector<std::unordered_map<ResType, uint32_t>> candidates;
1093         for (auto data : nameTypeIdMap) {
1094             if (data.first != resName) {
1095                 continue;
1096             }
1097             candidates.emplace_back(data.second);
1098         }
1099         resId = GetRealResId(resType, candidates);
1100         if (resId == 0) {
1101             RESMGR_HILOGE(RESMGR_TAG,
1102                 "GetResId name = %{public}s, resType = %{public}s", resName.c_str(), resType.c_str());
1103             return NOT_FOUND;
1104         }
1105     }
1106     return SUCCESS;
1107 }
1108 
GetLocales(std::vector<std::string> & outValue,bool includeSystem)1109 void HapManager::GetLocales(std::vector<std::string> &outValue, bool includeSystem)
1110 {
1111     if (isSystem_) {
1112         includeSystem = true;
1113     }
1114     std::set<std::string> result;
1115     ReadLock lock(this->mutex_);
1116     for (size_t i = 0; i < hapResources_.size(); i++) {
1117         hapResources_[i]->GetLocales(result, includeSystem);
1118     }
1119     outValue.assign(result.begin(), result.end());
1120 }
1121 
IsRawDirFromHap(const std::string & pathName,bool & outValue)1122 RState HapManager::IsRawDirFromHap(const std::string &pathName, bool &outValue)
1123 {
1124     ReadLock lock(this->mutex_);
1125     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1126         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
1127             continue;
1128         }
1129         const std::string tempPath = (*iter)->GetIndexPath();
1130         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
1131             RState state = HapParser::IsRawDirFromHap(tempPath.c_str(), pathName, outValue);
1132             if (state != SUCCESS) {
1133                 continue;
1134             }
1135         } else { // if file path is uncompressed
1136 #if !defined(__ARKUI_CROSS__)
1137             RState state = HapParser::IsRawDirUnCompressed(pathName, outValue);
1138             if (state != SUCCESS) {
1139                 continue;
1140             }
1141 #else
1142             const std::string finalPath = (*iter)->GetResourcePath() + RAW_FILE_PATH + pathName;
1143             RState state = HapParser::IsRawDirUnCompressed(finalPath, outValue);
1144             if (state != SUCCESS) {
1145                 continue;
1146             }
1147 #endif
1148         }
1149         return SUCCESS;
1150     }
1151     return ERROR_CODE_RES_PATH_INVALID;
1152 }
1153 
IsThemeSystemResEnableHap()1154 bool HapManager::IsThemeSystemResEnableHap()
1155 {
1156     ReadLock lock(this->mutex_);
1157     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1158         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
1159             continue;
1160         }
1161         if ((*iter)->IsThemeSystemResEnable()) {
1162             return true;
1163         }
1164     }
1165     return false;
1166 }
1167 } // namespace Resource
1168 } // namespace Global
1169 } // namespace OHOS
1170