mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 12:43:16 -04:00
support get other hap plugin
Signed-off-by: s30030188 <songjindian1@h-partners.com>
This commit is contained in:
@@ -34,6 +34,7 @@ namespace {
|
||||
constexpr size_t ARGC_ONE = 1;
|
||||
constexpr size_t ARGC_TWO = 2;
|
||||
constexpr size_t ARGC_THREE = 3;
|
||||
constexpr size_t ARGC_FOUR = 4;
|
||||
constexpr const char* PERMISSION_GET_BUNDLE_INFO = "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED";
|
||||
}
|
||||
void JsApplication::Finalizer(napi_env env, void *data, void *hint)
|
||||
@@ -81,6 +82,10 @@ napi_value JsApplication::CreatePluginModuleContext(napi_env env, napi_callback_
|
||||
GET_NAPI_INFO_AND_CALL(env, info, JsApplication, OnCreatePluginModuleContext);
|
||||
}
|
||||
|
||||
napi_value JsApplication::CreatePluginModuleContextForBundle(napi_env env, napi_callback_info info)
|
||||
{
|
||||
GET_NAPI_INFO_AND_CALL(env, info, JsApplication, OnCreatePluginModuleContextForBundle);
|
||||
}
|
||||
|
||||
napi_value JsApplication::OnCreatePluginModuleContext(napi_env env, NapiCallbackInfo &info)
|
||||
{
|
||||
@@ -143,6 +148,89 @@ napi_value JsApplication::OnCreatePluginModuleContext(napi_env env, NapiCallback
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value JsApplication::OnCreatePluginModuleContextForBundle(napi_env env, NapiCallbackInfo &info)
|
||||
{
|
||||
std::string moduleName = "";
|
||||
std::string pluginBundleName = "";
|
||||
std::string hostBundleName = "";
|
||||
if (!VerifyCreatePluginContextParams(env, info, moduleName, pluginBundleName, hostBundleName)) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "invalid params");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
|
||||
bool stageMode = false;
|
||||
napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[ARGC_ZERO], stageMode);
|
||||
if (status != napi_ok || !stageMode) {
|
||||
ThrowInvalidParamError(env, "Parse param context failed, must be a context of stageMode.");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
|
||||
auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[ARGC_ZERO]);
|
||||
if (context == nullptr) {
|
||||
ThrowInvalidParamError(env, "Parse param context failed, must not be nullptr.");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
auto inputContextPtr = Context::ConvertTo<Context>(context);
|
||||
if (inputContextPtr == nullptr) {
|
||||
ThrowInvalidParamError(env, "Parse param context failed, must be a context.");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
|
||||
std::shared_ptr<std::shared_ptr<Context>> moduleContext = std::make_shared<std::shared_ptr<Context>>();
|
||||
std::shared_ptr<ContextImpl> contextImpl = std::make_shared<ContextImpl>();
|
||||
if (contextImpl == nullptr) {
|
||||
ThrowInvalidParamError(env, "create context failed.");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
contextImpl->SetProcessName(context->GetProcessName());
|
||||
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "moduleName: %{public}s, pluginBundleName: %{public}s, bundleName: %{public}s",
|
||||
moduleName.c_str(), pluginBundleName.c_str(), hostBundleName.c_str());
|
||||
NapiAsyncTask::ExecuteCallback execute = [moduleName, pluginBundleName, hostBundleName, contextImpl,
|
||||
moduleContext, inputContextPtr]() {
|
||||
if (contextImpl != nullptr) {
|
||||
*moduleContext = contextImpl->CreateTargetPluginContext(
|
||||
hostBundleName, pluginBundleName, moduleName, inputContextPtr);
|
||||
}
|
||||
};
|
||||
|
||||
NapiAsyncTask::CompleteCallback complete;
|
||||
SetCreateCompleteCallback(moduleContext, complete);
|
||||
|
||||
napi_value result = nullptr;
|
||||
NapiAsyncTask::ScheduleHighQos("JsApplication::OnCreatePluginModuleContext",
|
||||
env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JsApplication::VerifyCreatePluginContextParams(napi_env env, NapiCallbackInfo &info, std::string &moduleName,
|
||||
std::string &pluginBundleName, std::string &hostBundleName)
|
||||
{
|
||||
if (info.argc != ARGC_FOUR) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "wrong number of params");
|
||||
ThrowTooFewParametersError(env);
|
||||
return false;
|
||||
}
|
||||
if (!ConvertFromJsValue(env, info.argv[ARGC_TWO], moduleName)
|
||||
|| !ConvertFromJsValue(env, info.argv[ARGC_ONE], pluginBundleName)
|
||||
|| !ConvertFromJsValue(env, info.argv[ARGC_THREE], hostBundleName)) {
|
||||
ThrowInvalidParamError(env, "Parse param failed, moduleName and pluginBundleName must be string.");
|
||||
return false;
|
||||
}
|
||||
if (!CheckCallerIsSystemApp()) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "no system app");
|
||||
ThrowNotSystemAppError(env);
|
||||
return false;
|
||||
}
|
||||
if (!CheckCallerPermission(PERMISSION_GET_BUNDLE_INFO)) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "no permission");
|
||||
ThrowNoPermissionError(env, PERMISSION_GET_BUNDLE_INFO);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
napi_value JsApplication::OnCreateModuleContext(napi_env env, NapiCallbackInfo &info)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "Called");
|
||||
@@ -511,6 +599,9 @@ napi_value ApplicationInit(napi_env env, napi_value exportObj)
|
||||
BindNativeFunction(env, exportObj, "demoteCurrentFromCandidateMasterProcess", moduleName,
|
||||
JsApplication::DemoteCurrentFromCandidateMasterProcess);
|
||||
|
||||
BindNativeFunction(env, exportObj, "createPluginModuleContextForHostBundle", moduleName,
|
||||
JsApplication::CreatePluginModuleContextForBundle);
|
||||
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
|
||||
@@ -37,11 +37,13 @@ public:
|
||||
static napi_value CreatePluginModuleContext(napi_env env, napi_callback_info info);
|
||||
static napi_value PromoteCurrentToCandidateMasterProcess(napi_env env, napi_callback_info info);
|
||||
static napi_value DemoteCurrentFromCandidateMasterProcess(napi_env env, napi_callback_info info);
|
||||
static napi_value CreatePluginModuleContextForBundle(napi_env env, napi_callback_info info);
|
||||
|
||||
private:
|
||||
napi_value OnCreateModuleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreateBundleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreatePluginModuleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreatePluginModuleContextForBundle(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value CreateJsContext(napi_env env, const std::shared_ptr<Context> &context);
|
||||
void SetCreateCompleteCallback(std::shared_ptr<std::shared_ptr<Context>> contextPtr,
|
||||
NapiAsyncTask::CompleteCallback &complete);
|
||||
@@ -50,6 +52,8 @@ private:
|
||||
napi_value OnGetApplicationContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnPromoteCurrentToCandidateMasterProcess(napi_env env, NapiCallbackInfo& info);
|
||||
napi_value OnDemoteCurrentFromCandidateMasterProcess(napi_env env, NapiCallbackInfo& info);
|
||||
bool VerifyCreatePluginContextParams(napi_env env, NapiCallbackInfo &info, std::string &moduleName,
|
||||
std::string &pluginBundleName, std::string &hostBundleName);
|
||||
};
|
||||
|
||||
napi_value ApplicationInit(napi_env env, napi_value exportObj);
|
||||
|
||||
@@ -1118,5 +1118,18 @@ ErrCode BundleMgrHelper::GetLauncherAbilityInfoSync(const std::string &bundleNam
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
return bundleMgr->GetLauncherAbilityInfoSync(bundleName, userId, abilityInfo);
|
||||
}
|
||||
|
||||
ErrCode BundleMgrHelper::GetPluginInfoForTarget(const std::string &hostBundleName,
|
||||
const std::string &pluginBundleName, int32_t userId, PluginBundleInfo &pluginBundleInfo)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::BUNDLEMGRHELPER, "called");
|
||||
auto bundleMgr = Connect();
|
||||
if (bundleMgr == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::BUNDLEMGRHELPER, "null bundleMgr");
|
||||
return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
|
||||
}
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
return bundleMgr->GetPluginInfo(hostBundleName, pluginBundleName, userId, pluginBundleInfo);
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
@@ -485,7 +485,14 @@ std::shared_ptr<Context> ContextImpl::CreatePluginContext(const std::string &plu
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto appContext = std::make_shared<ContextImpl>();
|
||||
return WrapContext(pluginBundleName, moduleName, inputContext, pluginBundleInfo, inputContext->GetBundleName());
|
||||
}
|
||||
|
||||
std::shared_ptr<Context> ContextImpl::WrapContext(const std::string &pluginBundleName, const std::string &moduleName,
|
||||
std::shared_ptr<Context> inputContext, AppExecFwk::PluginBundleInfo& pluginBundleInfo,
|
||||
const std::string &hostBundleName)
|
||||
{
|
||||
std::shared_ptr<ContextImpl> appContext = std::make_shared<ContextImpl>();
|
||||
appContext->SetConfiguration(config_);
|
||||
appContext->SetProcessName(processName_);
|
||||
appContext->isPlugin_ = true;
|
||||
@@ -499,7 +506,6 @@ std::shared_ptr<Context> ContextImpl::CreatePluginContext(const std::string &plu
|
||||
if (resourceManager == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) {
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "moduleName: %{public}s", pluginModuleInfo.moduleName.c_str());
|
||||
std::string loadPath = pluginModuleInfo.hapPath;
|
||||
@@ -507,14 +513,24 @@ std::shared_ptr<Context> ContextImpl::CreatePluginContext(const std::string &plu
|
||||
if (loadPath.empty()) {
|
||||
continue;
|
||||
}
|
||||
std::regex pattern(std::string(ABS_CODE_PATH) + std::string(FILE_SEPARATOR) + inputContext->GetBundleName());
|
||||
loadPath = std::regex_replace(loadPath, pattern, LOCAL_CODE_PATH);
|
||||
bool newCreate = false;
|
||||
std::shared_ptr<AbilityBase::Extractor> extractor =
|
||||
AbilityBase::ExtractorUtil::GetExtractor(loadPath, newCreate, true);
|
||||
if (!extractor) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "hapPath[%{private}s]", hapPath.c_str());
|
||||
return nullptr;
|
||||
if (moduleName != pluginModuleInfo.moduleName) {
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "not the target plugin");
|
||||
continue;
|
||||
}
|
||||
if (inputContext->GetBundleName() == hostBundleName) {
|
||||
std::regex pattern(
|
||||
std::string(ABS_CODE_PATH) + std::string(FILE_SEPARATOR) + inputContext->GetBundleName());
|
||||
loadPath = std::regex_replace(loadPath, pattern, LOCAL_CODE_PATH);
|
||||
bool newCreate = false;
|
||||
std::shared_ptr<AbilityBase::Extractor> extractor =
|
||||
AbilityBase::ExtractorUtil::GetExtractor(loadPath, newCreate, true);
|
||||
if (!extractor) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "hapPath[%{private}s]", hapPath.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
std::regex pattern(ABS_CODE_PATH);
|
||||
loadPath = std::regex_replace(loadPath, pattern, LOCAL_BUNDLES);
|
||||
}
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "loadPath: %{public}s", loadPath.c_str());
|
||||
if (!resourceManager->AddResource(loadPath.c_str())) {
|
||||
@@ -1798,5 +1814,40 @@ bool ContextImpl::GetDisplayConfig(uint64_t displayId, float &density, std::stri
|
||||
return getDisplayConfigCallback_(displayId, density, directionStr);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<Context> ContextImpl::CreateTargetPluginContext(const std::string &hostBundName,
|
||||
const std::string &pluginBundleName, const std::string &moduleName, std::shared_ptr<Context> inputContext)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
if (hostBundName.empty() || pluginBundleName.empty() || moduleName.empty() || inputContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "input params is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TAG_LOGD(AAFwkTag::APPKIT, "hostBundName: %{public}s, pluginBundleName: %{public}s, moduleName: %{public}s",
|
||||
hostBundName.c_str(), pluginBundleName.c_str(), moduleName.c_str());
|
||||
|
||||
int32_t errCode = GetBundleManager();
|
||||
if (errCode != ERR_OK) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "GetBundleManager failed, errCode: %{public}d", errCode);
|
||||
return nullptr;
|
||||
}
|
||||
int accountId = GetCurrentAccountId();
|
||||
if (accountId == 0) {
|
||||
accountId = GetCurrentActiveAccountId();
|
||||
}
|
||||
if (bundleMgr_ == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "null bundleMgr_");
|
||||
return nullptr;
|
||||
}
|
||||
AppExecFwk::PluginBundleInfo pluginBundleInfo;
|
||||
errCode = bundleMgr_->GetPluginInfoForTarget(hostBundName, pluginBundleName, accountId, pluginBundleInfo);
|
||||
if (errCode != ERR_OK) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "GetPluginInfosForTarget failed, errCode: %{public}d", errCode);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WrapContext(pluginBundleName, moduleName, inputContext, pluginBundleInfo, hostBundName);
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -32,11 +32,13 @@ public:
|
||||
static napi_value CreateBundleContext(napi_env env, napi_callback_info info);
|
||||
static napi_value GetApplicationContext(napi_env env, napi_callback_info info);
|
||||
static napi_value CreatePluginModuleContext(napi_env env, napi_callback_info info);
|
||||
static napi_value CreateOtherPluginModuleContext(napi_env env, napi_callback_info info);
|
||||
|
||||
private:
|
||||
napi_value OnCreateModuleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreateBundleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreatePluginModuleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value OnCreateOtherPluginModuleContext(napi_env env, NapiCallbackInfo &info);
|
||||
napi_value CreateJsContext(napi_env env, const std::shared_ptr<Context> &context);
|
||||
void SetCreateCompleteCallback(std::shared_ptr<std::shared_ptr<Context>> contextPtr,
|
||||
NapiAsyncTask::CompleteCallback &complete);
|
||||
|
||||
@@ -125,6 +125,9 @@ public:
|
||||
int32_t userId, BundleInfo &bundleInfo);
|
||||
ErrCode GetLauncherAbilityInfoSync(const std::string &bundleName, int32_t userId,
|
||||
std::vector<AbilityInfo> &abilityInfo);
|
||||
ErrCode GetPluginInfoForTarget(const std::string &hostBundleName, const std::string &pluginBundleName,
|
||||
int32_t userId, PluginBundleInfo &pluginBundleInfo);
|
||||
|
||||
private:
|
||||
sptr<IBundleMgr> Connect();
|
||||
sptr<IBundleMgr> Connect(bool checkBmsReady);
|
||||
|
||||
@@ -213,6 +213,9 @@ public:
|
||||
std::shared_ptr<Context> CreatePluginContext(const std::string &pluginBundleName,
|
||||
const std::string &moduleName, std::shared_ptr<Context> inputContext);
|
||||
|
||||
std::shared_ptr<Context> CreateTargetPluginContext(const std::string &hostBundName,
|
||||
const std::string &pluginBundleName, const std::string &moduleName, std::shared_ptr<Context> inputContext);
|
||||
|
||||
std::string GetBundleNameWithContext(std::shared_ptr<Context> inputContext = nullptr) const;
|
||||
|
||||
/**
|
||||
@@ -560,6 +563,9 @@ private:
|
||||
static std::mutex getDisplayConfigCallbackMutex_;
|
||||
static GetDisplayConfigCallback getDisplayConfigCallback_;
|
||||
#endif
|
||||
std::shared_ptr<Context> WrapContext(const std::string &pluginBundleName, const std::string &moduleName,
|
||||
std::shared_ptr<Context> inputContext, AppExecFwk::PluginBundleInfo &pluginBundleInfo,
|
||||
const std::string &hostBundleName);
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -99,5 +99,19 @@ HWTEST_F(BundleMgrHelperSecondTest, BundleMgrHelperSecondTest_GetDataDir_001, Te
|
||||
auto ret = bundleMgrHelper->GetDataDir(bundleName, appIndex);
|
||||
EXPECT_NE(ret, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BundleMgrHelperSecondTest_GetPluginInfoForTarget_001
|
||||
* @tc.desc: GetDataDir
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(BundleMgrHelperSecondTest, BundleMgrHelperSecondTest_GetPluginInfoForTarget_001, TestSize.Level1)
|
||||
{
|
||||
std::string hostBundleName = "hostBundleName";
|
||||
std::string pluginBundleName = "pluginBundleName";
|
||||
AppExecFwk::PluginBundleInfo pluginBundleInfo;
|
||||
auto ret = bundleMgrHelper->GetPluginInfoForTarget(hostBundleName, pluginBundleName, 0, pluginBundleInfo);
|
||||
EXPECT_NE(ret, ERR_OK);
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
Reference in New Issue
Block a user