LibrarySupportDirectory

Signed-off-by: liuzongze <liuzongze@h-partners.com>
Change-Id: I8e70f42fe399c1d33b4c54dc9b4a6af8bf3b3e67
This commit is contained in:
liuzongze
2026-04-10 12:45:09 +08:00
parent 1b6fb9e534
commit e47f98f225
8 changed files with 541 additions and 5 deletions
@@ -256,6 +256,7 @@ void MainThread::GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &h
} else {
TAG_LOGI(AAFwkTag::APPKIT, "NativeLibPath empty");
}
GetLibrarySupportDirectory(bundleInfo.hapModuleInfos, nativeLibraryPath, appLibPaths);
for (auto &hapInfo : bundleInfo.hapModuleInfos) {
TAG_LOGD(AAFwkTag::APPKIT,
@@ -75,6 +75,14 @@ void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &app
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
if (!hspInfo.librarySupportDirectory.empty()) {
for (const auto &dir : hspInfo.librarySupportDirectory) {
std::string supportLibPath = libPath + "/" + dir;
TAG_LOGD(AAFwkTag::APPKIT, "supportLibPath: %{public}s", supportLibPath.c_str());
appLibPaths["default"].emplace_back(supportLibPath);
}
}
}
void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
@@ -102,5 +110,24 @@ void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativ
patchLibPath.c_str());
appLibPaths[appLibPathKey].emplace_back(patchLibPath);
}
void GetLibrarySupportDirectory(
const std::vector<HapModuleInfo> &hapModuleInfos,
const std::string nativeLibraryPath,
AppLibPathMap &appLibPaths)
{
std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath;
for (auto &hapInfo : hapModuleInfos) {
if (hapInfo.librarySupportDirectory.empty()) {
continue;
}
for (const auto &dir : hapInfo.librarySupportDirectory) {
std::string supportLibPath = libPath + "/" + dir;
TAG_LOGD(AAFwkTag::APPKIT, "supportLibPath: %{public}s", supportLibPath.c_str());
appLibPaths["default"].emplace_back(supportLibPath);
}
}
}
} // AppExecFwk
} // namespace OHOS
@@ -83,6 +83,13 @@ void GetEtsHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
if (!hspInfo.librarySupportDirectory.empty()) {
for (const auto &dir : hspInfo.librarySupportDirectory) {
std::string supportLibPath = libPath + "/" + dir;
TAG_LOGD(AAFwkTag::APPKIT, "supportLibPath: %{public}s", supportLibPath.c_str());
appLibPaths["default"].emplace_back(supportLibPath);
}
}
if (!appBundleName.empty()) {
const bool isInternalHsp = (hspInfo.bundleName == appBundleName);
@@ -142,6 +149,7 @@ void GetEtsNativeLibPath(const BundleInfo &bundleInfo, const std::vector<BaseSha
libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath;
TAG_LOGD(AAFwkTag::APPKIT, "lib path = %{private}s", libPath.c_str());
appLibPaths["default"].emplace_back(libPath);
GetLibrarySupportDirectory(bundleInfo.hapModuleInfos, nativeLibraryPath, appLibPaths);
} else {
TAG_LOGI(AAFwkTag::APPKIT, "nativeLibraryPath is empty");
}
@@ -162,5 +170,24 @@ void GetEtsNativeLibPath(const BundleInfo &bundleInfo, const std::vector<BaseSha
bundleInfo.applicationInfo.bundleName, abcPathsToBundleModuleNameMap);
}
}
void GetLibrarySupportDirectory(
const std::vector<HapModuleInfo> &hapModuleInfos,
const std::string nativeLibraryPath,
AppLibPathMap &appLibPaths)
{
std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath;
for (auto &hapInfo : hapModuleInfos) {
if (hapInfo.librarySupportDirectory.empty()) {
continue;
}
for (const auto &dir : hapInfo.librarySupportDirectory) {
std::string supportLibPath = libPath + "/" + dir;
TAG_LOGD(AAFwkTag::APPKIT, "supportLibPath: %{public}s", supportLibPath.c_str());
appLibPaths["default"].emplace_back(supportLibPath);
}
}
}
} // AppExecFwk
} // namespace OHOS
@@ -38,6 +38,10 @@ void GetEtsPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNa
void GetEtsNativeLibPath(const BundleInfo &bundleInfo, const std::vector<BaseSharedBundleInfo> &hspList,
AppLibPathMap &appLibPaths, std::map<std::string, std::string> &abcPathsToBundleModuleNameMap);
void GetLibrarySupportDirectory(
const std::vector<HapModuleInfo> &hapModuleInfos,
const std::string nativeLibraryPath,
AppLibPathMap &appLibPaths);
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_ETS_NATIVE_LIB_UTIL_H
@@ -32,6 +32,11 @@ void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &app
void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
AppLibPathMap &appLibPaths);
void GetLibrarySupportDirectory(
const std::vector<HapModuleInfo> &hapModuleInfos,
const std::string nativeLibraryPath,
AppLibPathMap &appLibPaths);
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_NATIVE_LIB_UTIL_H
@@ -1137,6 +1137,43 @@ ohos_unittest("native_lib_util_test") {
]
}
ohos_unittest("ets_native_lib_util_test") {
sanitize = {
cfi = true
cfi_cross_dso = true
debug = false
blocklist = "../../cfi_blocklist.txt"
}
include_dirs = []
module_out_path = module_output_path
sources = [
"${ability_runtime_native_path}/runtime/ets_native_lib_util.cpp",
"ets_native_lib_util_test.cpp",
]
configs = [ ":module_context_config" ]
deps = [
"${ability_runtime_innerkits_path}/app_manager:app_manager",
"${ability_runtime_innerkits_path}/runtime:runtime",
"${ability_runtime_napi_path}/inner/napi_common:napi_common",
"${ability_runtime_native_path}/appkit:appkit_native",
"${ability_runtime_services_path}/common:app_util",
]
external_deps = [
"ability_base:extractresourcemanager",
"c_utils:utils",
"faultloggerd:libfaultloggerd",
"googletest:gtest_main",
"hilog:libhilog",
"hisysevent:libhisysevent",
"ipc:ipc_core",
"napi:ace_napi",
]
}
ohos_unittest("application_cleaner_test") {
sanitize = {
cfi = true
@@ -1374,6 +1411,7 @@ group("unittest") {
":idle_time_test",
":js_environment_callback_test",
":native_lib_util_test",
":ets_native_lib_util_test",
":overlay_event_subscriber_test",
":startup_manager_mock_test",
":startup_manager_test",
@@ -0,0 +1,242 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "ets_native_lib_util.h"
using namespace testing::ext;
namespace OHOS {
namespace AppExecFwk {
class EtsNativeLibUtilTest : public testing::Test {
public:
EtsNativeLibUtilTest()
{}
~EtsNativeLibUtilTest()
{}
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
};
void EtsNativeLibUtilTest::SetUpTestCase(void)
{}
void EtsNativeLibUtilTest::TearDownTestCase(void)
{}
void EtsNativeLibUtilTest::SetUp(void)
{}
void EtsNativeLibUtilTest::TearDown(void)
{}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0100
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test with empty hapModuleInfos, no paths should be added.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0100, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
EXPECT_TRUE(appLibPaths.empty());
}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0200
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test with hapModuleInfo that has empty librarySupportDirectory, no paths should be added.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0200, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
EXPECT_TRUE(appLibPaths.empty());
}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0300
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test with a single hapModuleInfo that has one librarySupportDirectory entry,
* verify exact path value.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0300, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"subdir1"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 1u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/subdir1");
}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0400
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test with a single hapModuleInfo that has multiple librarySupportDirectory entries,
* verify exact path values.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0400, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"subdir1", "subdir2", "subdir3"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 3u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/subdir1");
EXPECT_EQ(appLibPaths["default"][1], "/data/storage/el1/bundle/libs/arm/subdir2");
EXPECT_EQ(appLibPaths["default"][2], "/data/storage/el1/bundle/libs/arm/subdir3");
}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0500
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test with multiple hapModuleInfos. Only those with non-empty librarySupportDirectory
* should contribute paths. Verify exact count and path content.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0500, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
HapModuleInfo hapInfo1;
hapInfo1.librarySupportDirectory = {"dirA"};
hapModuleInfos.push_back(hapInfo1);
HapModuleInfo hapInfo2;
hapInfo2.librarySupportDirectory = {};
hapModuleInfos.push_back(hapInfo2);
HapModuleInfo hapInfo3;
hapInfo3.librarySupportDirectory = {"dirB", "dirC"};
hapModuleInfos.push_back(hapInfo3);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 3u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/dirA");
EXPECT_EQ(appLibPaths["default"][1], "/data/storage/el1/bundle/libs/arm/dirB");
EXPECT_EQ(appLibPaths["default"][2], "/data/storage/el1/bundle/libs/arm/dirC");
}
/**
* @tc.number: EtsGetLibrarySupportDirectory_0600
* @tc.name: GetLibrarySupportDirectory for ets
* @tc.desc: Test that generated path equals expected full path.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetLibrarySupportDirectory_0600, TestSize.Level1)
{
std::vector<HapModuleInfo> hapModuleInfos;
HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"support"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths["default"].size(), 1u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/support");
}
/**
* @tc.number: EtsGetHspNativeLibPath_WithSupportDirectory_0700
* @tc.name: GetEtsHspNativeLibPath with librarySupportDirectory
* @tc.desc: Test that GetEtsHspNativeLibPath adds support directory paths under "default" key
* when librarySupportDirectory is set.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetHspNativeLibPath_WithSupportDirectory_0700, TestSize.Level1)
{
BaseSharedBundleInfo hspInfo;
AppLibPathMap appLibPaths;
bool isPreInstallApp = true;
std::string appBundleName = "com.test.app";
std::map<std::string, std::string> abcPathsToBundleModuleNameMap;
hspInfo.bundleName = "com.test.hspbundle";
hspInfo.moduleName = "hsplib";
hspInfo.hapPath = "/data/storage/el1/bundle/com.test.hspbundle/hsplib.hsp";
hspInfo.nativeLibraryPath = "libs/arm";
hspInfo.compressNativeLibs = false;
hspInfo.librarySupportDirectory = {"support1", "support2"};
GetEtsHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp, appBundleName, abcPathsToBundleModuleNameMap);
// Verify the main HSP lib path exists
std::string key = "com.test.hspbundle/hsplib";
ASSERT_EQ(appLibPaths.count(key), 1u);
ASSERT_EQ(appLibPaths[key].size(), 1u);
EXPECT_EQ(appLibPaths[key][0], "/data/storage/el1/bundle/com.test.hspbundle/libs/arm");
// Verify "default" has exactly 2 support directory paths
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 2u);
EXPECT_EQ(appLibPaths["default"][0],
"/data/storage/el1/bundle/com.test.hspbundle/libs/arm/support1");
EXPECT_EQ(appLibPaths["default"][1],
"/data/storage/el1/bundle/com.test.hspbundle/libs/arm/support2");
}
/**
* @tc.number: EtsGetHspNativeLibPath_NoSupportDirectory_0800
* @tc.name: GetEtsHspNativeLibPath without librarySupportDirectory
* @tc.desc: Test that GetEtsHspNativeLibPath does not add "default" entry
* when librarySupportDirectory is empty.
*/
HWTEST_F(EtsNativeLibUtilTest, EtsGetHspNativeLibPath_NoSupportDirectory_0800, TestSize.Level1)
{
BaseSharedBundleInfo hspInfo;
AppLibPathMap appLibPaths;
bool isPreInstallApp = true;
std::string appBundleName = "com.test.app";
std::map<std::string, std::string> abcPathsToBundleModuleNameMap;
hspInfo.bundleName = "com.test.hspbundle";
hspInfo.moduleName = "hsplib";
hspInfo.hapPath = "/data/storage/el1/bundle/com.test.hspbundle/hsplib.hsp";
hspInfo.nativeLibraryPath = "libs/arm";
hspInfo.compressNativeLibs = false;
hspInfo.librarySupportDirectory = {};
GetEtsHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp, appBundleName, abcPathsToBundleModuleNameMap);
std::string key = "com.test.hspbundle/hsplib";
ASSERT_EQ(appLibPaths.count(key), 1u);
ASSERT_EQ(appLibPaths[key].size(), 1u);
EXPECT_EQ(appLibPaths[key][0], "/data/storage/el1/bundle/com.test.hspbundle/libs/arm");
EXPECT_EQ(appLibPaths.count("default"), 0u);
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -92,7 +92,7 @@ HWTEST_F(NativeLibUtilTest, GetHspNativeLibPath_0300, TestSize.Level1)
hspInfo.nativeLibraryPath = "";
AppExecFwk::GetHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp);
EXPECT_EQ(appLibPaths.empty(), true);
hspInfo.nativeLibraryPath = "/data/test/nativeLibraryPath";
hspInfo.bundleName = "nativeLibraryTest";
hspInfo.moduleName = "library";
@@ -105,7 +105,7 @@ HWTEST_F(NativeLibUtilTest, GetHspNativeLibPath_0300, TestSize.Level1)
isPreInstallApp = false;
AppExecFwk::GetHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp);
EXPECT_EQ(appLibPaths.empty(), false);
appLibPaths.clear();
hspInfo.compressNativeLibs = true;
AppExecFwk::GetHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp);
@@ -122,12 +122,12 @@ HWTEST_F(NativeLibUtilTest, GetPatchNativeLibPath_0400, TestSize.Level1)
AppExecFwk::HapModuleInfo hapInfo;
std::string patchNativeLibraryPath = "";
AppLibPathMap appLibPaths;
hapInfo.hapPath = "/data/test/NativeLibUtilTest.hap";
hapInfo.isLibIsolated = false;
AppExecFwk::GetPatchNativeLibPath(hapInfo, patchNativeLibraryPath, appLibPaths);
EXPECT_EQ(patchNativeLibraryPath, "");
hapInfo.compressNativeLibs = true;
patchNativeLibraryPath = "/data/test/patchNativeLibraryPath";
AppExecFwk::GetPatchNativeLibPath(hapInfo, patchNativeLibraryPath, appLibPaths);
@@ -141,5 +141,197 @@ HWTEST_F(NativeLibUtilTest, GetPatchNativeLibPath_0400, TestSize.Level1)
AppExecFwk::GetPatchNativeLibPath(hapInfo, patchNativeLibraryPath, appLibPaths);
EXPECT_EQ(appLibPaths.empty(), false);
}
} // namespace AbilityRuntime
/**
* @tc.number: GetLibrarySupportDirectory_0100
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test with empty hapModuleInfos, no paths should be added.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0100, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
EXPECT_TRUE(appLibPaths.empty());
}
/**
* @tc.number: GetLibrarySupportDirectory_0200
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test with hapModuleInfo that has empty librarySupportDirectory, no paths should be added.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0200, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
AppExecFwk::HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
EXPECT_TRUE(appLibPaths.empty());
}
/**
* @tc.number: GetLibrarySupportDirectory_0300
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test with a single hapModuleInfo that has one librarySupportDirectory entry,
* verify exact path value.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0300, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
AppExecFwk::HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"subdir1"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 1u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/subdir1");
}
/**
* @tc.number: GetLibrarySupportDirectory_0400
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test with a single hapModuleInfo that has multiple librarySupportDirectory entries,
* verify exact path values.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0400, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
AppExecFwk::HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"subdir1", "subdir2", "subdir3"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 3u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/subdir1");
EXPECT_EQ(appLibPaths["default"][1], "/data/storage/el1/bundle/libs/arm/subdir2");
EXPECT_EQ(appLibPaths["default"][2], "/data/storage/el1/bundle/libs/arm/subdir3");
}
/**
* @tc.number: GetLibrarySupportDirectory_0500
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test with multiple hapModuleInfos. Only those with non-empty librarySupportDirectory
* should contribute paths. Verify exact count and path content.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0500, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
AppExecFwk::HapModuleInfo hapInfo1;
hapInfo1.librarySupportDirectory = {"dirA"};
hapModuleInfos.push_back(hapInfo1);
AppExecFwk::HapModuleInfo hapInfo2;
hapInfo2.librarySupportDirectory = {};
hapModuleInfos.push_back(hapInfo2);
AppExecFwk::HapModuleInfo hapInfo3;
hapInfo3.librarySupportDirectory = {"dirB", "dirC"};
hapModuleInfos.push_back(hapInfo3);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 3u);
EXPECT_EQ(appLibPaths["default"][0], "/data/storage/el1/bundle/libs/arm/dirA");
// Second module with support dirs: libPath appends nativeLibraryPath again
EXPECT_EQ(appLibPaths["default"][1], "/data/storage/el1/bundle/libs/arm/dirB");
EXPECT_EQ(appLibPaths["default"][2], "/data/storage/el1/bundle/libs/arm/dirC");
}
/**
* @tc.number: GetLibrarySupportDirectory_0600
* @tc.name: GetLibrarySupportDirectory
* @tc.desc: Test that generated path starts with LOCAL_CODE_PATH and ends with support dir name.
*/
HWTEST_F(NativeLibUtilTest, GetLibrarySupportDirectory_0600, TestSize.Level1)
{
std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos;
AppExecFwk::HapModuleInfo hapInfo;
hapInfo.librarySupportDirectory = {"support"};
hapModuleInfos.push_back(hapInfo);
std::string nativeLibraryPath = "libs/arm";
AppLibPathMap appLibPaths;
AppExecFwk::GetLibrarySupportDirectory(hapModuleInfos, nativeLibraryPath, appLibPaths);
ASSERT_EQ(appLibPaths["default"].size(), 1u);
const std::string &path = appLibPaths["default"][0];
EXPECT_EQ(path, "/data/storage/el1/bundle/libs/arm/support");
}
/**
* @tc.number: GetHspNativeLibPath_WithSupportDirectory_0700
* @tc.name: GetHspNativeLibPath with librarySupportDirectory
* @tc.desc: Test that GetHspNativeLibPath adds support directory paths under "default" key
* when librarySupportDirectory is set.
*/
HWTEST_F(NativeLibUtilTest, GetHspNativeLibPath_WithSupportDirectory_0700, TestSize.Level1)
{
AppExecFwk::BaseSharedBundleInfo hspInfo;
AppLibPathMap appLibPaths;
bool isPreInstallApp = true;
hspInfo.bundleName = "com.test.hspbundle";
hspInfo.moduleName = "hsplib";
hspInfo.hapPath = "/data/storage/el1/bundle/com.test.hspbundle/hsplib.hsp";
hspInfo.nativeLibraryPath = "libs/arm";
hspInfo.compressNativeLibs = false;
hspInfo.librarySupportDirectory = {"support1", "support2"};
AppExecFwk::GetHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp);
// Verify the main HSP lib path exists
std::string key = "com.test.hspbundle/hsplib";
ASSERT_EQ(appLibPaths.count(key), 1u);
ASSERT_EQ(appLibPaths[key].size(), 1u);
EXPECT_EQ(appLibPaths[key][0], "/data/storage/el1/bundle/com.test.hspbundle/libs/arm");
// Verify "default" has exactly 2 support directory paths
ASSERT_EQ(appLibPaths.count("default"), 1u);
ASSERT_EQ(appLibPaths["default"].size(), 2u);
EXPECT_EQ(appLibPaths["default"][0],
"/data/storage/el1/bundle/com.test.hspbundle/libs/arm/support1");
EXPECT_EQ(appLibPaths["default"][1],
"/data/storage/el1/bundle/com.test.hspbundle/libs/arm/support2");
}
/**
* @tc.number: GetHspNativeLibPath_NoSupportDirectory_0800
* @tc.name: GetHspNativeLibPath without librarySupportDirectory
* @tc.desc: Test that GetHspNativeLibPath does not add "default" entry
* when librarySupportDirectory is empty.
*/
HWTEST_F(NativeLibUtilTest, GetHspNativeLibPath_NoSupportDirectory_0800, TestSize.Level1)
{
AppExecFwk::BaseSharedBundleInfo hspInfo;
AppLibPathMap appLibPaths;
bool isPreInstallApp = true;
hspInfo.bundleName = "com.test.hspbundle";
hspInfo.moduleName = "hsplib";
hspInfo.hapPath = "/data/storage/el1/bundle/com.test.hspbundle/hsplib.hsp";
hspInfo.nativeLibraryPath = "libs/arm";
hspInfo.compressNativeLibs = false;
hspInfo.librarySupportDirectory = {};
AppExecFwk::GetHspNativeLibPath(hspInfo, appLibPaths, isPreInstallApp);
std::string key = "com.test.hspbundle/hsplib";
ASSERT_EQ(appLibPaths.count(key), 1u);
ASSERT_EQ(appLibPaths[key].size(), 1u);
EXPECT_EQ(appLibPaths[key][0], "/data/storage/el1/bundle/com.test.hspbundle/libs/arm");
EXPECT_EQ(appLibPaths.count("default"), 0u);
}
} // namespace AppExecFwk
} // namespace OHOS