From 60a19fff58e3e14d73eaeab819987c6f52536fe5 Mon Sep 17 00:00:00 2001 From: wangzhen Date: Wed, 31 May 2023 17:19:57 +0800 Subject: [PATCH] Support loading library from hap file Signed-off-by: wangzhen --- frameworks/native/appkit/app/main_thread.cpp | 252 ++++++++++++------ .../kits/native/appkit/app/main_thread.h | 3 +- .../main_thread_test/main_thread_test.cpp | 5 +- 3 files changed, 174 insertions(+), 86 deletions(-) diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index ba27b5d63d..1380231cc8 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -112,6 +112,51 @@ constexpr uint32_t CHECK_MAIN_THREAD_IS_ALIVE = 1; const std::string OVERLAY_STATE_CHANGED = "usual.event.OVERLAY_STATE_CHANGED"; +std::string GetLibPath(const std::string &hapPath, bool isPreInstallApp) +{ + std::string libPath = LOCAL_CODE_PATH; + if (isPreInstallApp) { + auto pos = hapPath.rfind("/"); + libPath = hapPath.substr(0, pos); + } + return libPath; +} + +bool GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp) +{ + if (hapInfo.compressNativeLibs) { + return false; + } + + if (hapInfo.nativeLibraryPath.empty()) { + return true; + } + + std::string libPath = GetLibPath(hapInfo.hapPath, isPreInstallApp); + libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath; + HILOG_INFO("module lib path = %{public}s", libPath.c_str()); + appLibPaths["default"].emplace_back(libPath); + return true; +} + +void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp) +{ + if (hspInfo.nativeLibraryPath.empty()) { + return; + } + + std::string appLibPathKey = hspInfo.bundleName + "/" + hspInfo.moduleName; + std::string libPath = LOCAL_CODE_PATH; + if (!hspInfo.compressNativeLibs) { + libPath = GetLibPath(hspInfo.hapPath, isPreInstallApp); + appLibPathKey = "default"; + } + libPath = libPath.back() == '/' ? libPath : libPath + "/"; + libPath += hspInfo.bundleName + "/" + hspInfo.nativeLibraryPath; + HILOG_DEBUG("appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str()); + appLibPaths[appLibPathKey].emplace_back(libPath); +} + void GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppLibPathMap &appLibPaths) { std::string patchNativeLibraryPath = bundleInfo.applicationInfo.appQuickFix.deployedAppqfInfo.nativeLibraryPath; @@ -150,13 +195,13 @@ void GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppL HILOG_INFO("name: %{public}s, patch lib path = %{private}s", hapInfo.name.c_str(), patchLibPath.c_str()); appLibPaths[appLibPathKey].emplace_back(patchLibPath); } - - std::string libPath = LOCAL_CODE_PATH; - if (hapInfo.isLibIsolated) { - libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath; - } else { - libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath; + if (GetHapSoPath(hapInfo, appLibPaths, bundleInfo.isPreInstallApp)) { + continue; } + + std::string libPath = LOCAL_CODE_PATH; + const auto &tmpNativePath = hapInfo.isLibIsolated ? hapInfo.nativeLibraryPath : nativeLibraryPath; + libPath += (libPath.back() == '/') ? tmpNativePath : "/" + tmpNativePath; HILOG_DEBUG("appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str()); appLibPaths[appLibPathKey].emplace_back(libPath); } @@ -164,16 +209,7 @@ void GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppL for (auto &hspInfo : hspList) { HILOG_DEBUG("bundle:%s, module:%s, nativeLibraryPath:%s", hspInfo.bundleName.c_str(), hspInfo.moduleName.c_str(), hspInfo.nativeLibraryPath.c_str()); - if (hspInfo.nativeLibraryPath.empty()) { - continue; - } - - std::string appLibPathKey = hspInfo.bundleName + "/" + hspInfo.moduleName; - std::string libPath = LOCAL_CODE_PATH; - libPath = libPath.back() == '/' ? libPath : libPath + "/"; - libPath += hspInfo.bundleName + "/" + hspInfo.nativeLibraryPath; - HILOG_DEBUG("appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str()); - appLibPaths[appLibPathKey].emplace_back(libPath); + GetHspNativeLibPath(hspInfo, appLibPaths, bundleInfo.isPreInstallApp); } } } // namespace @@ -828,9 +864,13 @@ bool MainThread::InitCreate( std::shared_ptr &contextDeal, ApplicationInfo &appInfo, ProcessInfo &processInfo) { HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); + // get application shared point + application_ = std::shared_ptr(ApplicationLoader::GetInstance().GetApplicationByName()); if (application_ == nullptr) { + HILOG_ERROR("InitCreate application create failed"); return false; } + applicationInfo_ = std::make_shared(appInfo); if (applicationInfo_ == nullptr) { HILOG_ERROR("MainThread::InitCreate create applicationInfo_ failed"); @@ -1067,6 +1107,46 @@ void MainThread::HandleOnOverlayChanged(const EventFwk::CommonEventData &data, return ret; } +bool IsNeedLoadLibrary(const std::string &bundleName) +{ + std::vector needLoadLibraryBundleNames{ + "com.ohos.contactsdataability", + "com.ohos.medialibrary.medialibrarydata", + "com.ohos.telephonydataability", + "com.ohos.FusionSearch", + "com.ohos.formrenderservice" + }; + + for (const auto &item : needLoadLibraryBundleNames) { + if (item == bundleName) { + return true; + } + } + return false; +} + +bool GetBundleForLaunchApplication(sptr bundleMgr, const std::string &bundleName, + int32_t appIndex, BundleInfo &bundleInfo) +{ + bool queryResult; + if (appIndex != 0) { + HILOG_INFO("GetSandboxBundleInfo, bundleName = %{public}s", bundleName.c_str()); + queryResult = (bundleMgr->GetSandboxBundleInfo(bundleName, + appIndex, UNSPECIFIED_USERID, bundleInfo) == 0); + } else { + HILOG_INFO("GetBundleInfo, bundleName = %{public}s", bundleName.c_str()); + queryResult = (bundleMgr->GetBundleInfoForSelf( + (static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) + + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA)), bundleInfo) == ERR_OK); + } + return queryResult; +} + /** * * @brief Launch the application. @@ -1083,19 +1163,32 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con return; } - std::string contactsDataAbility("com.ohos.contactsdataability"); - std::string mediaDataAbility("com.ohos.medialibrary.medialibrarydata"); - std::string telephonyDataAbility("com.ohos.telephonydataability"); - std::string fusionSearchAbility("com.ohos.FusionSearch"); - std::string formRenderExtensionAbility("com.ohos.formrenderservice"); auto appInfo = appLaunchData.GetApplicationInfo(); + ProcessInfo processInfo = appLaunchData.GetProcessInfo(); + HILOG_DEBUG("MainThread handle launch application, InitCreate Start."); + std::shared_ptr contextDeal; + if (!InitCreate(contextDeal, appInfo, processInfo)) { + HILOG_ERROR("MainThread::handleLaunchApplication InitCreate failed"); + return; + } + sptr bundleMgr = contextDeal->GetBundleManager(); + if (bundleMgr == nullptr) { + HILOG_ERROR("MainThread::handleLaunchApplication GetBundleManager is nullptr"); + return; + } + auto bundleName = appInfo.bundleName; - if (bundleName == contactsDataAbility || bundleName == mediaDataAbility || bundleName == telephonyDataAbility - || bundleName == fusionSearchAbility || bundleName == formRenderExtensionAbility) { + BundleInfo bundleInfo; + if (!GetBundleForLaunchApplication(bundleMgr, bundleName, appLaunchData.GetAppIndex(), bundleInfo)) { + HILOG_ERROR("HandleLaunchApplication GetBundleInfo failed!"); + return; + } + + if (IsNeedLoadLibrary(bundleName)) { std::vector localPaths; ChangeToLocalPath(bundleName, appInfo.moduleSourceDirs, localPaths); LoadAbilityLibrary(localPaths); - LoadNativeLiabrary(appInfo.nativeLibraryPath); + LoadNativeLiabrary(bundleInfo, appInfo.nativeLibraryPath); } if (appInfo.needAppDetail) { HILOG_DEBUG("MainThread::handleLaunchApplication %{public}s need add app detail ability library path", @@ -1103,56 +1196,13 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con LoadAppDetailAbilityLibrary(appInfo.appDetailAbilityLibraryPath); } LoadAppLibrary(); - // get application shared point - application_ = std::shared_ptr(ApplicationLoader::GetInstance().GetApplicationByName()); - if (application_ == nullptr) { - HILOG_ERROR("HandleLaunchApplication::application launch failed"); - return; - } - ProcessInfo processInfo = appLaunchData.GetProcessInfo(); - - HILOG_DEBUG("MainThread handle launch application, InitCreate Start."); - std::shared_ptr contextDeal = nullptr; - if (!InitCreate(contextDeal, appInfo, processInfo)) { - HILOG_ERROR("MainThread::handleLaunchApplication InitCreate failed"); - return; - } - + applicationForDump_ = application_; mixStackDumper_ = std::make_shared(); if (!mixStackDumper_->IsInstalled()) { mixStackDumper_->InstallDumpHandler(application_, signalHandler_); } - sptr bundleMgr = contextDeal->GetBundleManager(); - if (bundleMgr == nullptr) { - HILOG_ERROR("MainThread::handleLaunchApplication GetBundleManager is nullptr"); - return; - } - - BundleInfo bundleInfo; - bool queryResult; - if (appLaunchData.GetAppIndex() != 0) { - HILOG_INFO("GetSandboxBundleInfo, bundleName = %{public}s", appInfo.bundleName.c_str()); - queryResult = (bundleMgr->GetSandboxBundleInfo(appInfo.bundleName, - appLaunchData.GetAppIndex(), UNSPECIFIED_USERID, bundleInfo) == 0); - } else { - HILOG_INFO("GetBundleInfo, bundleName = %{public}s", appInfo.bundleName.c_str()); - queryResult = (bundleMgr->GetBundleInfoForSelf( - (static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) + - static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA)), bundleInfo) == ERR_OK); - } - - if (!queryResult) { - HILOG_ERROR("HandleLaunchApplication GetBundleInfo failed!"); - return; - } - bool moduelJson = false; bool isStageBased = false; bool findEntryHapModuleInfo = false; @@ -1375,25 +1425,61 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con HILOG_DEBUG("MainThread::handleLaunchApplication called end."); } -void MainThread::LoadNativeLiabrary(std::string &nativeLibraryPath) -{ #ifdef ABILITY_LIBRARY_LOADER - if (nativeLibraryPath.empty()) { - HILOG_WARN("Native library path is empty."); - return; +void MainThread::CalcNativeLiabraryEntries(const BundleInfo &bundleInfo, std::string &nativeLibraryPath) +{ + bool loadSoFromDir = bundleInfo.hapModuleInfos.empty(); + std::vector nativeFileEntries; + for (const auto &item: bundleInfo.hapModuleInfos) { + if (!item.compressNativeLibs) { + HILOG_DEBUG("handle entries for: %{public}s, with path: %{public}s", item.moduleName.c_str(), + item.nativeLibraryPath.c_str()); + if (item.nativeLibraryPath.empty()) { + HILOG_DEBUG("nativeLibraryPath empty: %{public}s", item.moduleName.c_str()); + continue; + } + std::string libPath = GetLibPath(item.hapPath, bundleInfo.isPreInstallApp); + libPath += (libPath.back() == '/') ? item.nativeLibraryPath : "/" + item.nativeLibraryPath; + HILOG_INFO("module lib path: %{public}s", libPath.c_str()); + if (libPath.back() != '/') { + libPath.push_back('/'); + } + for (const auto &entryName : item.nativeLibraryFileNames) { + HILOG_DEBUG("add entry: %{public}s.", entryName.c_str()); + nativeFileEntries.emplace_back(libPath + entryName); + } + } else { + HILOG_DEBUG("compressNativeLibs flag true for: %{public}s.", item.moduleName.c_str()); + loadSoFromDir = true; + } + } + + if (loadSoFromDir) { + if (nativeLibraryPath.empty()) { + HILOG_WARN("Native library path is empty."); + return; + } + + if (nativeLibraryPath.back() == '/') { + nativeLibraryPath.pop_back(); + } + std::string libPath = LOCAL_CODE_PATH; + libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath; + HILOG_DEBUG("native library path = %{public}s", libPath.c_str()); + + if (!ScanDir(libPath, nativeFileEntries_)) { + HILOG_WARN("%{public}s scanDir %{public}s not exits", __func__, libPath.c_str()); + } } - if (nativeLibraryPath.back() == '/') { - nativeLibraryPath.pop_back(); - } - std::string libPath = LOCAL_CODE_PATH; - libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath; - HILOG_DEBUG("native library path = %{public}s", libPath.c_str()); - - if (!ScanDir(libPath, nativeFileEntries_)) { - HILOG_WARN("%{public}s scanDir %{public}s not exits", __func__, libPath.c_str()); + if (!nativeFileEntries.empty()) { + nativeFileEntries_.insert(nativeFileEntries_.end(), nativeFileEntries.begin(), nativeFileEntries.end()); } +} +void MainThread::LoadNativeLiabrary(const BundleInfo &bundleInfo, std::string &nativeLibraryPath) +{ + CalcNativeLiabraryEntries(bundleInfo, nativeLibraryPath); if (nativeFileEntries_.empty()) { HILOG_WARN("No native library"); return; @@ -1424,8 +1510,8 @@ void MainThread::LoadNativeLiabrary(std::string &nativeLibraryPath) HILOG_DEBUG("%{public}s Success to dlopen %{public}s", __func__, fileEntry.c_str()); handleAbilityLib_.emplace_back(handleAbilityLib); } -#endif } +#endif void MainThread::ChangeToLocalPath(const std::string &bundleName, const std::vector &sourceDirs, std::vector &localPath) diff --git a/interfaces/kits/native/appkit/app/main_thread.h b/interfaces/kits/native/appkit/app/main_thread.h index 50c2557f5c..aa2c51e008 100644 --- a/interfaces/kits/native/appkit/app/main_thread.h +++ b/interfaces/kits/native/appkit/app/main_thread.h @@ -558,7 +558,8 @@ private: */ void LoadAbilityLibrary(const std::vector &libraryPaths); - void LoadNativeLiabrary(std::string &nativeLibraryPath); + void CalcNativeLiabraryEntries(const BundleInfo &bundleInfo, std::string &nativeLibraryPath); + void LoadNativeLiabrary(const BundleInfo &bundleInfo, std::string &nativeLibraryPath); void LoadAppDetailAbilityLibrary(std::string &nativeLibraryPath); diff --git a/test/unittest/appkit/main_thread_test/main_thread_test.cpp b/test/unittest/appkit/main_thread_test/main_thread_test.cpp index d2f4fcc2e6..5707391c4c 100644 --- a/test/unittest/appkit/main_thread_test/main_thread_test.cpp +++ b/test/unittest/appkit/main_thread_test/main_thread_test.cpp @@ -1519,10 +1519,11 @@ HWTEST_F(MainThreadTest, LoadNativeLiabrary_0100, TestSize.Level1) HILOG_INFO("%{public}s start.", __func__); std::string nativeLibraryPath = ""; ASSERT_NE(mainThread_, nullptr); - mainThread_->LoadNativeLiabrary(nativeLibraryPath); + BundleInfo bundleInfo; + mainThread_->LoadNativeLiabrary(bundleInfo, nativeLibraryPath); nativeLibraryPath = "test/"; - mainThread_->LoadNativeLiabrary(nativeLibraryPath); + mainThread_->LoadNativeLiabrary(bundleInfo, nativeLibraryPath); HILOG_INFO("%{public}s end.", __func__); } #endif