diff --git a/frameworks/js/napi/application/js_application.cpp b/frameworks/js/napi/application/js_application.cpp index fd4e3f9c39..bb81f8aa62 100644 --- a/frameworks/js/napi/application/js_application.cpp +++ b/frameworks/js/napi/application/js_application.cpp @@ -31,6 +31,7 @@ namespace { constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; + constexpr size_t ARGC_THREE = 3; constexpr const char* PERMISSION_GET_BUNDLE_INFO = "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED"; } void JsApplication::Finalizer(napi_env env, void *data, void *hint) @@ -73,6 +74,73 @@ napi_value JsApplication::CreateBundleContext(napi_env env, napi_callback_info i GET_NAPI_INFO_AND_CALL(env, info, JsApplication, OnCreateBundleContext); } +napi_value JsApplication::CreatePluginModuleContext(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsApplication, OnCreatePluginModuleContext); +} + + +napi_value JsApplication::OnCreatePluginModuleContext(napi_env env, NapiCallbackInfo &info) +{ + if (info.argc < ARGC_THREE) { + ThrowTooFewParametersError(env); + 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()); + std::string moduleName = ""; + std::string pluginBundleName = ""; + + if (!ConvertFromJsValue(env, info.argv[ARGC_TWO], moduleName) + || !ConvertFromJsValue(env, info.argv[ARGC_ONE], pluginBundleName)) { + ThrowInvalidParamError(env, "Parse param failed, moduleName and pluginBundleName must be string."); + return CreateJsUndefined(env); + } + + TAG_LOGD(AAFwkTag::APPKIT, "moduleName: %{public}s, pluginBundleName: %{public}s", + moduleName.c_str(), pluginBundleName.c_str()); + NapiAsyncTask::ExecuteCallback execute = [moduleName, pluginBundleName, contextImpl, + moduleContext, inputContextPtr]() { + if (contextImpl != nullptr) { + *moduleContext = contextImpl->CreatePluginContext(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; +} + napi_value JsApplication::OnCreateModuleContext(napi_env env, NapiCallbackInfo &info) { TAG_LOGD(AAFwkTag::APPKIT, "Called"); @@ -352,6 +420,9 @@ napi_value ApplicationInit(napi_env env, napi_value exportObj) BindNativeFunction(env, exportObj, "createBundleContext", moduleName, JsApplication::CreateBundleContext); + + BindNativeFunction(env, exportObj, "createPluginModuleContext", moduleName, + JsApplication::CreatePluginModuleContext); return CreateJsUndefined(env); } } // namespace AbilityRuntime diff --git a/frameworks/js/napi/application/js_application.h b/frameworks/js/napi/application/js_application.h index 0e536e4411..0678511515 100644 --- a/frameworks/js/napi/application/js_application.h +++ b/frameworks/js/napi/application/js_application.h @@ -34,10 +34,12 @@ public: static napi_value CreateModuleContext(napi_env env, napi_callback_info info); 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); 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 CreateJsContext(napi_env env, const std::shared_ptr &context); void SetCreateCompleteCallback(std::shared_ptr> contextPtr, NapiAsyncTask::CompleteCallback &complete); 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 2ada928242..171f0b7fb4 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 @@ -356,6 +356,19 @@ bool BundleMgrHelper::GetHapModuleInfo(const AbilityInfo &abilityInfo, HapModule return bundleMgr->GetHapModuleInfo(abilityInfo, hapModuleInfo); } +ErrCode BundleMgrHelper::GetPluginHapModuleInfo(const std::string &hostBundleName, const std::string &pluginBundleName, + const std::string &pluginModuleName, const int32_t userId, HapModuleInfo &hapModuleInfo) +{ + TAG_LOGD(AAFwkTag::BUNDLEMGRHELPER, "called"); + auto bundleMgr = Connect(); + if (bundleMgr == nullptr) { + TAG_LOGE(AAFwkTag::BUNDLEMGRHELPER, "null bundleMgr"); + return false; + } + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return bundleMgr->GetPluginHapModuleInfo(hostBundleName, pluginBundleName, pluginModuleName, userId, hapModuleInfo); +} + std::string BundleMgrHelper::GetAbilityLabel(const std::string &bundleName, const std::string &abilityName) { TAG_LOGD(AAFwkTag::BUNDLEMGRHELPER, "called"); @@ -1003,5 +1016,17 @@ std::string BundleMgrHelper::GetDataDir(const std::string &bundleName, const int bundleMgr->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dataDir); return dataDir; } + +ErrCode BundleMgrHelper::GetPluginInfosForSelf(std::vector &pluginBundleInfos) +{ + 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->GetPluginInfosForSelf(pluginBundleInfos); +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/appkit/ability_runtime/context/ability_stage_context.cpp b/frameworks/native/appkit/ability_runtime/context/ability_stage_context.cpp index 14ce4b892f..e871cbe77d 100755 --- a/frameworks/native/appkit/ability_runtime/context/ability_stage_context.cpp +++ b/frameworks/native/appkit/ability_runtime/context/ability_stage_context.cpp @@ -49,6 +49,26 @@ void AbilityStageContext::InitHapModuleInfo(const std::shared_ptrInitHapModuleInfo(abilityInfo); } +void AbilityStageContext::InitPluginHapModuleInfo(const std::shared_ptr &abilityInfo, + const std::string &hostBundleName) +{ + if (contextImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null contextImpl"); + return; + } + + contextImpl_->InitPluginHapModuleInfo(abilityInfo, hostBundleName); +} + +void AbilityStageContext::SetIsPlugin(bool isPlugin) +{ + if (contextImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null contextImpl"); + return; + } + contextImpl_->isPlugin_ = isPlugin; +} + void AbilityStageContext::InitHapModuleInfo(const AppExecFwk::HapModuleInfo &hapModuleInfo) { if (contextImpl_ == nullptr) { @@ -129,6 +149,17 @@ std::shared_ptr AbilityStageContext::GetApplication return contextImpl_->GetApplicationInfo(); } +std::shared_ptr AbilityStageContext::CreatePluginContext(const std::string &pluginBundleName, + const std::string &moduleName, std::shared_ptr inputContext) +{ + if (contextImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null contextImpl"); + return nullptr; + } + + return contextImpl_->CreatePluginContext(pluginBundleName, moduleName, inputContext); +} + std::shared_ptr AbilityStageContext::CreateBundleContext(const std::string &bundleName) { if (contextImpl_ == nullptr) { diff --git a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp index 53e8cc1224..4639fb1867 100644 --- a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp +++ b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp @@ -27,6 +27,7 @@ #include "configuration_convertor.h" #include "constants.h" #include "directory_ex.h" +#include "extractor.h" #include "file_ex.h" #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" @@ -170,7 +171,7 @@ int32_t ContextImpl::GetDatabaseDirWithCheck(bool checkExist, std::string &datab } else { databaseDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_DATABASE; } - if (parentContext_ != nullptr) { + if (parentContext_ != nullptr && !isPlugin_) { databaseDir = databaseDir + CONTEXT_FILE_SEPARATOR + ((GetHapModuleInfo() == nullptr) ? "" : GetHapModuleInfo()->moduleName); } @@ -396,12 +397,105 @@ void ContextImpl::SetMnc(std::string mnc) } } +bool ContextImpl::GetPluginInfo(const std::string &hostBundleName, const std::string &pluginBundleName, + const std::string &pluginModuleName, AppExecFwk::PluginBundleInfo &pluginBundleInfo) +{ + if (hostBundleName.empty() || pluginBundleName.empty() || pluginModuleName.empty()) { + return false; + } + TAG_LOGD(AAFwkTag::APPKIT, "hostBundleName: %{public}s, pluginBundleName: %{public}s, pluginModuleName: %{public}s", + hostBundleName.c_str(), pluginBundleName.c_str(), pluginModuleName.c_str()); + int errCode = GetBundleManager(); + if (errCode != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "failed, errCode: %{public}d", errCode); + return false; + } + + std::vector pluginBundleInfos; + errCode = bundleMgr_->GetPluginInfosForSelf(pluginBundleInfos); + if (errCode != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "GetPluginInfosForSelf failed, errCode: %{public}d", errCode); + return false; + } + + for (auto &pluginBundle : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundle.pluginModuleInfos) { + if (pluginBundleName == pluginBundle.pluginBundleName + && pluginModuleName == pluginModuleInfo.moduleName) { + pluginBundleInfo = pluginBundle; + return true; + } + } + } + TAG_LOGE(AAFwkTag::APPKIT, "not find pluginBundleName"); + return false; +} + std::shared_ptr ContextImpl::CreateModuleContext(const std::string &moduleName, std::shared_ptr inputContext) { return CreateModuleContext(GetBundleNameWithContext(inputContext), moduleName, inputContext); } +std::shared_ptr ContextImpl::CreatePluginContext(const std::string &pluginBundleName, + const std::string &moduleName, std::shared_ptr inputContext) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (pluginBundleName.empty() || moduleName.empty() || inputContext == nullptr) { + return nullptr; + } + TAG_LOGD(AAFwkTag::APPKIT, "pluginBundleName: %{public}s, moduleName: %{public}s", + pluginBundleName.c_str(), moduleName.c_str()); + + AppExecFwk::PluginBundleInfo pluginBundleInfo; + if (!GetPluginInfo(inputContext->GetBundleName(), pluginBundleName, moduleName, pluginBundleInfo)) { + TAG_LOGE(AAFwkTag::APPKIT, "GetPluginInfo failed"); + return nullptr; + } + + auto appContext = std::make_shared(); + appContext->SetConfiguration(config_); + appContext->SetProcessName(processName_); + appContext->isPlugin_ = true; + + std::unique_ptr resConfig(Global::Resource::CreateResConfig()); + std::string hapPath; + std::vector overlayPaths; + int32_t appType = 0; + std::shared_ptr resourceManager(Global::Resource::CreateResourceManager( + pluginBundleName, moduleName, hapPath, overlayPaths, *resConfig, appType)); + 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; + TAG_LOGD(AAFwkTag::APPKIT, "loadPath: %{public}s", loadPath.c_str()); + 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; + } + TAG_LOGD(AAFwkTag::APPKIT, "loadPath: %{public}s", loadPath.c_str()); + if (!resourceManager->AddResource(loadPath.c_str())) { + TAG_LOGE(AAFwkTag::APPKIT, "AddResource failed"); + } + } + UpdateResConfig(inputContext->GetResourceManager(), resourceManager); + appContext->SetResourceManager(resourceManager); + appContext->SetApplicationInfo(std::make_shared(pluginBundleInfo.appInfo)); + + return appContext; +} + std::shared_ptr ContextImpl::CreateModuleContext(const std::string &bundleName, const std::string &moduleName, std::shared_ptr inputContext) { @@ -655,7 +749,7 @@ std::string ContextImpl::GetBaseDir() const } else { baseDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_BASE; } - if (parentContext_ != nullptr) { + if (parentContext_ != nullptr && !isPlugin_) { baseDir = baseDir + CONTEXT_HAPS + CONTEXT_FILE_SEPARATOR + ((GetHapModuleInfo() == nullptr) ? "" : GetHapModuleInfo()->moduleName); } @@ -1129,6 +1223,28 @@ void ContextImpl::InitHapModuleInfo(const std::shared_ptr &abilityInfo, + const std::string &hostBundleName) +{ + if (hapModuleInfo_ != nullptr || abilityInfo == nullptr || hostBundleName.empty()) { + return; + } + int errCode = GetBundleManager(); + if (errCode != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "failed, errCode: %{public}d", errCode); + return; + } + int accountId = GetCurrentAccountId(); + if (accountId == 0) { + accountId = GetCurrentActiveAccountId(); + } + hapModuleInfo_ = std::make_shared(); + if (bundleMgr_->GetPluginHapModuleInfo(hostBundleName, abilityInfo->bundleName, + abilityInfo->moduleName, accountId, *hapModuleInfo_) != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "GetPluginHapModuleInfo false"); + } +} + void ContextImpl::InitHapModuleInfo(const AppExecFwk::HapModuleInfo &hapModuleInfo) { hapModuleInfo_ = std::make_shared(hapModuleInfo); diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index 92355cbe0e..8d66b6999c 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -235,6 +235,27 @@ void MainThread::GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &h } } +void MainThread::GetPluginNativeLibPath(std::vector &pluginBundleInfos, + AppLibPathMap &appLibPaths) +{ + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + std::string libPath = pluginModuleInfo.nativeLibraryPath; + if (!pluginModuleInfo.isLibIsolated) { + libPath = pluginBundleInfo.nativeLibraryPath; + } + if (libPath.empty()) { + continue; + } + std::string appLibPathKey = pluginBundleInfo.pluginBundleName + "/" + pluginModuleInfo.moduleName; + libPath = std::string(LOCAL_CODE_PATH) + "/+plugins/" + libPath; + TAG_LOGD(AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", + appLibPathKey.c_str(), libPath.c_str()); + appLibPaths[appLibPathKey].emplace_back(libPath); + } + } +} + /** * * @brief Notify the AppMgrDeathRecipient that the remote is dead. @@ -702,7 +723,11 @@ void MainThread::ScheduleUpdateApplicationInfoInstalled(const ApplicationInfo &a TAG_LOGE(AAFwkTag::APPKIT, "null appThread"); return; } - appThread->HandleUpdateApplicationInfoInstalled(appInfo, moduleName); + if (appInfo.bundleType != AppExecFwk::BundleType::APP_PLUGIN) { + appThread->HandleUpdateApplicationInfoInstalled(appInfo, moduleName); + } else { + appThread->HandleUpdatePluginInfoInstalled(appInfo, moduleName); + } }; if (!mainHandler_->PostTask(task, "MainThread:UpdateApplicationInfoInstalled")) { TAG_LOGE(AAFwkTag::APPKIT, "PostTask task failed"); @@ -1457,11 +1482,24 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con } std::map pkgContextInfoJsonStringMap; + std::vector pluginBundleInfos; + AppLibPathMap appLibPaths {}; + if (bundleInfo.hasPlugin) { + if (bundleMgrHelper->GetPluginInfosForSelf(pluginBundleInfos) != ERR_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginInfosForSelf failed"); + } + GetPluginNativeLibPath(pluginBundleInfos, appLibPaths); + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + pkgContextInfoJsonStringMap[pluginModuleInfo.moduleName] = pluginModuleInfo.hapPath; + } + } + } + for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { pkgContextInfoJsonStringMap[hapModuleInfo.moduleName] = hapModuleInfo.hapPath; } - AppLibPathMap appLibPaths {}; GetNativeLibPath(bundleInfo, hspList, appLibPaths); bool isSystemApp = bundleInfo.applicationInfo.isSystemApp; TAG_LOGD(AAFwkTag::APPKIT, "the application isSystemApp: %{public}d", isSystemApp); @@ -1519,6 +1557,15 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con AbilityRuntime::ChildProcessManager::GetInstance().SetForkProcessDebugOption(appInfo.bundleName, appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart()); #endif // SUPPORT_CHILD_PROCESS + if (!pluginBundleInfos.empty()) { + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + options.packageNameList[pluginModuleInfo.moduleName] = pluginModuleInfo.packageName; + TAG_LOGI(AAFwkTag::APPKIT, "moduleName %{public}s, packageName %{public}s", + pluginModuleInfo.moduleName.c_str(), pluginModuleInfo.packageName.c_str()); + } + } + } if (!bundleInfo.hapModuleInfos.empty()) { for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { options.hapModulePath[hapModuleInfo.moduleName] = hapModuleInfo.hapPath; @@ -2067,6 +2114,54 @@ void MainThread::ChangeToLocalPath(const std::string &bundleName, } } +void MainThread::HandleUpdatePluginInfoInstalled(const ApplicationInfo &pluginAppInfo, const std::string &moduleName) +{ + TAG_LOGD(AAFwkTag::APPKIT, "called"); + if (!application_) { + TAG_LOGE(AAFwkTag::APPKIT, "null application_"); + return; + } + auto& runtime = application_->GetRuntime(); + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); + return; + } + + if (runtime->GetLanguage() != Runtime::Language::JS) { + TAG_LOGE(AAFwkTag::APPKIT, "only support js"); + return; + } + + AbilityRuntime::JsRuntime* jsRuntime = static_cast(runtime.get()); + if (jsRuntime == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); + return; + } + + auto bundleMgrHelper = DelayedSingleton::GetInstance(); + if (bundleMgrHelper == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null bundleMgrHelper"); + return; + } + + std::vector pluginBundleInfos; + if (bundleMgrHelper->GetPluginInfosForSelf(pluginBundleInfos) != ERR_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginInfosForSelf failed"); + return; + } + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + if (moduleName == pluginModuleInfo.moduleName && + pluginBundleInfo.pluginBundleName == pluginAppInfo.name) { + jsRuntime->UpdatePkgContextInfoJson(moduleName, pluginModuleInfo.hapPath, pluginModuleInfo.packageName); + TAG_LOGI(AAFwkTag::APPKIT, + "UpdatePkgContextInfoJson moduleName: %{public}s, hapPath: %{public}s", + moduleName.c_str(), pluginModuleInfo.hapPath.c_str()); + } + } + } +} + void MainThread::HandleUpdateApplicationInfoInstalled(const ApplicationInfo& appInfo, const std::string& moduleName) { TAG_LOGD(AAFwkTag::APPKIT, "called"); diff --git a/frameworks/native/appkit/app/ohos_application.cpp b/frameworks/native/appkit/app/ohos_application.cpp index 02c7a93ace..5f254001f2 100644 --- a/frameworks/native/appkit/app/ohos_application.cpp +++ b/frameworks/native/appkit/app/ohos_application.cpp @@ -386,8 +386,23 @@ std::shared_ptr OHOSApplication::AddAbilityStage( auto iterator = abilityStages_.find(moduleName); if (iterator == abilityStages_.end()) { auto stageContext = std::make_shared(); - stageContext->SetParentContext(abilityRuntimeContext_); - stageContext->InitHapModuleInfo(abilityInfo); + bool isPlugin = abilityInfo->applicationInfo.bundleType == AppExecFwk::BundleType::APP_PLUGIN; + if (isPlugin) { + stageContext->SetIsPlugin(true); + stageContext->InitPluginHapModuleInfo(abilityInfo, abilityRuntimeContext_->GetBundleName()); + auto pluginContext = stageContext->CreatePluginContext( + abilityInfo->bundleName, abilityInfo->moduleName, abilityRuntimeContext_); + if (pluginContext == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null pluginContext"); + return nullptr; + } + auto rm = pluginContext->GetResourceManager(); + stageContext->SetResourceManager(rm); + } else { + stageContext->InitHapModuleInfo(abilityInfo); + stageContext->SetParentContext(abilityRuntimeContext_); + } + stageContext->SetConfiguration(GetConfiguration()); stageContext->SetProcessName(GetProcessName()); std::shared_ptr hapModuleInfo = stageContext->GetHapModuleInfo(); diff --git a/frameworks/native/runtime/js_module_reader.cpp b/frameworks/native/runtime/js_module_reader.cpp index 51a872a9d3..35aa5db47a 100755 --- a/frameworks/native/runtime/js_module_reader.cpp +++ b/frameworks/native/runtime/js_module_reader.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include "js_module_reader.h" #include "bundle_info.h" @@ -31,6 +32,7 @@ using namespace OHOS::AbilityBase; namespace OHOS { namespace AbilityRuntime { using IBundleMgr = AppExecFwk::IBundleMgr; +bool JsModuleReader::needFindPluginHsp_ = true; JsModuleReader::JsModuleReader(const std::string& bundleName, const std::string& hapPath, bool isFormRender) : JsModuleSearcher(bundleName), isFormRender_(isFormRender) @@ -58,6 +60,16 @@ bool JsModuleReader::operator()(const std::string& inputPath, uint8_t **buff, return false; } + if (needFindPluginHsp_) { + // find plugin + realHapPath = GetPluginHspPath(inputPath); + if (realHapPath.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); + return false; + } + needFindPluginHsp_ = true; + } + bool newCreate = false; std::shared_ptr extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate); if (extractor == nullptr) { @@ -77,6 +89,48 @@ bool JsModuleReader::operator()(const std::string& inputPath, uint8_t **buff, return true; } +std::string JsModuleReader::GetPluginHspPath(const std::string& inputPath) const +{ + std::string presetAppHapPath = ""; + auto bundleMgrHelper = DelayedSingleton::GetInstance(); + if (bundleMgrHelper == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper"); + return presetAppHapPath; + } + std::string moduleName = inputPath.substr(inputPath.find_last_of("/") + 1); + std::string tmpPath = inputPath.substr(inputPath.find_first_of("/") + 1); + const std::string sharedBundleName = tmpPath.substr(0, tmpPath.find_first_of("/")); + TAG_LOGI(AAFwkTag::JSRUNTIME, "moduleName: %{public}s, sharedBundleName: %{public}s", + moduleName.c_str(), sharedBundleName.c_str()); + if (moduleName.empty() || sharedBundleName.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty moduleName"); + return presetAppHapPath; + } + + std::vector pluginBundleInfos; + if (bundleMgrHelper->GetPluginInfosForSelf(pluginBundleInfos) != ERR_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginInfosForSelf failed"); + return presetAppHapPath; + } + + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + if (moduleName == pluginModuleInfo.moduleName + && sharedBundleName == pluginBundleInfo.pluginBundleName) { + presetAppHapPath = pluginModuleInfo.hapPath; + TAG_LOGD(AAFwkTag::JSRUNTIME, "presetAppHapPath %{public}s", presetAppHapPath.c_str()); + std::regex pattern(std::string(ABS_DATA_CODE_PATH) + bundleName_ + "/"); + presetAppHapPath = std::regex_replace( + presetAppHapPath, pattern, std::string(ABS_CODE_PATH) + std::string(BUNDLE)); + TAG_LOGD(AAFwkTag::JSRUNTIME, "presetAppHapPath %{public}s", presetAppHapPath.c_str()); + return presetAppHapPath; + } + } + } + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginHspPath failed"); + return presetAppHapPath; +} + std::string JsModuleReader::GetAppHspPath(const std::string& inputPath) const { if (isFormRender_) { @@ -148,6 +202,7 @@ std::string JsModuleReader::GetOtherHspPath(const std::string& bundleName, const for (const auto &info : baseSharedBundleInfos) { if ((info.bundleName == sharedBundleName) && (info.moduleName == moduleName)) { presetAppHapPath = info.hapPath; + needFindPluginHsp_ = false; break; } } @@ -161,6 +216,7 @@ std::string JsModuleReader::GetOtherHspPath(const std::string& bundleName, const for (const auto &info : bundleInfo.hapModuleInfos) { if (info.moduleName == moduleName) { presetAppHapPath = info.hapPath; + needFindPluginHsp_ = false; break; } } @@ -191,6 +247,7 @@ std::string JsModuleReader::GetPresetAppHapPath(const std::string& inputPath, co for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { if (hapModuleInfo.moduleName == moduleName) { presetAppHapPath = hapModuleInfo.hapPath; + needFindPluginHsp_ = false; break; } } diff --git a/frameworks/native/runtime/js_module_reader.h b/frameworks/native/runtime/js_module_reader.h index affe228e86..1777266c38 100755 --- a/frameworks/native/runtime/js_module_reader.h +++ b/frameworks/native/runtime/js_module_reader.h @@ -51,11 +51,13 @@ private: std::string GetCommonAppHspPath(const std::string& inputPath) const; std::string GetFormAppHspPath(const std::string& inputPath) const; std::string GetModuleName(const std::string& inputPath) const; + std::string GetPluginHspPath(const std::string& inputPath) const; static std::string GetOtherHspPath(const std::string& bundleName, const std::string& moduleName, const std::string& inputPath); bool isSystemPath_ = false; bool isFormRender_ = false; + static bool needFindPluginHsp_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index 7a083c5a1a..25418bb9b5 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -1110,6 +1110,7 @@ bool JsRuntime::RunScript(const std::string& srcPath, const std::string& hapPath return false; } if (newCreate) { + TAG_LOGD(AAFwkTag::JSRUNTIME, "newCreate"); panda::JSNApi::LoadAotFile(vm, moduleName_); auto resourceManager = AbilityBase::ExtractResourceManager::GetExtractResourceManager().GetGlobalObject(); if (resourceManager) { 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 6712a0b9c1..709c73a8d3 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 @@ -48,6 +48,8 @@ public: bool GetBundleInfo(const std::string &bundleName, int32_t flags, BundleInfo &bundleInfo, int32_t userId); std::string GetAppIdByBundleName(const std::string &bundleName, const int32_t userId); bool GetHapModuleInfo(const AbilityInfo &abilityInfo, HapModuleInfo &hapModuleInfo); + ErrCode GetPluginHapModuleInfo(const std::string &hostBundleName, const std::string &pluginBundleName, + const std::string &pluginModuleName, const int32_t userId, HapModuleInfo &hapModuleInfo); std::string GetAbilityLabel(const std::string &bundleName, const std::string &abilityName); std::string GetAppType(const std::string &bundleName); ErrCode GetBaseSharedBundleInfos( @@ -111,6 +113,7 @@ public: std::string GetStringById( const std::string &bundleName, const std::string &moduleName, uint32_t resId, int32_t userId); std::string GetDataDir(const std::string &bundleName, const int32_t appIndex); + ErrCode GetPluginInfosForSelf(std::vector &pluginBundleInfos); private: sptr Connect(); diff --git a/interfaces/kits/native/appkit/ability_runtime/context/ability_stage_context.h b/interfaces/kits/native/appkit/ability_runtime/context/ability_stage_context.h index e6ae67ca54..41e136ac66 100755 --- a/interfaces/kits/native/appkit/ability_runtime/context/ability_stage_context.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/ability_stage_context.h @@ -30,6 +30,8 @@ public: void InitHapModuleInfo(const std::shared_ptr &abilityInfo); void InitHapModuleInfo(const AppExecFwk::HapModuleInfo &hapModuleInfo); + void InitPluginHapModuleInfo(const std::shared_ptr &abilityInfo, + const std::string &hostBundleName); std::shared_ptr GetHapModuleInfo() const override; void SetConfiguration(const std::shared_ptr &config); @@ -41,6 +43,8 @@ public: std::string GetBundleName() const override; std::shared_ptr GetApplicationInfo() const override; + std::shared_ptr CreatePluginContext(const std::string &pluginBundleName, + const std::string &moduleName, std::shared_ptr inputContext); std::shared_ptr CreateBundleContext(const std::string &bundleName) override; std::shared_ptr CreateModuleContext(const std::string &moduleName) override; std::shared_ptr CreateModuleContext(const std::string &bundleName, const std::string &moduleName) override; @@ -70,6 +74,7 @@ public: bool IsUpdatingConfigurations() override; bool PrintDrawnCompleted() override; + void SetIsPlugin(bool isPlugin); sptr GetToken() override; void SetToken(const sptr &token) override; 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 cfe43e9559..b8d81c551e 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h @@ -208,6 +208,9 @@ public: std::shared_ptr CreateModuleContext(const std::string &bundleName, const std::string &moduleName, std::shared_ptr inputContext); + std::shared_ptr CreatePluginContext(const std::string &pluginBundleName, + const std::string &moduleName, std::shared_ptr inputContext); + std::string GetBundleNameWithContext(std::shared_ptr inputContext = nullptr) const; /** @@ -320,6 +323,14 @@ public: * @param hapModuleInfo HapModuleInfo instance. */ void InitHapModuleInfo(const std::shared_ptr &abilityInfo); + + /** + * @brief Set HapModuleInfo + * + * @param hapModuleInfo HapModuleInfo instance. + */ + void InitPluginHapModuleInfo(const std::shared_ptr &abilityInfo, + const std::string &hostBundleName); /** * @brief Set HapModuleInfo @@ -428,6 +439,8 @@ public: static const int EL_DEFAULT = 1; + bool isPlugin_ = false; + protected: // Adding a new attribute requires adding a copy in the ShallowCopySelf function sptr token_; @@ -515,7 +528,8 @@ private: #ifdef SUPPORT_GRAPHICS bool GetDisplayConfig(uint64_t displayId, float &density, std::string &directionStr); #endif - + bool GetPluginInfo(const std::string &hostBundleName, const std::string &pluginBundleName, + const std::string &pluginModuleName, AppExecFwk::PluginBundleInfo &pluginBundleInfo); // Adding a new attribute requires adding a copy in the ShallowCopySelf function static Global::Resource::DeviceType deviceType_; std::shared_ptr applicationInfo_ = nullptr; diff --git a/interfaces/kits/native/appkit/app/main_thread.h b/interfaces/kits/native/appkit/app/main_thread.h index 4061b1ccbd..773da48fc7 100644 --- a/interfaces/kits/native/appkit/app/main_thread.h +++ b/interfaces/kits/native/appkit/app/main_thread.h @@ -59,6 +59,7 @@ struct BaseSharedBundleInfo; using HspList = std::vector; enum class MainThreadState { INIT, ATTACH, READY, RUNNING }; struct BundleInfo; +struct PluginBundleInfo; class ContextDeal; // class Global::Resource::ResourceManager; class AppMgrDeathRecipient : public IRemoteObject::DeathRecipient { @@ -641,6 +642,8 @@ private: bool IsBgWorkingThread(const AbilityInfo &info); + void HandleUpdatePluginInfoInstalled(const ApplicationInfo &pluginAppInfo, const std::string &moduleName); + /** * @brief parse app configuration params * @@ -757,6 +760,8 @@ private: std::vector> &fileMap); void GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppLibPathMap &appLibPaths); void SetAppDebug(uint32_t modeFlag, bool isDebug); + void GetPluginNativeLibPath(std::vector &pluginBundleInfos, + AppLibPathMap &appLibPaths); std::vector fileEntries_; std::vector nativeFileEntries_;