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