• 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     WriteLock lock(this->mutex_);
447     hapResources_.clear();
448     loadedHapPaths_.clear();
449 #ifdef SUPPORT_GRAPHICS
450     auto iter = plurRulesCache_.begin();
451     for (; iter != plurRulesCache_.end(); iter++) {
452         RESMGR_HILOGD(RESMGR_TAG, "delete plurRulesMap_ %s", iter->first.c_str());
453         if (iter->second != nullptr) {
454             auto ptr = iter->second;
455             delete (ptr);
456             iter->second = nullptr;
457         }
458     }
459 #endif
460 }
461 
GetResourceList(uint32_t ident) const462 std::vector<std::shared_ptr<HapResource::IdValues>> HapManager::GetResourceList(uint32_t ident) const
463 {
464     std::vector<std::shared_ptr<HapResource::IdValues>> result;
465     // one id only exit in one hap
466     for (size_t i = 0; i < hapResources_.size(); ++i) {
467         std::shared_ptr<HapResource> pResource = hapResources_[i];
468         const std::shared_ptr<HapResource::IdValues>out = pResource->GetIdValues(ident);
469         if (out != nullptr) {
470             result.emplace_back(out);
471         }
472     }
473     return result;
474 }
475 
GetResourceListByName(const char * name,const ResType resType) const476 std::vector<std::shared_ptr<HapResource::IdValues>> HapManager::GetResourceListByName(const char *name,
477     const ResType resType) const
478 {
479     std::vector<std::shared_ptr<HapResource::IdValues>> result;
480     // all match will return
481     if (name == nullptr) {
482         return result;
483     }
484     std::string key(name);
485     for (size_t i = 0; i < hapResources_.size(); ++i) {
486         std::shared_ptr<HapResource> pResource = hapResources_[i];
487         const std::shared_ptr<HapResource::IdValues> out = pResource->GetIdValuesByName(key, resType);
488         if (out != nullptr) {
489             result.emplace_back(out);
490         }
491     }
492     return result;
493 }
494 
AddResourcePath(const char * path,const uint32_t & selectedTypes)495 bool HapManager::AddResourcePath(const char *path, const uint32_t &selectedTypes)
496 {
497     std::string sPath(path);
498     auto it = loadedHapPaths_.find(sPath);
499     if (it != loadedHapPaths_.end()) {
500         return false;
501     }
502     const std::shared_ptr<HapResource> pResource = HapResource::Load(path, resConfig_, isSystem_, false, selectedTypes);
503     if (pResource == nullptr) {
504         return false;
505     }
506     this->hapResources_.push_back(pResource);
507     this->loadedHapPaths_[sPath] = std::vector<std::string>();
508     return true;
509 }
510 
ReloadAll()511 RState HapManager::ReloadAll()
512 {
513     WriteLock lock(this->mutex_);
514     if (hapResources_.size() == 0) {
515         return SUCCESS;
516     }
517     std::vector<std::shared_ptr<HapResource>> newResources;
518     for (auto iter = loadedHapPaths_.begin(); iter != loadedHapPaths_.end(); iter++) {
519         std::vector<std::string> &overlayPaths = iter->second;
520         if (overlayPaths.size() == 0) {
521             const auto pResource = HapResource::Load(iter->first.c_str(), resConfig_);
522             if (pResource == nullptr) {
523                 newResources.clear();
524                 return HAP_INIT_FAILED;
525             }
526             newResources.push_back(pResource);
527             continue;
528         }
529         std::unordered_map<std::string, std::shared_ptr<HapResource>> result = HapResource::LoadOverlays(
530             iter->first.c_str(), overlayPaths, resConfig_);
531         if (result.size() == 0) {
532             continue;
533         }
534         for (auto iter = result.begin(); iter != result.end(); iter++) {
535             newResources.push_back(iter->second);
536         }
537     }
538     hapResources_.clear();
539     hapResources_ = newResources;
540     return SUCCESS;
541 }
542 
GetResourcePaths()543 std::vector<std::string> HapManager::GetResourcePaths()
544 {
545     std::vector<std::string> result;
546     ReadLock lock(this->mutex_);
547     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
548         std::string indexPath = (*iter)->GetIndexPath();
549         auto index = indexPath.rfind('/');
550         if (index == std::string::npos) {
551             RESMGR_HILOGE(RESMGR_TAG, "index path format error, %s", indexPath.c_str());
552             continue;
553         }
554 
555         result.emplace_back(indexPath.substr(0, index) + "/resources/");
556     }
557 
558     return result;
559 }
560 
GetImageType(const std::string fileName)561 std::string GetImageType(const std::string fileName)
562 {
563     auto pos = fileName.find_last_of('.');
564     std::string imgType;
565     if (pos != std::string::npos) {
566         imgType = fileName.substr(pos + 1);
567     }
568     return imgType;
569 }
570 
571 #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)572 std::string GetFilePathFromHap(std::shared_ptr<AbilityBase::Extractor> &extractor,
573     const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, const ResType resType)
574 {
575     std::string filePath;
576     const std::shared_ptr<IdItem> idItem = qd->GetIdItem();
577     if (idItem == nullptr || idItem->resType_ != resType) {
578         std::string hapPath = qd->GetIndexPath();
579         RESMGR_HILOGE(RESMGR_TAG, "actual resType = %{public}d, expect resType = %{public}d, hapPath = %{public}s",
580             idItem == nullptr ? -1 : idItem->resType_, resType, hapPath.c_str());
581         return filePath;
582     }
583     if (extractor->IsStageModel()) {
584         std::string tempFilePath(idItem->value_);
585         auto index = tempFilePath.find('/');
586         if (index == std::string::npos) {
587             RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", tempFilePath.c_str());
588             return filePath;
589         }
590         filePath = idItem->value_.substr(index + 1);
591     } else {
592         // FA mode
593         std::string tempFilePath("assets/");
594         tempFilePath.append(idItem->value_);
595         filePath = tempFilePath;
596     }
597     return filePath;
598 }
599 
GetAbilityExtractor(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd)600 std::shared_ptr<AbilityBase::Extractor> GetAbilityExtractor(
601     const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd)
602 {
603     std::string hapPath = qd->GetIndexPath();
604     bool isNewExtractor = false;
605     auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
606     return extractor;
607 }
608 #endif
609 
GetProfileData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)610 RState HapManager::GetProfileData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
611     std::unique_ptr<uint8_t[]> &outValue)
612 {
613 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
614     auto extractor = GetAbilityExtractor(qd);
615     if (extractor == nullptr) {
616         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
617         return NOT_FOUND;
618     }
619     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::PROF);
620     if (filePath.empty()) {
621         RESMGR_HILOGE(RESMGR_TAG, "get file path failed in GetProfileData");
622         return NOT_FOUND;
623     }
624     bool ret = extractor->ExtractToBufByName(filePath, outValue, len);
625     if (!ret) {
626         RESMGR_HILOGE(RESMGR_TAG, "failed to get config data from ability");
627         return NOT_FOUND;
628     }
629 #endif
630     return SUCCESS;
631 }
632 
GetMediaData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)633 RState HapManager::GetMediaData(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
634     std::unique_ptr<uint8_t[]> &outValue)
635 {
636     std::string filePath = qd->GetIndexPath();
637     RState state;
638     if (Utils::ContainsTail(filePath, Utils::tailSet)) {
639         state = HapManager::GetMediaDataFromHap(qd, len, outValue);
640     } else {
641         state = HapManager::GetMediaDataFromIndex(qd, len, outValue);
642     }
643     return state;
644 }
645 
GetMediaDataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)646 RState HapManager::GetMediaDataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
647     std::unique_ptr<uint8_t[]> &outValue)
648 {
649 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
650     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
651     auto extractor = GetAbilityExtractor(qd);
652     if (extractor == nullptr) {
653         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
654         return NOT_FOUND;
655     }
656     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::MEDIA);
657     if (filePath.empty()) {
658         RESMGR_HILOGE(RESMGR_TAG, "get file path failed in GetMediaDataFromHap");
659         return NOT_FOUND;
660     }
661     bool ret = extractor->ExtractToBufByName(filePath, outValue, len);
662     if (!ret) {
663         RESMGR_HILOGE(RESMGR_TAG, "failed to get media data from ability");
664         return NOT_FOUND;
665     }
666 #endif
667     return SUCCESS;
668 }
669 
GetMediaDataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,size_t & len,std::unique_ptr<uint8_t[]> & outValue)670 RState HapManager::GetMediaDataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd, size_t &len,
671     std::unique_ptr<uint8_t[]> &outValue)
672 {
673     std::string filePath;
674     RState state = HapManager::GetFilePath(qd, ResType::MEDIA, filePath);
675     if (state != SUCCESS) {
676         return NOT_FOUND;
677     }
678     outValue = Utils::LoadResourceFile(filePath, len);
679     return SUCCESS;
680 }
681 
GetMediaBase64Data(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)682 RState HapManager::GetMediaBase64Data(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
683     std::string &outValue)
684 {
685     std::string filePath = qd->GetIndexPath();
686     RState state;
687     if (Utils::ContainsTail(filePath, Utils::tailSet)) {
688         state = HapManager::GetMediaBase64DataFromHap(qd, outValue);
689     } else {
690         state = HapManager::GetMediaBase64DataFromIndex(qd, outValue);
691     }
692     return state;
693 }
694 
GetMediaBase64DataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)695 RState HapManager::GetMediaBase64DataFromHap(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
696     std::string &outValue)
697 {
698 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
699     auto extractor = GetAbilityExtractor(qd);
700     if (extractor == nullptr) {
701         RESMGR_HILOGE(RESMGR_TAG, "failed to get extractor from ability");
702         return NOT_FOUND;
703     }
704     std::string filePath = GetFilePathFromHap(extractor, qd, ResType::MEDIA);
705     std::unique_ptr<uint8_t[]> buffer;
706     size_t tmpLen;
707     bool ret = extractor->ExtractToBufByName(filePath, buffer, tmpLen);
708     if (!ret) {
709         RESMGR_HILOGE(RESMGR_TAG, "failed to get mediabase64 data from ability");
710         return NOT_FOUND;
711     }
712     std::string imgType = GetImageType(filePath);
713     Utils::EncodeBase64(buffer, tmpLen, imgType, outValue);
714 #endif
715     return SUCCESS;
716 }
717 
GetMediaBase64DataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,std::string & outValue)718 RState HapManager::GetMediaBase64DataFromIndex(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd,
719     std::string &outValue)
720 {
721     std::string filePath;
722     RState state = HapManager::GetFilePath(qd, ResType::MEDIA, filePath);
723     if (state != SUCCESS) {
724         return NOT_FOUND;
725     }
726     return Utils::GetMediaBase64Data(filePath, outValue);
727 }
728 
GetValidHapPath(std::string & hapPath)729 int32_t HapManager::GetValidHapPath(std::string &hapPath)
730 {
731     ReadLock lock(this->mutex_);
732     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
733         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
734             continue;
735         }
736         const std::string tempPath = (*iter)->GetIndexPath();
737         if (Utils::ContainsTail(tempPath, Utils::tailSet)) {
738             hapPath = tempPath;
739             return OK;
740         }
741     }
742     return NOT_FOUND;
743 }
744 
GetValidIndexPath(std::string & indexPath)745 int32_t HapManager::GetValidIndexPath(std::string &indexPath)
746 {
747     ReadLock lock(this->mutex_);
748     for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
749         const std::string tempPath = (*iter)->GetIndexPath();
750         if (Utils::endWithTail(tempPath, "/systemres/resources.index")) {
751             continue;
752         }
753         indexPath = tempPath;
754         return OK;
755     }
756     return NOT_FOUND;
757 }
758 
FindRawFileFromHap(const std::string & rawFileName,size_t & len,std::unique_ptr<uint8_t[]> & outValue)759 RState HapManager::FindRawFileFromHap(const std::string &rawFileName, size_t &len,
760     std::unique_ptr<uint8_t[]> &outValue)
761 {
762     ReadLock lock(this->mutex_);
763     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
764         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
765             continue;
766         }
767         const std::string tempPath = (*iter)->GetIndexPath();
768         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
769             RState state = HapParser::ReadRawFileFromHap(tempPath, rawFileName, len, outValue);
770             if (state != SUCCESS) {
771                 continue;
772             }
773         } else { // if file path is uncompressed
774             std::string filePath;
775             HapManager::FindRawFile(rawFileName, filePath);
776             outValue = Utils::LoadResourceFile(filePath, len);
777             if (outValue == nullptr) {
778                 continue;
779             }
780         }
781         return SUCCESS;
782     }
783     return ERROR_CODE_RES_PATH_INVALID;
784 }
785 
FindRawFileDescriptorFromHap(const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)786 RState HapManager::FindRawFileDescriptorFromHap(const std::string &rawFileName,
787     ResourceManager::RawFileDescriptor &descriptor)
788 {
789     std::lock_guard<std::mutex> lock(g_rawFileLock);
790     auto it = rawFileDescriptor_.find(rawFileName);
791     if (it != rawFileDescriptor_.end()) {
792         descriptor.fd = rawFileDescriptor_[rawFileName].fd;
793         descriptor.length = rawFileDescriptor_[rawFileName].length;
794         descriptor.offset = rawFileDescriptor_[rawFileName].offset;
795         return SUCCESS;
796     }
797     RState state = GetRawFd(rawFileName, descriptor);
798     if (state == SUCCESS) {
799         rawFileDescriptor_[rawFileName] = descriptor;
800     }
801     return state;
802 }
803 
GetRawFd(const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)804 RState HapManager::GetRawFd(const std::string &rawFileName, ResourceManager::RawFileDescriptor &descriptor)
805 {
806     RState state;
807     ReadLock lock(this->mutex_);
808     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
809         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
810             continue;
811         }
812         const std::string tempPath = (*iter)->GetIndexPath();
813         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
814             state = HapParser::ReadRawFileDescriptor(tempPath.c_str(), rawFileName, descriptor);
815         } else { // if file path is uncompressed
816             state = HapManager::FindRawFileDescriptor(rawFileName, descriptor);
817         }
818         if (state != SUCCESS) {
819             continue;
820         }
821         return SUCCESS;
822     }
823     return ERROR_CODE_RES_PATH_INVALID;
824 }
825 
GetRawFileList(const std::string & rawDirPath,std::vector<std::string> & fileList)826 RState HapManager::GetRawFileList(const std::string &rawDirPath, std::vector<std::string> &fileList)
827 {
828     std::string hapOrIndexPath;
829     if (HapManager::GetValidHapPath(hapOrIndexPath) == OK) {
830         return HapParser::GetRawFileList(hapOrIndexPath, rawDirPath, fileList);
831     }
832     if (HapManager::GetValidIndexPath(hapOrIndexPath) == OK) {
833         return  HapParser::GetRawFileListUnCompressed(hapOrIndexPath, rawDirPath, fileList);
834     }
835     return ERROR_CODE_RES_PATH_INVALID;
836 }
837 
IsLoadHap(std::string & hapPath)838 bool HapManager::IsLoadHap(std::string &hapPath)
839 {
840     return HapManager::GetValidHapPath(hapPath) == OK ? true : false;
841 }
842 
GetFilePath(const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd,const ResType resType,std::string & outValue)843 RState HapManager::GetFilePath(const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd, const ResType resType,
844     std::string &outValue)
845 {
846     // not found or type invalid
847     if (vuqd == nullptr) {
848         return NOT_FOUND;
849     }
850     const std::shared_ptr<IdItem> idItem = vuqd->GetIdItem();
851     if (idItem == nullptr || idItem->resType_ != resType) {
852         return NOT_FOUND;
853     }
854     outValue = vuqd->GetResourcePath();
855 #if defined(__ARKUI_CROSS__)
856     auto index = idItem->value_.find('/');
857     if (index == std::string::npos) {
858         RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", idItem->value_.c_str());
859         return NOT_FOUND;
860     }
861     auto nameWithoutModule = idItem->value_.substr(index + 1);
862     outValue.append(nameWithoutModule);
863 #elif defined(__IDE_PREVIEW__)
864     if (Utils::IsFileExist(idItem->value_)) {
865         outValue = idItem->value_;
866         return SUCCESS;
867     }
868     auto index = idItem->value_.find('/');
869     if (index == std::string::npos) {
870         RESMGR_HILOGE(RESMGR_TAG, "resource path format error, %s", idItem->value_.c_str());
871         return NOT_FOUND;
872     }
873     auto nameWithoutModule = idItem->value_.substr(index + 1);
874     outValue.append(nameWithoutModule);
875 #else
876     outValue.append(idItem->value_);
877 #endif
878     return SUCCESS;
879 }
880 
FindRawFileDescriptor(const std::string & name,ResourceManager::RawFileDescriptor & descriptor)881 RState HapManager::FindRawFileDescriptor(const std::string &name, ResourceManager::RawFileDescriptor &descriptor)
882 {
883     std::string paths = "";
884     RState rState = HapManager::FindRawFile(name, paths);
885     if (rState != SUCCESS) {
886         return rState;
887     }
888     char outPath[PATH_MAX + 1] = {0};
889     Utils::CanonicalizePath(paths.c_str(), outPath, PATH_MAX);
890     int fd = open(outPath, O_RDONLY);
891     if (fd > 0) {
892         long length = lseek(fd, 0, SEEK_END);
893         if (length == -1) {
894             close(fd);
895             return ERROR_CODE_RES_PATH_INVALID;
896         }
897         long begin = lseek(fd, 0, SEEK_SET);
898         if (begin == -1) {
899             close(fd);
900             return ERROR_CODE_RES_PATH_INVALID;
901         }
902         descriptor.fd = fd;
903         descriptor.length = length;
904         descriptor.offset = 0;
905         return SUCCESS;
906     }
907     return ERROR_CODE_RES_PATH_INVALID;
908 }
909 
CloseRawFileDescriptor(const std::string & name)910 RState HapManager::CloseRawFileDescriptor(const std::string &name)
911 {
912     std::lock_guard<std::mutex> lock(g_rawFileLock);
913     auto it = rawFileDescriptor_.find(name);
914     if (it == rawFileDescriptor_.end()) {
915         return ERROR_CODE_RES_PATH_INVALID;
916     }
917     int fd = rawFileDescriptor_[name].fd;
918     if (fd > 0) {
919         int result = close(fd);
920         if (result == -1) {
921             return ERROR_CODE_RES_PATH_INVALID;
922         }
923         rawFileDescriptor_.erase(name);
924         return SUCCESS;
925     }
926     return ERROR_CODE_RES_PATH_INVALID;
927 }
928 
RemoveResource(const std::string & path,const std::vector<std::string> & overlayPaths)929 bool HapManager::RemoveResource(const std::string &path, const std::vector<std::string> &overlayPaths)
930 {
931     WriteLock lock(this->mutex_);
932     RESMGR_HILOGI(RESMGR_TAG, "remove overlay for path, %{public}s", path.c_str());
933     if (loadedHapPaths_.find(path) == loadedHapPaths_.end()) {
934         return false;
935     }
936     std::vector<std::string> targetOverlay = loadedHapPaths_[path];
937     if (targetOverlay.empty()) {
938         RESMGR_HILOGE(RESMGR_TAG, "the %{public}s have not overlay", path.c_str());
939         return false;
940     }
941     char outPath[PATH_MAX] = {0};
942     for (auto iter = overlayPaths.begin(); iter != overlayPaths.end(); iter++) {
943         Utils::CanonicalizePath((*iter).c_str(), outPath, PATH_MAX);
944         if (outPath[0] == '\0') {
945             RESMGR_HILOGE(RESMGR_TAG, "invalid overlayPath, %{public}s", (*iter).c_str());
946             continue;
947         }
948         if (std::find(targetOverlay.begin(), targetOverlay.end(), outPath) != targetOverlay.end()) {
949             targetOverlay.erase(std::remove(targetOverlay.begin(), targetOverlay.end(), outPath),
950                 targetOverlay.end());
951         }
952         for (auto resIter = hapResources_.begin(); resIter != hapResources_.end();) {
953             if ((*resIter) == nullptr) {
954                 RESMGR_HILOGE(RESMGR_TAG, "hapResource is nullptr");
955                 return false;
956             }
957             std::string hapPath = (*resIter)->GetIndexPath();
958             if (hapPath == outPath) {
959                 resIter = hapResources_.erase(resIter);
960             } else {
961                 resIter++;
962             }
963         }
964     }
965     loadedHapPaths_[path] = targetOverlay;
966     return true;
967 }
968 
GetHapResource()969 std::vector<std::shared_ptr<HapResource>> HapManager::GetHapResource()
970 {
971     return hapResources_;
972 }
973 
AddSystemResource(const std::shared_ptr<HapManager> & systemHapManager)974 void HapManager::AddSystemResource(const std::shared_ptr<HapManager> &systemHapManager)
975 {
976     if (systemHapManager == nullptr) {
977         RESMGR_HILOGE(RESMGR_TAG, "add system resource failed, systemHapManager is nullptr");
978         return;
979     }
980     if (!systemHapManager->isSystem_) {
981         RESMGR_HILOGE(RESMGR_TAG, "add system resource failed, the added hapManager is not system");
982         return;
983     }
984     WriteLock lock(this->mutex_);
985     // add system resource to app resource vector
986     const std::vector<std::shared_ptr<HapResource>> &systemResources = systemHapManager->hapResources_;
987     for (size_t i = 0; i < systemResources.size(); i++) {
988         this->hapResources_.push_back(systemResources[i]);
989     }
990 
991     // add system loaded path to app loaded path map.
992     const std::unordered_map<std::string, std::vector<std::string>> &loadedSystemPaths =
993         systemHapManager->loadedHapPaths_;
994     for (auto iter = loadedSystemPaths.begin(); iter != loadedSystemPaths.end(); iter++) {
995         const std::vector<std::string> &overlayPaths = iter->second;
996         if (this->loadedHapPaths_.find(iter->first) == this->loadedHapPaths_.end()) {
997             this->loadedHapPaths_[iter->first] = overlayPaths;
998         }
999     }
1000 }
1001 
GetResourceLimitKeys()1002 uint32_t HapManager::GetResourceLimitKeys()
1003 {
1004     ReadLock lock(this->mutex_);
1005     uint32_t limitKeysValue = 0;
1006     for (size_t i = 0; i < hapResources_.size(); i++) {
1007         limitKeysValue |= hapResources_[i]->GetResourceLimitKeys();
1008     }
1009     RESMGR_HILOGD(RESMGR_TAG, "hap manager limit key is %{public}u", limitKeysValue);
1010     return limitKeysValue;
1011 }
1012 
1013 std::unordered_map<std::string, ResType> ResTypeMap {
1014     {"integer", INTEGER},
1015     {"string", STRING},
1016     {"strarray", STRINGARRAY},
1017     {"intarray", INTARRAY},
1018     {"boolean", BOOLEAN},
1019     {"color", COLOR},
1020     {"theme", THEME},
1021     {"plural", PLURALS},
1022     {"float", FLOAT},
1023     {"media", MEDIA},
1024     {"profile", PROF},
1025     {"pattern", PATTERN},
1026 };
1027 
IsPrefix(std::string_view prefix,std::string_view full)1028 bool IsPrefix(std::string_view prefix, std::string_view full)
1029 {
1030     return prefix == full.substr(0, prefix.size());
1031 }
1032 
GetRealResId(const std::string & resType,const std::vector<std::unordered_map<ResType,uint32_t>> & candidates)1033 uint32_t GetRealResId(const std::string &resType,
1034     const std::vector<std::unordered_map<ResType, uint32_t>> &candidates)
1035 {
1036     for (auto candidate : candidates) {
1037         for (auto data : candidate) {
1038             if (ResTypeMap.find(resType) != ResTypeMap.end() && ResTypeMap[resType] == data.first) {
1039                 return data.second;
1040             }
1041         }
1042     }
1043     return 0;
1044 }
1045 
GetResTypeAndResName(const std::string & resTypeName)1046 std::tuple<std::string, std::string> GetResTypeAndResName(const std::string &resTypeName)
1047 {
1048     std::tuple<std::string, std::string> typeNameTuple;
1049     auto pos1 = resTypeName.find('.');
1050     auto pos2 = resTypeName.rfind('.');
1051     if (pos1 == std::string::npos || pos2 == std::string::npos) {
1052         return std::make_tuple("", "");
1053     }
1054     if (pos2 < pos1 + 1) {
1055         return std::make_tuple("", "");
1056     }
1057     const std::string resType = resTypeName.substr(pos1 + 1, pos2 - pos1 - 1);
1058     if (ResTypeMap.find(resType) == ResTypeMap.end()) {
1059         return std::make_tuple("", "");
1060     }
1061     const std::string resName = resTypeName.substr(pos2 + 1);
1062     if (resName.empty()) {
1063         return std::make_tuple("", "");
1064     }
1065     typeNameTuple = std::make_tuple(resType, resName);
1066     return typeNameTuple;
1067 }
1068 
GetResId(const std::string & resTypeName,uint32_t & resId)1069 RState HapManager::GetResId(const std::string &resTypeName, uint32_t &resId)
1070 {
1071     auto typeNameTuple = GetResTypeAndResName(resTypeName);
1072     const std::string resType =  std::get<0>(typeNameTuple);
1073     const std::string resName =  std::get<1>(typeNameTuple);
1074     if (resType.empty() || resName.empty()) {
1075         RESMGR_HILOGE(RESMGR_TAG, "invalid resTypeName = %{public}s", resTypeName.c_str());
1076         return NOT_FOUND;
1077     }
1078     bool isSystem = IsPrefix("sys", resTypeName);
1079     bool isApp = IsPrefix("app", resTypeName);
1080     if (!isSystem && !isApp) {
1081         RESMGR_HILOGE(RESMGR_TAG, "invalid resTypeName = %{public}s", resTypeName.c_str());
1082         return NOT_FOUND;
1083     }
1084     ReadLock lock(this->mutex_);
1085     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1086         bool isSystemResource = (*iter)->IsSystemResource();
1087         bool isOverlayResource = (*iter)->IsOverlayResource();
1088         if (isOverlayResource) {
1089             continue;
1090         }
1091         if (isSystem && !isSystemResource) {
1092             continue;
1093         }
1094         if (isApp && isSystemResource) {
1095             continue;
1096         }
1097         std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> nameTypeIdMap =
1098                 (*iter)->BuildNameTypeIdMapping();
1099         std::vector<std::unordered_map<ResType, uint32_t>> candidates;
1100         for (auto data : nameTypeIdMap) {
1101             if (data.first != resName) {
1102                 continue;
1103             }
1104             candidates.emplace_back(data.second);
1105         }
1106         resId = GetRealResId(resType, candidates);
1107         if (resId == 0) {
1108             RESMGR_HILOGE(RESMGR_TAG,
1109                 "GetResId name = %{public}s, resType = %{public}s", resName.c_str(), resType.c_str());
1110             return NOT_FOUND;
1111         }
1112     }
1113     return SUCCESS;
1114 }
1115 
GetLocales(std::vector<std::string> & outValue,bool includeSystem)1116 void HapManager::GetLocales(std::vector<std::string> &outValue, bool includeSystem)
1117 {
1118     if (isSystem_) {
1119         includeSystem = true;
1120     }
1121     std::set<std::string> result;
1122     ReadLock lock(this->mutex_);
1123     for (size_t i = 0; i < hapResources_.size(); i++) {
1124         hapResources_[i]->GetLocales(result, includeSystem);
1125     }
1126     outValue.assign(result.begin(), result.end());
1127 }
1128 
IsRawDirFromHap(const std::string & pathName,bool & outValue)1129 RState HapManager::IsRawDirFromHap(const std::string &pathName, bool &outValue)
1130 {
1131     ReadLock lock(this->mutex_);
1132     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1133         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
1134             continue;
1135         }
1136         const std::string tempPath = (*iter)->GetIndexPath();
1137         if (Utils::ContainsTail(tempPath, Utils::tailSet)) { // if file path is compressed
1138             RState state = HapParser::IsRawDirFromHap(tempPath.c_str(), pathName, outValue);
1139             if (state != SUCCESS) {
1140                 continue;
1141             }
1142         } else { // if file path is uncompressed
1143 #if !defined(__ARKUI_CROSS__)
1144             RState state = HapParser::IsRawDirUnCompressed(pathName, outValue);
1145             if (state != SUCCESS) {
1146                 continue;
1147             }
1148 #else
1149             const std::string finalPath = (*iter)->GetResourcePath() + RAW_FILE_PATH + pathName;
1150             RState state = HapParser::IsRawDirUnCompressed(finalPath, outValue);
1151             if (state != SUCCESS) {
1152                 continue;
1153             }
1154 #endif
1155         }
1156         return SUCCESS;
1157     }
1158     return ERROR_CODE_RES_PATH_INVALID;
1159 }
1160 
IsThemeSystemResEnableHap()1161 bool HapManager::IsThemeSystemResEnableHap()
1162 {
1163     ReadLock lock(this->mutex_);
1164     for (auto iter = hapResources_.begin(); iter != hapResources_.end(); iter++) {
1165         if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
1166             continue;
1167         }
1168         if ((*iter)->IsThemeSystemResEnable()) {
1169             return true;
1170         }
1171     }
1172     return false;
1173 }
1174 } // namespace Resource
1175 } // namespace Global
1176 } // namespace OHOS
1177