支持运行时资源加载

Signed-off-by: huangjie <huangjie125@huawei.com>
This commit is contained in:
huangjie 2023-06-12 17:52:39 +08:00
parent c9d966210b
commit 0caffc2eb2
11 changed files with 174 additions and 5 deletions

View File

@ -80,6 +80,29 @@ public:
*/
bool RemoveResource(const std::string &path, const std::vector<std::string> &overlayPaths);
/**
* Add the overlay resource for current application
*
* @param path the overlay resource path
* @return true if add resource path success, else false
*/
bool AddAppOverlay(const std::string &path);
/**
* Remove the overlay resource for current application
*
* @param path the overlay resource path
* @return true if add resource path success, else false
*/
bool RemoveAppOverlay(const std::string &path);
/**
* Obtain the hap path of the current application
*
* @return the current application hap path
*/
std::string GetValidAppPath();
/**
* Find resource by resource id
* @param id the resource id

View File

@ -69,6 +69,22 @@ public:
*/
virtual bool RemoveResource(const std::string &path, const std::vector<std::string> &overlayPaths);
/**
* Add the overlay resource for current application
*
* @param path the overlay resource path
* @return true if add resource path success, else false
*/
virtual bool AddAppOverlay(const std::string &path);
/**
* Remove the overlay resource for current application
*
* @param path the overlay resource path
* @return true if add resource path success, else false
*/
virtual bool RemoveAppOverlay(const std::string &path);
/**
* Update the resConfig
* @param resConfig the resource config

View File

@ -193,7 +193,8 @@ const HapResource::ValueUnderQualifierDir *HapManager::GetBestMatchResource(std:
const HapResource::ValueUnderQualifierDir *result = nullptr;
const HapResource::ValueUnderQualifierDir *overlayResult = nullptr;
const ResConfigImpl *currentResConfig = this->resConfig_;
for (auto iter = candidates.begin(); iter != candidates.end(); iter++) {
// When there are multiple overlays, reverse the search to find the first match resource.
for (auto iter = candidates.rbegin(); iter != candidates.rend(); iter++) {
const std::vector<HapResource::ValueUnderQualifierDir *> paths = (*iter)->GetLimitPathsConst();
size_t len = paths.size();
size_t i = 0;
@ -307,7 +308,7 @@ bool HapManager::AddResource(const std::string &path, const std::vector<std::str
std::vector<std::string> targetOverlay = loadedHapPaths_[path];
if (!targetOverlay.empty() && targetOverlay == overlayPaths) {
HILOG_INFO("the overlay for %{public}s already been loaded", path.c_str());
return false;
return true;
}
loadedHapPaths_[path] = overlayPaths;
std::unordered_map<std::string, HapResource *> result = HapResource::LoadOverlays(path, overlayPaths,
@ -321,6 +322,49 @@ bool HapManager::AddResource(const std::string &path, const std::vector<std::str
return false;
}
std::string HapManager::GetValidAppPath()
{
std::string appPath;
for (auto iter = hapResources_.rbegin(); iter != hapResources_.rend(); iter++) {
const std::string tempPath = (*iter)->GetIndexPath();
if ((*iter)->IsSystemResource() || (*iter)->IsOverlayResource()) {
continue;
}
appPath = tempPath;
}
return appPath;
}
bool HapManager::AddAppOverlay(const std::string &overlayPath)
{
HILOG_INFO("AddAppOverlay overlayPath = %{public}s", overlayPath.c_str());
char outPath[PATH_MAX + 1] = {0};
Utils::CanonicalizePath(overlayPath.c_str(), outPath, PATH_MAX);
if (outPath[0] == '\0') {
HILOG_ERROR("invalid overlayPath, %{public}s", overlayPath.c_str());
return false;
}
std::vector<std::string> overlayPaths;
overlayPaths.emplace_back(outPath);
std::string appPath = GetValidAppPath();
return AddResource(appPath, overlayPaths);
}
bool HapManager::RemoveAppOverlay(const std::string &overlayPath)
{
HILOG_INFO("RemoveAppOverlay overlayPath = %{public}s", overlayPath.c_str());
char outPath[PATH_MAX + 1] = {0};
Utils::CanonicalizePath(overlayPath.c_str(), outPath, PATH_MAX);
if (outPath[0] == '\0') {
HILOG_ERROR("invalid overlayPath, %{public}s", overlayPath.c_str());
return false;
}
std::vector<std::string> overlayPaths;
overlayPaths.emplace_back(outPath);
std::string appPath = GetValidAppPath();
return RemoveResource(appPath, overlayPaths);
}
HapManager::~HapManager()
{
for (size_t i = 0; i < hapResources_.size(); ++i) {

View File

@ -832,6 +832,16 @@ bool ResourceManagerImpl::RemoveResource(const std::string &path, const std::vec
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::UpdateResConfig(ResConfig &resConfig)
{
#if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)

View File

@ -173,6 +173,10 @@ public:
std::vector<std::tuple<NapiValueType, std::string>> &jsParams) = 0;
virtual uint32_t GetResourceLimitKeys() = 0;
virtual bool AddAppOverlay(const std::string &path) = 0;
virtual bool RemoveAppOverlay(const std::string &path) = 0;
};
EXPORT_FUNC ResourceManager *CreateResourceManager();

View File

@ -41,6 +41,7 @@ enum RState {
ERROR_CODE_RES_ID_FORMAT_ERROR = 9001007,
ERROR_CODE_RES_NAME_FORMAT_ERROR = 9001008,
ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED = 9001009,
ERROR_CODE_OVERLAY_RES_PATH_INVALID = 9001010,
};
} // namespace Resource
} // namespace Global

View File

@ -150,6 +150,9 @@ private:
static napi_value WrapResourceManager(napi_env env, std::shared_ptr<ResourceManagerAddon> &addon);
static napi_value AddResource(napi_env env, napi_callback_info info);
static napi_value RemoveResource(napi_env env, napi_callback_info info);
std::string bundleName_;
std::shared_ptr<ResourceManager> resMgr_;
std::shared_ptr<AbilityRuntime::Context> context_;

View File

@ -62,6 +62,10 @@ private:
static napi_value GetColorByNameSync(napi_env env, napi_callback_info info);
static napi_value AddResource(napi_env env, napi_callback_info info);
static napi_value RemoveResource(napi_env env, napi_callback_info info);
static int32_t InitIdResourceAddon(napi_env env, napi_callback_info info,
std::unique_ptr<ResMgrDataContext> &dataContext);

View File

@ -149,7 +149,9 @@ bool ResourceManagerAddon::Init(napi_env env)
DECLARE_NAPI_FUNCTION("getColor", GetColor),
DECLARE_NAPI_FUNCTION("getColorByName", GetColorByName),
DECLARE_NAPI_FUNCTION("getColorSync", GetColorSync),
DECLARE_NAPI_FUNCTION("getColorByNameSync", GetColorByNameSync)
DECLARE_NAPI_FUNCTION("getColorByNameSync", GetColorByNameSync),
DECLARE_NAPI_FUNCTION("addResource", AddResource),
DECLARE_NAPI_FUNCTION("removeResource", RemoveResource)
};
napi_value constructor;
@ -411,6 +413,18 @@ napi_value ResourceManagerAddon::GetColorByNameSync(napi_env env, napi_callback_
auto addon = ResMgrDataContext::GetResourceManagerAddon(env, info);
return addon->napiContext_->ContextGetResource(env, info, "GetColorByNameSync", FunctionType::SYNC);
}
napi_value ResourceManagerAddon::AddResource(napi_env env, napi_callback_info info)
{
auto addon = ResMgrDataContext::GetResourceManagerAddon(env, info);
return addon->napiContext_->ContextGetResource(env, info, "AddResource", FunctionType::SYNC);
}
napi_value ResourceManagerAddon::RemoveResource(napi_env env, napi_callback_info info)
{
auto addon = ResMgrDataContext::GetResourceManagerAddon(env, info);
return addon->napiContext_->ContextGetResource(env, info, "RemoveResource", FunctionType::SYNC);
}
} // namespace Resource
} // namespace Global
} // namespace OHOS

View File

@ -44,7 +44,9 @@ std::unordered_map<std::string, std::function<napi_value(napi_env&, napi_callbac
{"GetDrawableDescriptor", std::bind(&ResourceManagerNapiSyncImpl::GetDrawableDescriptor, _1, _2)},
{"GetDrawableDescriptorByName", std::bind(&ResourceManagerNapiSyncImpl::GetDrawableDescriptorByName, _1, _2)},
{"GetColorSync", std::bind(&ResourceManagerNapiSyncImpl::GetColorSync, _1, _2)},
{"GetColorByNameSync", std::bind(&ResourceManagerNapiSyncImpl::GetColorByNameSync, _1, _2)}
{"GetColorByNameSync", std::bind(&ResourceManagerNapiSyncImpl::GetColorByNameSync, _1, _2)},
{"AddResource", std::bind(&ResourceManagerNapiSyncImpl::AddResource, _1, _2)},
{"RemoveResource", std::bind(&ResourceManagerNapiSyncImpl::RemoveResource, _1, _2)}
};
napi_value ResourceManagerNapiSyncImpl::GetResource(napi_env env, napi_callback_info info,
@ -62,7 +64,7 @@ napi_value ResourceManagerNapiSyncImpl::GetRawFileList(napi_env env, napi_callba
{
GET_PARAMS(env, info, PARAMS_NUM_TWO);
if (!ResourceManagerNapiUtils::ResourceManagerNapiUtils::IsNapiString(env, info)) {
if (!ResourceManagerNapiUtils::IsNapiString(env, info)) {
ResourceManagerNapiUtils::NapiThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
return nullptr;
}
@ -544,6 +546,52 @@ napi_value ResourceManagerNapiSyncImpl::GetDrawableDescriptorByName(napi_env env
}
return Ace::Napi::JsDrawableDescriptor::ToNapi(env, drawableDescriptor.release(), drawableType);
}
std::shared_ptr<ResourceManager> GetNativeResoruceManager(napi_env env, napi_callback_info info)
{
auto addon = ResMgrDataContext::GetResourceManagerAddon(env, info);
if (addon == nullptr) {
HiLog::Error(LABEL, "Failed to get addon_ in GetNativeResoruceManager");
return nullptr;
}
return addon->GetResMgr();
}
napi_value ResourceManagerNapiSyncImpl::AddResource(napi_env env, napi_callback_info info)
{
GET_PARAMS(env, info, PARAMS_NUM_TWO);
if (!ResourceManagerNapiUtils::IsNapiString(env, info)) {
ResourceManagerNapiUtils::NapiThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
return nullptr;
}
auto dataContext = std::make_unique<ResMgrDataContext>();
dataContext->path_ = ResourceManagerNapiUtils::GetResNameOrPath(env, argc, argv);
auto resMgr = GetNativeResoruceManager(env, info);
if (!resMgr->AddAppOverlay(dataContext->path_)) {
HiLog::Error(LABEL, "Failed to add overlay path = %{public}s", dataContext->path_.c_str());
ResourceManagerNapiUtils::NapiThrow(env, ERROR_CODE_OVERLAY_RES_PATH_INVALID);
return nullptr;
}
return nullptr;
}
napi_value ResourceManagerNapiSyncImpl::RemoveResource(napi_env env, napi_callback_info info)
{
GET_PARAMS(env, info, PARAMS_NUM_TWO);
if (!ResourceManagerNapiUtils::IsNapiString(env, info)) {
ResourceManagerNapiUtils::NapiThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
return nullptr;
}
auto dataContext = std::make_unique<ResMgrDataContext>();
dataContext->path_ = ResourceManagerNapiUtils::GetResNameOrPath(env, argc, argv);
auto resMgr = GetNativeResoruceManager(env, info);
if (!resMgr->RemoveAppOverlay(dataContext->path_)) {
HiLog::Error(LABEL, "Failed to add overlay path = %{public}s", dataContext->path_.c_str());
ResourceManagerNapiUtils::NapiThrow(env, ERROR_CODE_OVERLAY_RES_PATH_INVALID);
return nullptr;
}
return nullptr;
}
} // namespace Resource
} // namespace Global
} // namespace OHOS

View File

@ -35,6 +35,7 @@ const std::unordered_map<int32_t, std::string> ResourceManagerNapiUtils::ErrorCo
{ERROR_CODE_RES_ID_FORMAT_ERROR, "Resource obtained by resId formatting error"},
{ERROR_CODE_RES_NAME_FORMAT_ERROR, "Resource obtained by resName formatting error"},
{ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED, "Get system resource manager failed"},
{ERROR_CODE_OVERLAY_RES_PATH_INVALID, "Overlay resource path is invalid"},
{ERROR, "Unknow error"}
};
@ -211,6 +212,7 @@ napi_value ResourceManagerNapiUtils::CreateJsRawFd(napi_env env, ResMgrDataConte
ResourceManager::RawFileDescriptor descriptor;
RState state = context.addon_->GetResMgr()->GetRawFileDescriptorFromHap(context.path_, descriptor);
if (state != RState::SUCCESS) {
context.SetErrorMsg("Failed to get descriptor", false, state);
return nullptr;
}
napi_value result;