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