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