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