/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "resource_manager_impl.h" #include <cmath> #include <cstdarg> #include <cstdlib> #include <cstring> #include <fcntl.h> #include <regex> #include <sstream> #include <sys/types.h> #include <unistd.h> #include <fstream> #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__) #include "hitrace_meter.h" #endif #include "hilog_wrapper.h" #include "res_config.h" #include "securec.h" #include "system_resource_manager.h" #include "utils/common.h" #include "utils/string_utils.h" #include "utils/utils.h" #include "tuple" namespace OHOS { namespace Global { namespace Resource { // default logLevel #ifdef CONFIG_HILOG LogLevel g_logLevel = LOG_INFO; #endif constexpr int HEX_ADECIMAL = 16; const std::string FOREGROUND = "foreground"; const std::string BACKGROUND = "background"; const std::regex FLOAT_REGEX = std::regex("(\\+|-)?\\d+(\\.\\d+)? *(px|vp|fp)?"); void ResourceManagerImpl::AddSystemResource(ResourceManagerImpl *systemResourceManager) { if (systemResourceManager != nullptr) { this->hapManager_->AddSystemResource(systemResourceManager->hapManager_); } } ResourceManagerImpl::ResourceManagerImpl(bool isOverrideResMgr) : hapManager_(nullptr), isOverrideResMgr_(isOverrideResMgr) { psueManager_ = std::make_shared<PsueManager>(); } bool ResourceManagerImpl::Init(bool isSystem) { auto resConfig = std::make_shared<ResConfigImpl>(); if (resConfig == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "new ResConfigImpl failed when ResourceManagerImpl::Init"); return false; } hapManager_ = std::make_shared<HapManager>(resConfig, isSystem); if (hapManager_ == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "new HapManager failed when ResourceManagerImpl::Init"); return false; } isSystemResMgr_ = isSystem; return true; } bool ResourceManagerImpl::Init(std::shared_ptr<HapManager> hapManager) { if (hapManager == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "ResourceManagerImpl::Init, hapManager is nullptr"); return false; } this->hapManager_ = hapManager; return true; } RState ResourceManagerImpl::GetStringById(uint32_t id, std::string &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetStringById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetString(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetStringByName(const char *name, std::string &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::STRING, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetStringByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetString(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetStringFormatById(std::string &outValue, uint32_t id, ...) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); std::string temp; RState rState = GetString(idItem, temp); if (rState != SUCCESS) { return rState; } va_list args; va_start(args, id); outValue = FormatString(temp.c_str(), args); va_end(args); return SUCCESS; } RState ResourceManagerImpl::GetStringFormatByName(std::string &outValue, const char *name, ...) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::STRING, isOverrideResMgr_); std::string temp; RState rState = GetString(idItem, temp); if (rState != SUCCESS) { return rState; } va_list args; va_start(args, name); outValue = FormatString(temp.c_str(), args); va_end(args); return SUCCESS; } RState ResourceManagerImpl::GetStringFormatById(std::string &outValue, uint32_t id, va_list args) { RState state = GetStringById(id, outValue); if (state != SUCCESS) { return state; } std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> jsParams; if (parseArgs(outValue, args, jsParams)) { ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { return ERROR_CODE_RES_ID_FORMAT_ERROR; } return SUCCESS; } return ERROR_CODE_INVALID_INPUT_PARAMETER; } RState ResourceManagerImpl::GetStringFormatByName(std::string &outValue, const char *name, va_list args) { RState state = GetStringByName(name, outValue); if (state != SUCCESS) { return state; } std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> jsParams; if (parseArgs(outValue, args, jsParams)) { ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { return ERROR_CODE_RES_NAME_FORMAT_ERROR; } return SUCCESS; } return ERROR_CODE_INVALID_INPUT_PARAMETER; } RState ResourceManagerImpl::GetString(const std::shared_ptr<IdItem> idItem, std::string &outValue) { // not found or type invalid if (idItem == nullptr || idItem->resType_ != ResType::STRING) { return NOT_FOUND; } RState ret = ResolveReference(idItem->value_, outValue); if (isFakeLocale) { ProcessPsuedoTranslate(outValue); } if (isBidirectionFakeLocale) { outValue = psueManager_->BidirectionConvert(outValue); } if (ret != SUCCESS) { return ret; } return SUCCESS; } RState ResourceManagerImpl::GetStringArrayById(uint32_t id, std::vector<std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetStringArrayById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetStringArray(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetStringArrayByName(const char *name, std::vector<std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName( name, ResType::STRINGARRAY, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetStringArrayByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetStringArray(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetStringArray(const std::shared_ptr<IdItem> idItem, std::vector<std::string> &outValue) { // not found or type invalid if (idItem == nullptr || idItem->resType_ != ResType::STRINGARRAY) { return NOT_FOUND; } outValue.clear(); for (size_t i = 0; i < idItem->values_.size(); ++i) { std::string resolvedValue; RState rrRet = ResolveReference(idItem->values_[i], resolvedValue); if (rrRet != SUCCESS) { RESMGR_HILOGD(RESMGR_TAG, "GetStringArray ResolveReference failed, value:%{public}s", idItem->values_[i].c_str()); return rrRet; } outValue.push_back(resolvedValue); } if (isFakeLocale) { for (auto &iter : outValue) { ProcessPsuedoTranslate(iter); } } if (isBidirectionFakeLocale) { for (auto &iter : outValue) { iter = psueManager_->BidirectionConvert(iter); } } return SUCCESS; } RState ResourceManagerImpl::GetPatternById(uint32_t id, std::map<std::string, std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetPatternById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetPattern(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetPatternByName(const char *name, std::map<std::string, std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::PATTERN, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetPatternByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetPattern(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetPattern(const std::shared_ptr<IdItem> idItem, std::map<std::string, std::string> &outValue) { //type invalid if (idItem->resType_ != ResType::PATTERN) { RESMGR_HILOGE(RESMGR_TAG, "actual resType = %{public}d, expect resType = %{public}d", idItem->resType_, ResType::PATTERN); return NOT_FOUND; } return ResolveParentReference(idItem, outValue); } RState ResourceManagerImpl::GetPluralStringById(uint32_t id, int quantity, std::string &outValue) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_); return GetPluralString(vuqd, quantity, outValue); } RState ResourceManagerImpl::GetPluralStringByName(const char *name, int quantity, std::string &outValue) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueByName(name, ResType::PLURALS, isOverrideResMgr_); return GetPluralString(vuqd, quantity, outValue); } RState ResourceManagerImpl::GetPluralStringByIdFormat(std::string &outValue, uint32_t id, int quantity, ...) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_); if (vuqd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetPluralStringByIdFormat error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } std::string temp; RState rState = GetPluralString(vuqd, quantity, temp); if (rState == ERROR_CODE_RES_REF_TOO_MUCH) { return rState; } if (rState != SUCCESS) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } va_list args; va_start(args, quantity); outValue = FormatString(temp.c_str(), args); va_end(args); return SUCCESS; } RState ResourceManagerImpl::GetPluralStringByNameFormat(std::string &outValue, const char *name, int quantity, ...) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueByName(name, ResType::PLURALS, isOverrideResMgr_); if (vuqd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetPluralStringByNameFormat error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } std::string temp; RState rState = GetPluralString(vuqd, quantity, temp); if (rState == ERROR_CODE_RES_REF_TOO_MUCH) { return rState; } if (rState != SUCCESS) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } va_list args; va_start(args, quantity); outValue = FormatString(temp.c_str(), args); va_end(args); return SUCCESS; } RState ResourceManagerImpl::GetPluralString(const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd, int quantity, std::string &outValue) { // not found or type invalid if (vuqd == nullptr) { return NOT_FOUND; } auto idItem = vuqd->GetIdItem(); if (idItem == nullptr || idItem->resType_ != ResType::PLURALS) { return NOT_FOUND; } std::map<std::string, std::string> map; size_t startIdx = 0; size_t loop = idItem->values_.size() / 2; for (size_t i = 0; i < loop; ++i) { std::string key(idItem->values_[startIdx + i * 2]); // 2 means keyappear in pairs std::string value(idItem->values_[startIdx + i * 2 + 1]); // 2 means value appear in pairs auto iter = map.find(key); if (iter == map.end()) { std::string resolvedValue; RState rrRet = ResolveReference(value, resolvedValue); if (rrRet != SUCCESS) { RESMGR_HILOGD(RESMGR_TAG, "ResolveReference failed, value:%{public}s", value.c_str()); return rrRet; } map[key] = resolvedValue; } } std::string converted = hapManager_->GetPluralRulesAndSelect(quantity, isOverrideResMgr_); auto mapIter = map.find(converted); if (mapIter == map.end()) { mapIter = map.find("other"); if (mapIter == map.end()) { return NOT_FOUND; } } outValue = mapIter->second; if (isFakeLocale) { ProcessPsuedoTranslate(outValue); } if (isBidirectionFakeLocale) { outValue = psueManager_->BidirectionConvert(outValue); } return SUCCESS; } RState ResourceManagerImpl::ResolveReference(const std::string value, std::string &outValue) { int id; ResType resType; bool isRef = true; int count = 0; std::string refStr(value); while (isRef) { isRef = IdItem::IsRef(refStr, resType, id); if (!isRef) { outValue = refStr; return SUCCESS; } if (IdItem::IsArrayOfType(resType)) { // can't be array RESMGR_HILOGD(RESMGR_TAG, "ref %{public}s can't be array", refStr.c_str()); return ERROR; } const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "ref %s id not found", refStr.c_str()); return ERROR; } // unless compile bug if (resType != idItem->resType_) { RESMGR_HILOGE(RESMGR_TAG, "impossible. ref %s type mismatch, found type: %d", refStr.c_str(), idItem->resType_); return ERROR; } refStr = idItem->value_; if (++count > MAX_DEPTH_REF_SEARCH) { RESMGR_HILOGE(RESMGR_TAG, "ref %s has re-ref too much", value.c_str()); return ERROR_CODE_RES_REF_TOO_MUCH; } } return SUCCESS; } RState ResourceManagerImpl::GetThemeValues(const std::string &value, std::string &outValue) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem>> idItems; if (ProcessReference(value, idItems) != SUCCESS) { return NOT_FOUND; } outValue = ThemePackManager::GetThemePackManager()->FindThemeResource(bundleInfo, idItems, resConfig, hapManager_->IsThemeSystemResEnableHap()); return outValue.empty() ? NOT_FOUND : SUCCESS; } RState ResourceManagerImpl::ResolveParentReference(const std::shared_ptr<IdItem> idItem, std::map<std::string, std::string> &outValue) { // only pattern and theme // ref always at idx 0 // child will cover parent outValue.clear(); bool haveParent = false; int count = 0; std::shared_ptr<IdItem> currItem = idItem; do { haveParent = currItem->HaveParent(); size_t startIdx = haveParent ? 1 : 0; // add currItem values into map when key is absent // this make sure child covers parent size_t loop = currItem->values_.size() / 2; for (size_t i = 0; i < loop; ++i) { std::string key(currItem->values_[startIdx + i * 2]); // 2 means key appear in pairs std::string value(currItem->values_[startIdx + i * 2 + 1]); // 2 means value appear in pairs auto iter = outValue.find(key); if (iter != outValue.end()) { continue; } std::string resolvedValue; if (GetThemeValues(value, resolvedValue) == SUCCESS) { outValue[key] = resolvedValue; continue; } RState rrRet = ResolveReference(value, resolvedValue); if (rrRet != SUCCESS) { RESMGR_HILOGD(RESMGR_TAG, "ResolveReference failed, value:%{public}s", value.c_str()); return ERROR; } outValue[key] = resolvedValue; } if (haveParent) { // get parent int id; ResType resType; bool isRef = IdItem::IsRef(currItem->values_[0], resType, id); if (!isRef) { RESMGR_HILOGE(RESMGR_TAG, "something wrong, pls check HaveParent(). idItem: %{public}s", idItem->ToString().c_str()); return ERROR; } currItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (currItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "ref %s id not found", idItem->values_[0].c_str()); return ERROR; } } if (++count > MAX_DEPTH_REF_SEARCH) { RESMGR_HILOGE(RESMGR_TAG, " %u has too many parents", idItem->id_); return ERROR; } } while (haveParent); return SUCCESS; } RState ResourceManagerImpl::GetBooleanById(uint32_t id, bool &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetBooleanById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetBoolean(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetBooleanByName(const char *name, bool &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::BOOLEAN, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetBooleanByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetBoolean(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetBoolean(const std::shared_ptr<IdItem> idItem, bool &outValue) { if (idItem == nullptr || idItem->resType_ != ResType::BOOLEAN) { return NOT_FOUND; } std::string temp; RState state = ResolveReference(idItem->value_, temp); if (state == SUCCESS) { if (strcmp(temp.c_str(), "true") == 0) { outValue = true; return SUCCESS; } if (strcmp(temp.c_str(), "false") == 0) { outValue = false; return SUCCESS; } return ERROR; } return state; } RState ResourceManagerImpl::GetThemeFloat(const std::shared_ptr<IdItem> idItem, float &outValue) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem>> idItems; idItems.emplace_back(idItem); ProcessReference(idItem->value_, idItems); std::string result = ThemePackManager::GetThemePackManager()->FindThemeResource( bundleInfo, idItems, resConfig, userId); if (result.empty()) { return NOT_FOUND; } std::string unit; RState state = ParseFloat(result.c_str(), outValue, unit); return state == SUCCESS ? RecalculateFloat(unit, outValue) : state; } RState ResourceManagerImpl::GetThemeFloat(const std::shared_ptr<IdItem> idItem, float &outValue, std::string &unit) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem>> idItems; idItems.emplace_back(idItem); ProcessReference(idItem->value_, idItems); std::string result = ThemePackManager::GetThemePackManager()->FindThemeResource( bundleInfo, idItems, resConfig, userId); if (result.empty()) { return NOT_FOUND; } RState state = ParseFloat(result.c_str(), outValue, unit); return state == SUCCESS ? RecalculateFloat(unit, outValue) : state; } RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetFloatById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } // find in theme pack if (GetThemeFloat(idItem, outValue) == SUCCESS) { return SUCCESS; } std::string unit; RState state = GetFloat(idItem, outValue, unit); if (state == SUCCESS) { return RecalculateFloat(unit, outValue); } if (state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue, std::string &unit) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetFloatById error with unit id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } // find in theme pack if (GetThemeFloat(idItem, outValue, unit) == SUCCESS) { return SUCCESS; } RState state = GetFloat(idItem, outValue, unit); if (state == SUCCESS) { return state; } if (state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::FLOAT, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetFloatByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } // find in theme pack if (GetThemeFloat(idItem, outValue) == SUCCESS) { return SUCCESS; } std::string unit; RState state = GetFloat(idItem, outValue, unit); if (state == SUCCESS) { return RecalculateFloat(unit, outValue); } if (state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue, std::string &unit) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::FLOAT, isOverrideResMgr_); return GetFloat(idItem, outValue, unit); } RState ResourceManagerImpl::RecalculateFloat(const std::string &unit, float &result) { ResConfigImpl rc; GetResConfig(rc); float density = rc.GetScreenDensity(); if (density == SCREEN_DENSITY_NOT_SET) { RESMGR_HILOGD(RESMGR_TAG, "RecalculateFloat srcDensity SCREEN_DENSITY_NOT_SET "); return SUCCESS; } if (unit == VIRTUAL_PIXEL) { result = result * density; } else if (unit == FONT_SIZE_PIXEL) { float fontSizeDensity = density * ((fabs(fontRatio_) <= 1E-6) ? 1.0f : fontRatio_); result = result * fontSizeDensity; } else { // no unit } return SUCCESS; } RState ResourceManagerImpl::ParseFloat(const std::string &strValue, float &result, std::string &unit) { std::smatch floatMatch; if (!regex_search(strValue, floatMatch, FLOAT_REGEX)) { RESMGR_HILOGD(RESMGR_TAG, "not valid float value %{public}s", strValue.c_str()); return ERROR; } std::string matchString(floatMatch.str()); if (floatMatch.size() < 1) { return ERROR; } unit = floatMatch[floatMatch.size() - 1]; std::istringstream stream(matchString.substr(0, matchString.length() - unit.length())); stream >> result; return SUCCESS; } RState ResourceManagerImpl::GetFloat(const std::shared_ptr<IdItem> idItem, float &outValue, std::string &unit) { if (idItem == nullptr || idItem->resType_ != ResType::FLOAT) { return NOT_FOUND; } std::string temp; RState state = ResolveReference(idItem->value_, temp); if (state == SUCCESS) { return ParseFloat(temp.c_str(), outValue, unit); } return state; } RState ResourceManagerImpl::GetIntegerById(uint32_t id, int &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetIntegerById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetInteger(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetIntegerByName(const char *name, int &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::INTEGER, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetIntegerByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetInteger(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetInteger(const std::shared_ptr<IdItem> idItem, int &outValue) { if (idItem == nullptr || idItem->resType_ != ResType::INTEGER) { return NOT_FOUND; } std::string temp; RState state = ResolveReference(idItem->value_, temp); if (state != SUCCESS) { return state; } int intValue; if (Utils::convertToInteger(temp, intValue)) { outValue = intValue; return SUCCESS; } return ERROR; } RState ResourceManagerImpl::ProcessReference(const std::string value, std::vector<std::shared_ptr<IdItem>> &idItems) { int id; ResType resType; bool isRef = true; int count = 0; std::string refStr(value); while (isRef) { isRef = IdItem::IsRef(refStr, resType, id); if (!isRef) { return SUCCESS; } if (IdItem::IsArrayOfType(resType)) { // can't be array RESMGR_HILOGD(RESMGR_TAG, "ref %{public}s can't be array", refStr.c_str()); return ERROR; } const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); idItems.emplace_back(idItem); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "ref %s id not found", refStr.c_str()); return ERROR; } // unless compile bug if (resType != idItem->resType_) { RESMGR_HILOGE(RESMGR_TAG, "impossible. ref %s type mismatch, found type: %d", refStr.c_str(), idItem->resType_); return ERROR; } refStr = idItem->value_; if (++count > MAX_DEPTH_REF_SEARCH) { RESMGR_HILOGE(RESMGR_TAG, "ref %s has re-ref too much", value.c_str()); return ERROR_CODE_RES_REF_TOO_MUCH; } } return SUCCESS; } RState ResourceManagerImpl::GetThemeColor(const std::shared_ptr<IdItem> idItem, uint32_t &outValue) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem> > idItems; idItems.emplace_back(idItem); RState state = ProcessReference(idItem->value_, idItems); std::string result = ThemePackManager::GetThemePackManager()->FindThemeResource(bundleInfo, idItems, resConfig, hapManager_->IsThemeSystemResEnableHap()); if (result.empty()) { return ERROR_CODE_RES_ID_NOT_FOUND; } return state == SUCCESS ? Utils::ConvertColorToUInt32(result.c_str(), outValue) : state; } RState ResourceManagerImpl::GetColorById(uint32_t id, uint32_t &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetColorById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } // find in theme pack if (GetThemeColor(idItem, outValue) == SUCCESS) { return SUCCESS; } RState state = GetColor(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetColorByName(const char *name, uint32_t &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::COLOR, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetColorByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } // find in theme pack if (GetThemeColor(idItem, outValue) == SUCCESS) { return SUCCESS; } RState state = GetColor(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetColor(const std::shared_ptr<IdItem> idItem, uint32_t &outValue) { if (idItem == nullptr || idItem->resType_ != ResType::COLOR) { return NOT_FOUND; } std::string temp; RState state = ResolveReference(idItem->value_, temp); if (state == SUCCESS) { return Utils::ConvertColorToUInt32(temp.c_str(), outValue); } return state; } RState ResourceManagerImpl::GetSymbolById(uint32_t id, uint32_t &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetSymbolById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetSymbol(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetSymbolByName(const char *name, uint32_t &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::SYMBOL, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetSymbolByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetSymbol(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetSymbol(const std::shared_ptr<IdItem> idItem, uint32_t &outValue) { if (idItem == nullptr || idItem->resType_ != ResType::SYMBOL) { return NOT_FOUND; } std::string temp; RState state = ResolveReference(idItem->value_, temp); if (state == SUCCESS) { outValue = static_cast<uint32_t>(strtol(temp.c_str(), nullptr, HEX_ADECIMAL)); } return state; } RState ResourceManagerImpl::GetIntArrayById(uint32_t id, std::vector<int> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); return GetIntArray(idItem, outValue); } RState ResourceManagerImpl::GetIntArrayByName(const char *name, std::vector<int> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::INTARRAY, isOverrideResMgr_); return GetIntArray(idItem, outValue); } RState ResourceManagerImpl::GetIntArray(const std::shared_ptr<IdItem> idItem, std::vector<int> &outValue) { // not found or type invalid if (idItem == nullptr || idItem->resType_ != ResType::INTARRAY) { return NOT_FOUND; } outValue.clear(); for (size_t i = 0; i < idItem->values_.size(); ++i) { std::string resolvedValue; RState rrRet = ResolveReference(idItem->values_[i], resolvedValue); if (rrRet != SUCCESS) { RESMGR_HILOGD(RESMGR_TAG, "ResolveReference failed, value:%{public}s", idItem->values_[i].c_str()); return ERROR; } int intValue; if (!Utils::convertToInteger(resolvedValue, intValue)) { return ERROR; } outValue.push_back(intValue); } return SUCCESS; } RState ResourceManagerImpl::GetThemeById(uint32_t id, std::map<std::string, std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceById(id, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetThemeById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = GetTheme(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return state; } RState ResourceManagerImpl::GetThemeByName(const char *name, std::map<std::string, std::string> &outValue) { const std::shared_ptr<IdItem> idItem = hapManager_->FindResourceByName(name, ResType::THEME, isOverrideResMgr_); if (idItem == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetThemeByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = GetTheme(idItem, outValue); if (state != SUCCESS && state != ERROR_CODE_RES_REF_TOO_MUCH) { return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return state; } RState ResourceManagerImpl::GetTheme(const std::shared_ptr<IdItem> idItem, std::map<std::string, std::string> &outValue) { //type invalid if (idItem->resType_ != ResType::THEME) { RESMGR_HILOGE(RESMGR_TAG, "actual resType = %{public}d, expect resType = %{public}d", idItem->resType_, ResType::THEME); return NOT_FOUND; } return ResolveParentReference(idItem, outValue); } RState ResourceManagerImpl::GetProfileById(uint32_t id, std::string &outValue) { auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetProfileById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = hapManager_->GetFilePath(qd, ResType::PROF, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_ID; } RState ResourceManagerImpl::GetProfileByName(const char *name, std::string &outValue) { auto qd = hapManager_->FindQualifierValueByName(name, ResType::PROF, isOverrideResMgr_); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetProfileByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = hapManager_->GetFilePath(qd, ResType::PROF, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_NAME; } RState ResourceManagerImpl::GetMediaById(uint32_t id, std::string &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState state = hapManager_->GetFilePath(qd, ResType::MEDIA, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_ID; } RState ResourceManagerImpl::GetMediaByName(const char *name, std::string &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState state = hapManager_->GetFilePath(qd, ResType::MEDIA, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_NAME; } RState ResourceManagerImpl::GetRawFilePathByName(const std::string &name, std::string &outValue) { return hapManager_->FindRawFile(name, outValue); } RState ResourceManagerImpl::GetRawFileDescriptor(const std::string &name, RawFileDescriptor &descriptor) { return hapManager_->FindRawFileDescriptorFromHap(name, descriptor); } RState ResourceManagerImpl::CloseRawFileDescriptor(const std::string &name) { return hapManager_->CloseRawFileDescriptor(name); } void ResourceManagerImpl::ProcessPsuedoTranslate(std::string &outValue) { auto len = outValue.length() + 1; char src[len]; if (strcpy_s(src, len, outValue.c_str()) == EOK) { std::string resultMsg = psueManager_->Convert(src, outValue); if (resultMsg != "") { RESMGR_HILOGE(RESMGR_TAG, "Psuedo translate failed, value:%s", src); } } } ResourceManagerImpl::~ResourceManagerImpl() {} bool ResourceManagerImpl::AddResource(const char *path, const uint32_t &selectedTypes) { #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__) HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); #endif #if defined(__ARKUI_CROSS__) if (!isSystemResMgr_ && std::string(path).find("/systemres/resources.index") != std::string::npos) { ResourceManagerImpl* systemResourceManager = SystemResourceManager::GetSystemResourceManager(); if (systemResourceManager != nullptr) { systemResourceManager->AddResource(path); AddSystemResource(systemResourceManager); return true; } } #endif return this->hapManager_->AddResource(path, selectedTypes); } bool ResourceManagerImpl::AddResource(const std::string &path, const std::vector<std::string> &overlayPaths) { return this->hapManager_->AddResource(path, overlayPaths); } bool ResourceManagerImpl::RemoveResource(const std::string &path, const std::vector<std::string> &overlayPaths) { return this->hapManager_->RemoveResource(path, overlayPaths); } bool ResourceManagerImpl::AddAppOverlay(const std::string &path) { return this->hapManager_->AddAppOverlay(path); } bool ResourceManagerImpl::RemoveAppOverlay(const std::string &path) { return this->hapManager_->RemoveAppOverlay(path); } RState ResourceManagerImpl::UpdateFakeLocaleFlag(ResConfig &resConfig) { #ifdef SUPPORT_GRAPHICS if (resConfig.GetLocaleInfo() == nullptr) { return LOCALEINFO_IS_NULL; } if (resConfig.GetLocaleInfo()->getLanguage() == nullptr) { return LOCALEINFO_IS_NULL; } const char* language = resConfig.GetLocaleInfo()->getLanguage(); const char* region = resConfig.GetLocaleInfo()->getCountry(); if (language != nullptr && region != nullptr) { std::string languageStr = language; std::string regionStr = region; if (languageStr == "en" && regionStr == "XA") { isFakeLocale = true; } else { isFakeLocale = false; } if (languageStr == "ar" && regionStr == "XB") { isBidirectionFakeLocale = true; } else { isBidirectionFakeLocale = false; } } #endif return SUCCESS; } RState ResourceManagerImpl::UpdateResConfig(ResConfig &resConfig, bool isUpdateTheme) { auto themePackManager = ThemePackManager::GetThemePackManager(); if (themePackManager->UpdateThemeId(resConfig.GetThemeId())) { RESMGR_HILOGD(RESMGR_TAG, "The theme enabled"); themePackManager->LoadThemeRes(bundleInfo.first, bundleInfo.second, userId); } #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__) HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); #endif RState state = UpdateFakeLocaleFlag(resConfig); if (state != SUCCESS) { return state; } return this->hapManager_->UpdateResConfig(resConfig); } RState ResourceManagerImpl::UpdateOverrideResConfig(ResConfig &resConfig) { #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__) HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); #endif UpdateFakeLocaleFlag(resConfig); return this->hapManager_->UpdateOverrideResConfig(resConfig); } void ResourceManagerImpl::GetResConfig(ResConfig &resConfig) { this->hapManager_->GetResConfig(resConfig); } void ResourceManagerImpl::GetOverrideResConfig(ResConfig &resConfig) { this->hapManager_->GetOverrideResConfig(resConfig); } std::vector<std::string> ResourceManagerImpl::GetResourcePaths() { return this->hapManager_->GetResourcePaths(); } bool ResourceManagerImpl::IsDensityValid(uint32_t density) { switch (density) { case SCREEN_DENSITY_NOT_SET: case SCREEN_DENSITY_SDPI: case SCREEN_DENSITY_MDPI: case SCREEN_DENSITY_LDPI: case SCREEN_DENSITY_XLDPI: case SCREEN_DENSITY_XXLDPI: case SCREEN_DENSITY_XXXLDPI: return true; default: return false; } } RState ResourceManagerImpl::GetThemeMedia(const std::shared_ptr<IdItem> idItem, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem>> idItems; idItems.emplace_back(idItem); std::string result = ThemePackManager::GetThemePackManager()->FindThemeResource( bundleInfo, idItems, resConfig, userId); outValue = Utils::LoadResourceFile(result, len); return result.empty() ? ERROR_CODE_RES_ID_NOT_FOUND : SUCCESS; } RState ResourceManagerImpl::GetMediaDataById(uint32_t id, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaDataById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } // find in theme const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (GetThemeMedia(idItem, len, outValue, density) == SUCCESS) { return SUCCESS; } RState state = hapManager_->GetMediaData(qd, len, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_ID; } RState ResourceManagerImpl::GetMediaDataByName(const char *name, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaDataByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (GetThemeMedia(idItem, len, outValue, density) == SUCCESS) { return SUCCESS; } RState state = hapManager_->GetMediaData(qd, len, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_NAME; } RState ResourceManagerImpl::GetThemeMediaBase64(const std::shared_ptr<IdItem> idItem, std::string &outValue) { ResConfigImpl resConfig; GetResConfig(resConfig); std::vector<std::shared_ptr<IdItem>> idItems; idItems.emplace_back(idItem); std::string result = ThemePackManager::GetThemePackManager()->FindThemeResource( bundleInfo, idItems, resConfig, userId); if (result.empty()) { return NOT_FOUND; } return Utils::GetMediaBase64Data(result, outValue); } RState ResourceManagerImpl::GetMediaBase64DataById(uint32_t id, std::string &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaBase64DataById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (GetThemeMediaBase64(idItem, outValue) == SUCCESS) { return SUCCESS; } RState state = hapManager_->GetMediaBase64Data(qd, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_ID; } RState ResourceManagerImpl::GetMediaBase64DataByName(const char *name, std::string &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetMediaBase64DataByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (GetThemeMediaBase64(idItem, outValue) == SUCCESS) { return SUCCESS; } RState state = hapManager_->GetMediaBase64Data(qd, outValue); return state == SUCCESS ? state : ERROR_CODE_RES_NOT_FOUND_BY_NAME; } RState ResourceManagerImpl::GetProfileDataById(uint32_t id, size_t &len, std::unique_ptr<uint8_t[]> &outValue) { auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetProfileDataById error id = %{public}d", id); return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return hapManager_->GetProfileData(qd, len, outValue); } RState ResourceManagerImpl::GetProfileDataByName(const char *name, size_t &len, std::unique_ptr<uint8_t[]> &outValue) { auto qd = hapManager_->FindQualifierValueByName(name, ResType::PROF, isOverrideResMgr_); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetProfileDataByName error name = %{public}s", name); return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return hapManager_->GetProfileData(qd, len, outValue); } RState ResourceManagerImpl::GetRawFileFromHap(const std::string &rawFileName, size_t &len, std::unique_ptr<uint8_t[]> &outValue) { return hapManager_->FindRawFileFromHap(rawFileName, len, outValue); } RState ResourceManagerImpl::GetRawFileDescriptorFromHap(const std::string &rawFileName, RawFileDescriptor &descriptor) { return hapManager_->FindRawFileDescriptorFromHap(rawFileName, descriptor); } RState ResourceManagerImpl::IsLoadHap(std::string &hapPath) { if (hapManager_->IsLoadHap(hapPath)) { return SUCCESS; } return NOT_FOUND; } bool ResourceManagerImpl::IsFileExist(const std::string& path) { std::fstream inputFile; inputFile.open(path, std::ios::in); if (inputFile) { return true; } return false; } RState ResourceManagerImpl::GetRawFileList(const std::string &rawDirPath, std::vector<std::string>& rawfileList) { return hapManager_->GetRawFileList(rawDirPath, rawfileList); } std::string GetSuffix(const std::shared_ptr<HapResource::ValueUnderQualifierDir> qd) { const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (idItem == nullptr || idItem->resType_ != ResType::MEDIA) { return std::string(); } std::string mediaPath = idItem->value_; auto pos = mediaPath.find_last_of('.'); if (pos == std::string::npos) { return std::string(); } return mediaPath.substr(pos + 1); } RState ResourceManagerImpl::GetThemeIcon(const std::shared_ptr<IdItem> idItem, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { std::string iconName = idItem->GetItemResName(); std::string result = ThemePackManager::GetThemePackManager()->FindThemeIconResource( bundleInfo, iconName, userId); if (result.empty()) { RESMGR_HILOGD(RESMGR_TAG, "GetThemeIcon FAILED bundlename = %{public}s, modulename = %{public}s, iconName = %{public}s", bundleInfo.first.c_str(), bundleInfo.second.c_str(), iconName.c_str()); return ERROR_CODE_RES_ID_NOT_FOUND; } outValue = Utils::LoadResourceFile(result, len); return SUCCESS; } RState ResourceManagerImpl::GetThemeDrawable(const std::shared_ptr<IdItem> idItem, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t iconType, uint32_t density) { if (iconType == 0 && GetThemeMedia(idItem, len, outValue, density) == SUCCESS) { return SUCCESS; } else if (iconType == 1 && GetThemeIcon(idItem, len, outValue, density) == SUCCESS) { return SUCCESS; } else { // other type } return ERROR_CODE_RES_NOT_FOUND_BY_ID; } RState ResourceManagerImpl::GetDrawableInfoById(uint32_t id, std::string &type, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetDrawableInfoById id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } type = GetSuffix(qd); if (type.empty()) { RESMGR_HILOGE(RESMGR_TAG, "failed to get resourceType"); return ERROR_CODE_RES_NOT_FOUND_BY_ID; } return hapManager_->GetMediaData(qd, len, outValue); } RState ResourceManagerImpl::GetDrawableInfoByName(const char *name, std::string &type, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetDrawableInfoByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } type = GetSuffix(qd); if (type.empty()) { RESMGR_HILOGE(RESMGR_TAG, "failed to get resourceType"); return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } return hapManager_->GetMediaData(qd, len, outValue); } RState ResourceManagerImpl::GetDrawableInfoById(uint32_t id, std::tuple<std::string, size_t, std::string> &drawableInfo, std::unique_ptr<uint8_t[]> &outValue, uint32_t iconType, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetDrawableInfoById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } std::string type = GetSuffix(qd); if (type.empty()) { RESMGR_HILOGE(RESMGR_TAG, "failed to get resourceType"); return ERROR_CODE_RES_NOT_FOUND_BY_ID; } size_t len = 0; // find in theme const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); std::string themeMask = ThemePackManager::GetThemePackManager()->GetMask(); if (GetThemeDrawable(idItem, len, outValue, iconType, density) == SUCCESS) { drawableInfo = std::make_tuple(type, len, themeMask); return SUCCESS; } RState state = hapManager_->GetMediaData(qd, len, outValue); drawableInfo = std::make_tuple(type, len, themeMask); return state; } RState ResourceManagerImpl::GetDrawableInfoByName(const char *name, std::tuple<std::string, size_t, std::string> &drawableInfo, std::unique_ptr<uint8_t[]> &outValue, uint32_t iconType, uint32_t density) { if (!IsDensityValid(density)) { RESMGR_HILOGE(RESMGR_TAG, "density invalid"); return ERROR_CODE_INVALID_INPUT_PARAMETER; } auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA, isOverrideResMgr_, density); if (qd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetDrawableInfoByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } std::string type = GetSuffix(qd); if (type.empty()) { RESMGR_HILOGE(RESMGR_TAG, "failed to get resourceType"); return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } size_t len = 0; // find in theme std::string themeMask = ThemePackManager::GetThemePackManager()->GetMask(); const std::shared_ptr<IdItem> idItem = qd->GetIdItem(); if (GetThemeDrawable(idItem, len, outValue, iconType, density) == SUCCESS) { drawableInfo = std::make_tuple(type, len, themeMask); return SUCCESS; } RState state = hapManager_->GetMediaData(qd, len, outValue); drawableInfo = std::make_tuple(type, len, themeMask); return state; } RState ResourceManagerImpl::GetStringFormatById(uint32_t id, std::string &outValue, std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> &jsParams) { RState state = GetStringById(id, outValue); if (state != SUCCESS) { return state; } ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { return ERROR_CODE_RES_ID_FORMAT_ERROR; } return SUCCESS; } RState ResourceManagerImpl::GetStringFormatByName(const char *name, std::string &outValue, std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> &jsParams) { RState state = GetStringByName(name, outValue); if (state != SUCCESS) { return state; } ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { return ERROR_CODE_RES_NAME_FORMAT_ERROR; } return SUCCESS; } RState ResourceManagerImpl::GetFormatPluralStringById(std::string &outValue, uint32_t id, int quantity, std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> &jsParams) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueById(id, isOverrideResMgr_); if (vuqd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetFormatPluralStringById error id = %{public}d", id); return ERROR_CODE_RES_ID_NOT_FOUND; } RState rState = GetPluralString(vuqd, quantity, outValue); if (rState == ERROR_CODE_RES_REF_TOO_MUCH) { RESMGR_HILOGE(RESMGR_TAG, "find too much ref by plural id = %{public}d", id); return rState; } if (rState != SUCCESS) { RESMGR_HILOGE(RESMGR_TAG, "plural res not found, id = %{public}d", id); return ERROR_CODE_RES_NOT_FOUND_BY_ID; } ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { RESMGR_HILOGE(RESMGR_TAG, "format plural string error, id = %{public}d", id); return ERROR_CODE_RES_NAME_FORMAT_ERROR; } return SUCCESS; } RState ResourceManagerImpl::GetFormatPluralStringByName(std::string &outValue, const char *name, int quantity, std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> &jsParams) { const std::shared_ptr<HapResource::ValueUnderQualifierDir> vuqd = hapManager_->FindQualifierValueByName(name, ResType::PLURALS, isOverrideResMgr_); if (vuqd == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetFormatPluralStringByName error name = %{public}s", name); return ERROR_CODE_RES_NAME_NOT_FOUND; } RState rState = GetPluralString(vuqd, quantity, outValue); if (rState == ERROR_CODE_RES_REF_TOO_MUCH) { RESMGR_HILOGE(RESMGR_TAG, "find too much ref by plural name = %{public}s", name); return rState; } if (rState != SUCCESS) { RESMGR_HILOGE(RESMGR_TAG, "plural res not found, name = %{public}s", name); return ERROR_CODE_RES_NOT_FOUND_BY_NAME; } ResConfigImpl resConfig; GetResConfig(resConfig); if (!ReplacePlaceholderWithParams(outValue, resConfig, jsParams)) { RESMGR_HILOGE(RESMGR_TAG, "format plural string error, name = %{public}s", name); return ERROR_CODE_RES_NAME_FORMAT_ERROR; } return SUCCESS; } uint32_t ResourceManagerImpl::GetResourceLimitKeys() { if (hapManager_ == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "resource manager get limit keys failed, hapManager_ is nullptr"); return 0; } return hapManager_->GetResourceLimitKeys(); } RState ResourceManagerImpl::GetRawFdNdkFromHap(const std::string &name, RawFileDescriptor &descriptor) { return hapManager_->GetRawFd(name, descriptor); } RState ResourceManagerImpl::GetResId(const std::string &resTypeName, uint32_t &resId) { return hapManager_->GetResId(resTypeName, resId); } void ResourceManagerImpl::GetLocales(std::vector<std::string> &outValue, bool includeSystem) { hapManager_->GetLocales(outValue, includeSystem); } RState ResourceManagerImpl::GetThemeIconInfo(const std::string &iconName, size_t &len, std::unique_ptr<uint8_t[]> &outValue, const std::string &abilityName) { std::string result = ThemePackManager::GetThemePackManager()->FindThemeIconResource( bundleInfo, iconName, userId, abilityName); if (result.empty()) { RESMGR_HILOGD(RESMGR_TAG, "GetThemeIconInfo FAILED bundlename = %{public}s,", result.c_str()); return ERROR_CODE_RES_ID_NOT_FOUND; } outValue = Utils::LoadResourceFile(result, len); if (outValue == nullptr) { RESMGR_HILOGD(RESMGR_TAG, "LoadResourceFile FAILED"); return ERROR_CODE_RES_ID_NOT_FOUND; } return SUCCESS; } RState ResourceManagerImpl::GetThemeIcons(uint32_t resId, std::pair<std::unique_ptr<uint8_t[]>, size_t> &foregroundInfo, std::pair<std::unique_ptr<uint8_t[]>, size_t> &backgroundInfo, uint32_t density, const std::string &abilityName) { RState foreState = GetThemeIconInfo(FOREGROUND, foregroundInfo.second, foregroundInfo.first, abilityName); RState backState = GetThemeIconInfo(BACKGROUND, backgroundInfo.second, backgroundInfo.first, abilityName); if (foreState == SUCCESS && backState == SUCCESS) { return SUCCESS; } return ERROR_CODE_RES_ID_NOT_FOUND; } RState ResourceManagerImpl::GetDynamicIcon(const std::string &resName, std::pair<std::unique_ptr<uint8_t[]>, size_t> &iconInfo, uint32_t density) { return GetThemeIconInfo(resName, iconInfo.second, iconInfo.first); } std::string ResourceManagerImpl::GetThemeMask() { return ThemePackManager::GetThemePackManager()->GetMask(); } bool ResourceManagerImpl::HasIconInTheme(const std::string &bundleName) { return ThemePackManager::GetThemePackManager()->HasIconInTheme(bundleName, userId); } RState ResourceManagerImpl::GetOtherIconsInfo(const std::string &iconName, std::unique_ptr<uint8_t[]> &outValue, size_t &len, bool isGlobalMask) { std::string iconTag; if (iconName.find("icon_mask") != std::string::npos && isGlobalMask) { iconTag = "global_" + iconName; } else { iconTag = "other_icons_" + iconName; } RState result = ThemePackManager::GetThemePackManager()->GetThemeIconFromCache(iconTag, outValue, len); if (result == SUCCESS) { return SUCCESS; } return ThemePackManager::GetThemePackManager()->GetOtherIconsInfo(iconName, outValue, len, isGlobalMask, userId); } RState ResourceManagerImpl::IsRawDirFromHap(const std::string &pathName, bool &outValue) { return hapManager_->IsRawDirFromHap(pathName, outValue); } std::shared_ptr<HapManager> ResourceManagerImpl::GetHapManager() { return hapManager_; } std::shared_ptr<ResourceManager> ResourceManagerImpl::GetOverrideResourceManager( std::shared_ptr<ResConfig> overrideResConfig) { ResourceManagerImpl *impl = new (std::nothrow) ResourceManagerImpl(true); if (impl == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "new ResourceManagerImpl failed when GetOverrideResourceManager"); return nullptr; } if (!impl->Init(this->GetHapManager())) { delete (impl); return nullptr; } std::shared_ptr<ResourceManager> overrideResMgr(impl); if (overrideResMgr == nullptr) { RESMGR_HILOGE(RESMGR_TAG, "GetOverrideResourceManager failed bundleName = %{public}s, moduleName = %{public}s", this->bundleInfo.first.c_str(), this->bundleInfo.second.c_str()); return nullptr; } overrideResMgr->bundleInfo.first = this->bundleInfo.first; overrideResMgr->bundleInfo.second = this->bundleInfo.second; if (overrideResConfig && overrideResMgr->UpdateOverrideResConfig(*overrideResConfig) != SUCCESS) { RESMGR_HILOGE(RESMGR_TAG, "GetOverrideResourceManager UpdateOverrideResConfig failed bundleName = %{public}s, \ moduleName = %{public}s", this->bundleInfo.first.c_str(), this->bundleInfo.second.c_str()); return nullptr; } return overrideResMgr; } } // namespace Resource } // namespace Global } // namespace OHOS