Skip to content

Commit 39cab7c

Browse files
Treehugger RobotGerrit Code Review
authored andcommitted
Merge "Support product-specific libraries"
2 parents 98c1b1c + 67cb056 commit 39cab7c

File tree

7 files changed

+104
-37
lines changed

7 files changed

+104
-37
lines changed

libnativeloader/native_loader.cpp

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
"%s:%d: %s CHECK '" #predicate "' failed.",\
4747
__FILE__, __LINE__, __FUNCTION__)
4848

49+
using namespace std::string_literals;
50+
4951
namespace android {
5052

5153
#if defined(__ANDROID__)
@@ -236,10 +238,15 @@ class LibraryNamespaces {
236238
// Different name is useful for debugging
237239
namespace_name = kVendorClassloaderNamespaceName;
238240
ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
239-
} else if (!oem_public_libraries_.empty()) {
240-
// oem_public_libraries are NOT available to vendor apks, otherwise it
241+
} else {
242+
// oem and product public libraries are NOT available to vendor apks, otherwise it
241243
// would be system->vendor violation.
242-
system_exposed_libraries = system_exposed_libraries + ":" + oem_public_libraries_.c_str();
244+
if (!oem_public_libraries_.empty()) {
245+
system_exposed_libraries = system_exposed_libraries + ':' + oem_public_libraries_;
246+
}
247+
if (!product_public_libraries_.empty()) {
248+
system_exposed_libraries = system_exposed_libraries + ':' + product_public_libraries_;
249+
}
243250
}
244251

245252
NativeLoaderNamespace native_loader_ns;
@@ -351,6 +358,8 @@ class LibraryNamespaces {
351358
std::string vndksp_native_libraries_system_config =
352359
root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
353360

361+
std::string product_public_native_libraries_dir = "/product/etc";
362+
354363
std::string error_msg;
355364
LOG_ALWAYS_FATAL_IF(
356365
!ReadConfig(public_native_libraries_system_config, &sonames, always_true, &error_msg),
@@ -373,7 +382,7 @@ class LibraryNamespaces {
373382
//
374383
// TODO(dimitry): this is a bit misleading since we do not know
375384
// if the vendor public library is going to be opened from /vendor/lib
376-
// we might as well end up loading them from /system/lib
385+
// we might as well end up loading them from /system/lib or /product/lib
377386
// For now we rely on CTS test to catch things like this but
378387
// it should probably be addressed in the future.
379388
for (const auto& soname : sonames) {
@@ -387,13 +396,43 @@ class LibraryNamespaces {
387396
// system libs that are exposed to apps. The libs in the txt files must be
388397
// named as lib<name>.<companyname>.so.
389398
sonames.clear();
390-
std::string dirname = base::Dirname(public_native_libraries_system_config);
391-
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname.c_str()), closedir);
399+
ReadExtensionLibraries(base::Dirname(public_native_libraries_system_config).c_str(), &sonames);
400+
oem_public_libraries_ = base::Join(sonames, ':');
401+
402+
// read /product/etc/public.libraries-<companyname>.txt which contain partner defined
403+
// product libs that are exposed to apps.
404+
sonames.clear();
405+
ReadExtensionLibraries(product_public_native_libraries_dir.c_str(), &sonames);
406+
product_public_libraries_ = base::Join(sonames, ':');
407+
408+
// Insert VNDK version to llndk and vndksp config file names.
409+
insert_vndk_version_str(&llndk_native_libraries_system_config);
410+
insert_vndk_version_str(&vndksp_native_libraries_system_config);
411+
412+
sonames.clear();
413+
ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
414+
system_llndk_libraries_ = base::Join(sonames, ':');
415+
416+
sonames.clear();
417+
ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
418+
system_vndksp_libraries_ = base::Join(sonames, ':');
419+
420+
sonames.clear();
421+
// This file is optional, quietly ignore if the file does not exist.
422+
ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames, always_true, nullptr);
423+
424+
vendor_public_libraries_ = base::Join(sonames, ':');
425+
}
426+
427+
void Reset() { namespaces_.clear(); }
428+
429+
private:
430+
void ReadExtensionLibraries(const char* dirname, std::vector<std::string>* sonames) {
431+
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname), closedir);
392432
if (dir != nullptr) {
393433
// Failing to opening the dir is not an error, which can happen in
394434
// webview_zygote.
395-
struct dirent* ent;
396-
while ((ent = readdir(dir.get())) != nullptr) {
435+
while (struct dirent* ent = readdir(dir.get())) {
397436
if (ent->d_type != DT_REG && ent->d_type != DT_LNK) {
398437
continue;
399438
}
@@ -403,14 +442,17 @@ class LibraryNamespaces {
403442
const size_t start = kPublicNativeLibrariesExtensionConfigPrefixLen;
404443
const size_t end = filename.size() - kPublicNativeLibrariesExtensionConfigSuffixLen;
405444
const std::string company_name = filename.substr(start, end - start);
406-
const std::string config_file_path = dirname + "/" + filename;
445+
const std::string config_file_path = dirname + "/"s + filename;
407446
LOG_ALWAYS_FATAL_IF(
408447
company_name.empty(),
409448
"Error extracting company name from public native library list file path \"%s\"",
410449
config_file_path.c_str());
450+
451+
std::string error_msg;
452+
411453
LOG_ALWAYS_FATAL_IF(
412454
!ReadConfig(
413-
config_file_path, &sonames,
455+
config_file_path, sonames,
414456
[&company_name](const std::string& soname, std::string* error_msg) {
415457
if (android::base::StartsWith(soname, "lib") &&
416458
android::base::EndsWith(soname, "." + company_name + ".so")) {
@@ -427,32 +469,9 @@ class LibraryNamespaces {
427469
}
428470
}
429471
}
430-
oem_public_libraries_ = base::Join(sonames, ':');
431-
432-
// Insert VNDK version to llndk and vndksp config file names.
433-
insert_vndk_version_str(&llndk_native_libraries_system_config);
434-
insert_vndk_version_str(&vndksp_native_libraries_system_config);
435-
436-
sonames.clear();
437-
ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
438-
system_llndk_libraries_ = base::Join(sonames, ':');
439-
440-
sonames.clear();
441-
ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
442-
system_vndksp_libraries_ = base::Join(sonames, ':');
443-
444-
sonames.clear();
445-
// This file is optional, quietly ignore if the file does not exist.
446-
ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames, always_true, nullptr);
447-
448-
vendor_public_libraries_ = base::Join(sonames, ':');
449472
}
450473

451-
void Reset() {
452-
namespaces_.clear();
453-
}
454474

455-
private:
456475
bool ReadConfig(const std::string& configFile, std::vector<std::string>* sonames,
457476
const std::function<bool(const std::string& /* soname */,
458477
std::string* /* error_msg */)>& check_soname,
@@ -559,6 +578,7 @@ class LibraryNamespaces {
559578
std::string system_public_libraries_;
560579
std::string vendor_public_libraries_;
561580
std::string oem_public_libraries_;
581+
std::string product_public_libraries_;
562582
std::string system_llndk_libraries_;
563583
std::string system_vndksp_libraries_;
564584

libnativeloader/test/Android.bp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,23 @@ cc_library {
4949
"libbase",
5050
],
5151
}
52+
53+
cc_library {
54+
name: "libfoo.product1",
55+
srcs: ["test.cpp"],
56+
cflags: ["-DLIBNAME=\"libfoo.product1.so\""],
57+
product_specific: true,
58+
shared_libs: [
59+
"libbase",
60+
],
61+
}
62+
63+
cc_library {
64+
name: "libbar.product1",
65+
srcs: ["test.cpp"],
66+
cflags: ["-DLIBNAME=\"libbar.product1.so\""],
67+
product_specific: true,
68+
shared_libs: [
69+
"libbase",
70+
],
71+
}

libnativeloader/test/Android.mk

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ LOCAL_MODULE_CLASS := ETC
2929
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
3030
include $(BUILD_PREBUILT)
3131

32+
include $(CLEAR_VARS)
33+
LOCAL_MODULE := public.libraries-product1.txt
34+
LOCAL_SRC_FILES:= $(LOCAL_MODULE)
35+
LOCAL_MODULE_CLASS := ETC
36+
LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT_ETC)
37+
include $(BUILD_PREBUILT)
38+
3239
include $(CLEAR_VARS)
3340
LOCAL_PACKAGE_NAME := oemlibrarytest-system
3441
LOCAL_MODULE_TAGS := tests
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
libfoo.product1.so
2+
libbar.product1.so

libnativeloader/test/src/android/test/app/TestActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public void onCreate(Bundle icicle) {
2929
tryLoadingLib("bar.oem1");
3030
tryLoadingLib("foo.oem2");
3131
tryLoadingLib("bar.oem2");
32+
tryLoadingLib("foo.product1");
33+
tryLoadingLib("bar.product1");
3234
}
3335

3436
private void tryLoadingLib(String name) {

rootdir/etc/ld.config.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ additional.namespaces = sphal,vndk,rs
3737
###############################################################################
3838
namespace.default.isolated = true
3939

40-
namespace.default.search.paths = /system/${LIB}
40+
namespace.default.search.paths = /system/${LIB}
41+
namespace.default.search.paths += /product/${LIB}
4142

4243
# We can't have entire /system/${LIB} as permitted paths because doing so
4344
# makes it possible to load libs in /system/${LIB}/vndk* directories by
@@ -49,6 +50,7 @@ namespace.default.search.paths = /system/${LIB}
4950
namespace.default.permitted.paths = /system/${LIB}/drm
5051
namespace.default.permitted.paths += /system/${LIB}/extractors
5152
namespace.default.permitted.paths += /system/${LIB}/hw
53+
namespace.default.permitted.paths += /product/${LIB}
5254
# These are where odex files are located. libart has to be able to dlopen the files
5355
namespace.default.permitted.paths += /system/framework
5456
namespace.default.permitted.paths += /system/app
@@ -68,6 +70,8 @@ namespace.default.permitted.paths += /mnt/expand
6870

6971
namespace.default.asan.search.paths = /data/asan/system/${LIB}
7072
namespace.default.asan.search.paths += /system/${LIB}
73+
namespace.default.asan.search.paths += /data/asan/product/${LIB}
74+
namespace.default.asan.search.paths += /product/${LIB}
7175

7276
namespace.default.asan.permitted.paths = /data
7377
namespace.default.asan.permitted.paths += /system/${LIB}/drm
@@ -83,6 +87,7 @@ namespace.default.asan.permitted.paths += /odm/framework
8387
namespace.default.asan.permitted.paths += /odm/app
8488
namespace.default.asan.permitted.paths += /odm/priv-app
8589
namespace.default.asan.permitted.paths += /oem/app
90+
namespace.default.asan.permitted.paths += /product/${LIB}
8691
namespace.default.asan.permitted.paths += /product/framework
8792
namespace.default.asan.permitted.paths += /product/app
8893
namespace.default.asan.permitted.paths += /product/priv-app
@@ -320,10 +325,13 @@ namespace.vndk.link.default.allow_all_shared_libs = true
320325
###############################################################################
321326
namespace.system.isolated = false
322327

323-
namespace.system.search.paths = /system/${LIB}
328+
namespace.system.search.paths = /system/${LIB}
329+
namespace.system.search.paths += /product/${LIB}
324330

325331
namespace.system.asan.search.paths = /data/asan/system/${LIB}
326332
namespace.system.asan.search.paths += /system/${LIB}
333+
namespace.system.asan.search.paths += /data/asan/product/${LIB}
334+
namespace.system.asan.search.paths += /product/${LIB}
327335

328336
###############################################################################
329337
# Namespace config for binaries under /postinstall.
@@ -335,4 +343,5 @@ namespace.system.asan.search.paths += /system/${LIB}
335343
###############################################################################
336344
[postinstall]
337345
namespace.default.isolated = false
338-
namespace.default.search.paths = /system/${LIB}
346+
namespace.default.search.paths = /system/${LIB}
347+
namespace.default.search.paths += /product/${LIB}

rootdir/etc/ld.config.vndk_lite.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ namespace.default.isolated = false
4040
namespace.default.search.paths = /system/${LIB}
4141
namespace.default.search.paths += /odm/${LIB}
4242
namespace.default.search.paths += /vendor/${LIB}
43+
namespace.default.search.paths += /product/${LIB}
4344

4445
namespace.default.asan.search.paths = /data/asan/system/${LIB}
4546
namespace.default.asan.search.paths += /system/${LIB}
4647
namespace.default.asan.search.paths += /data/asan/odm/${LIB}
4748
namespace.default.asan.search.paths += /odm/${LIB}
4849
namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
4950
namespace.default.asan.search.paths += /vendor/${LIB}
51+
namespace.default.asan.search.paths += /data/asan/product/${LIB}
52+
namespace.default.asan.search.paths += /product/${LIB}
5053

5154
###############################################################################
5255
# "sphal" namespace
@@ -205,6 +208,7 @@ namespace.default.search.paths += /vendor/${LIB}/vndk-sp
205208
namespace.default.search.paths += /system/${LIB}/vndk%VNDK_VER%
206209
namespace.default.search.paths += /system/${LIB}/vndk-sp%VNDK_VER%
207210
namespace.default.search.paths += /system/${LIB}
211+
namespace.default.search.paths += /product/${LIB}
208212

209213
namespace.default.asan.search.paths = /data/asan/odm/${LIB}
210214
namespace.default.asan.search.paths += /odm/${LIB}
@@ -224,6 +228,8 @@ namespace.default.asan.search.paths += /data/asan/system/${LIB}/vndk-sp%VNDK_VER
224228
namespace.default.asan.search.paths += /system/${LIB}/vndk-sp%VNDK_VER%
225229
namespace.default.asan.search.paths += /data/asan/system/${LIB}
226230
namespace.default.asan.search.paths += /system/${LIB}
231+
namespace.default.asan.search.paths += /data/asan/product/${LIB}
232+
namespace.default.asan.search.paths += /product/${LIB}
227233

228234
###############################################################################
229235
# Namespace config for binaries under /postinstall.
@@ -235,4 +241,5 @@ namespace.default.asan.search.paths += /system/${LIB}
235241
###############################################################################
236242
[postinstall]
237243
namespace.default.isolated = false
238-
namespace.default.search.paths = /system/${LIB}
244+
namespace.default.search.paths = /system/${LIB}
245+
namespace.default.search.paths += /product/${LIB}

0 commit comments

Comments
 (0)