From cbb0ee6c2fa0b8f0770e63bec4d52a32ecfe568f Mon Sep 17 00:00:00 2001 From: s30030188 Date: Thu, 12 Jun 2025 21:37:20 +0800 Subject: [PATCH] support get other hap plugin Signed-off-by: s30030188 --- .../js/napi/application/js_application.cpp | 91 +++++++++++++++++++ .../js/napi/application/js_application.h | 4 + .../bundle_mgr_helper.cpp | 13 +++ .../ability_runtime/context/context_impl.cpp | 71 +++++++++++++-- .../napi_module/application/js_application.h | 2 + .../bundle_mgr_helper.h | 3 + .../ability_runtime/context/context_impl.h | 6 ++ .../bundle_mgr_helper_second_test.cpp | 14 +++ 8 files changed, 194 insertions(+), 10 deletions(-) diff --git a/frameworks/js/napi/application/js_application.cpp b/frameworks/js/napi/application/js_application.cpp index 7f9a64e214..7e5394e1ae 100644 --- a/frameworks/js/napi/application/js_application.cpp +++ b/frameworks/js/napi/application/js_application.cpp @@ -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); + if (inputContextPtr == nullptr) { + ThrowInvalidParamError(env, "Parse param context failed, must be a context."); + return CreateJsUndefined(env); + } + + std::shared_ptr> moduleContext = std::make_shared>(); + std::shared_ptr contextImpl = std::make_shared(); + 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 diff --git a/frameworks/js/napi/application/js_application.h b/frameworks/js/napi/application/js_application.h index 13164547bb..c7b62a8334 100644 --- a/frameworks/js/napi/application/js_application.h +++ b/frameworks/js/napi/application/js_application.h @@ -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); void SetCreateCompleteCallback(std::shared_ptr> 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); diff --git a/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp b/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp index 94c8a8e6dd..0b5ba7b561 100644 --- a/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp +++ b/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp @@ -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 \ No newline at end of file diff --git a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp index cab45fda83..fd846ca59d 100644 --- a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp +++ b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp @@ -485,7 +485,14 @@ std::shared_ptr ContextImpl::CreatePluginContext(const std::string &plu return nullptr; } - auto appContext = std::make_shared(); + return WrapContext(pluginBundleName, moduleName, inputContext, pluginBundleInfo, inputContext->GetBundleName()); +} + +std::shared_ptr ContextImpl::WrapContext(const std::string &pluginBundleName, const std::string &moduleName, + std::shared_ptr inputContext, AppExecFwk::PluginBundleInfo& pluginBundleInfo, + const std::string &hostBundleName) +{ + std::shared_ptr appContext = std::make_shared(); appContext->SetConfiguration(config_); appContext->SetProcessName(processName_); appContext->isPlugin_ = true; @@ -499,7 +506,6 @@ std::shared_ptr 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 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 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 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 ContextImpl::CreateTargetPluginContext(const std::string &hostBundName, + const std::string &pluginBundleName, const std::string &moduleName, std::shared_ptr 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 diff --git a/frameworks/simulator/napi_module/application/js_application.h b/frameworks/simulator/napi_module/application/js_application.h index 66b3d462a7..756b19a0bf 100644 --- a/frameworks/simulator/napi_module/application/js_application.h +++ b/frameworks/simulator/napi_module/application/js_application.h @@ -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); void SetCreateCompleteCallback(std::shared_ptr> contextPtr, NapiAsyncTask::CompleteCallback &complete); diff --git a/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h b/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h index 3862786ed6..66423c1b6a 100644 --- a/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h +++ b/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h @@ -125,6 +125,9 @@ public: int32_t userId, BundleInfo &bundleInfo); ErrCode GetLauncherAbilityInfoSync(const std::string &bundleName, int32_t userId, std::vector &abilityInfo); + ErrCode GetPluginInfoForTarget(const std::string &hostBundleName, const std::string &pluginBundleName, + int32_t userId, PluginBundleInfo &pluginBundleInfo); + private: sptr Connect(); sptr Connect(bool checkBmsReady); diff --git a/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h b/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h index 5e82b63798..3e61977f84 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h @@ -213,6 +213,9 @@ public: std::shared_ptr CreatePluginContext(const std::string &pluginBundleName, const std::string &moduleName, std::shared_ptr inputContext); + std::shared_ptr CreateTargetPluginContext(const std::string &hostBundName, + const std::string &pluginBundleName, const std::string &moduleName, std::shared_ptr inputContext); + std::string GetBundleNameWithContext(std::shared_ptr inputContext = nullptr) const; /** @@ -560,6 +563,9 @@ private: static std::mutex getDisplayConfigCallbackMutex_; static GetDisplayConfigCallback getDisplayConfigCallback_; #endif + std::shared_ptr WrapContext(const std::string &pluginBundleName, const std::string &moduleName, + std::shared_ptr inputContext, AppExecFwk::PluginBundleInfo &pluginBundleInfo, + const std::string &hostBundleName); }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/test/unittest/bundle_mgr_helper_second_test/bundle_mgr_helper_second_test.cpp b/test/unittest/bundle_mgr_helper_second_test/bundle_mgr_helper_second_test.cpp index 31ad83dda6..555b680ac6 100755 --- a/test/unittest/bundle_mgr_helper_second_test/bundle_mgr_helper_second_test.cpp +++ b/test/unittest/bundle_mgr_helper_second_test/bundle_mgr_helper_second_test.cpp @@ -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 \ No newline at end of file