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