summaryrefslogtreecommitdiff
path: root/libnativeloader/native_loader.cpp
diff options
context:
space:
mode:
authorInseob Kim <inseob@google.com>2018-05-04 11:39:12 +0900
committerInseob Kim <inseob@google.com>2018-05-16 01:36:25 +0000
commit67cb05654cfa677fd5db33ea0629a9496a9ae907 (patch)
tree09bf4faaeccf76fa4016db43d231c897a2435bd6 /libnativeloader/native_loader.cpp
parenta3d95cf2f8f5b9acca9be690bc3c6904de6677de (diff)
Support product-specific libraries
Product-specific libraries in /product/lib can be exposed to Android apps by adding the list of the libs into /product/etc/public.libraries-<companyname>.txt. The libs MUST be named as lib<name>.<companyname>.so. Bug: 73095206 Test: with taimen mma -j and runtest.sh. The libs are all loaded in system, but not in vendor. After reinstalling app using adb -r and reopening app, only libraries listed in .txt are loaded Change-Id: I7c386813c72a7b225a7f244b6c5fec4ac0660fd3
Diffstat (limited to 'libnativeloader/native_loader.cpp')
-rw-r--r--libnativeloader/native_loader.cpp86
1 files changed, 53 insertions, 33 deletions
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 0ebb22647..7fef10685 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -46,6 +46,8 @@
"%s:%d: %s CHECK '" #predicate "' failed.",\
__FILE__, __LINE__, __FUNCTION__)
+using namespace std::string_literals;
+
namespace android {
#if defined(__ANDROID__)
@@ -236,10 +238,15 @@ class LibraryNamespaces {
// Different name is useful for debugging
namespace_name = kVendorClassloaderNamespaceName;
ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
- } else if (!oem_public_libraries_.empty()) {
- // oem_public_libraries are NOT available to vendor apks, otherwise it
+ } else {
+ // oem and product public libraries are NOT available to vendor apks, otherwise it
// would be system->vendor violation.
- system_exposed_libraries = system_exposed_libraries + ":" + oem_public_libraries_.c_str();
+ if (!oem_public_libraries_.empty()) {
+ system_exposed_libraries = system_exposed_libraries + ':' + oem_public_libraries_;
+ }
+ if (!product_public_libraries_.empty()) {
+ system_exposed_libraries = system_exposed_libraries + ':' + product_public_libraries_;
+ }
}
NativeLoaderNamespace native_loader_ns;
@@ -351,6 +358,8 @@ class LibraryNamespaces {
std::string vndksp_native_libraries_system_config =
root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
+ std::string product_public_native_libraries_dir = "/product/etc";
+
std::string error_msg;
LOG_ALWAYS_FATAL_IF(
!ReadConfig(public_native_libraries_system_config, &sonames, always_true, &error_msg),
@@ -373,7 +382,7 @@ class LibraryNamespaces {
//
// TODO(dimitry): this is a bit misleading since we do not know
// if the vendor public library is going to be opened from /vendor/lib
- // we might as well end up loading them from /system/lib
+ // we might as well end up loading them from /system/lib or /product/lib
// For now we rely on CTS test to catch things like this but
// it should probably be addressed in the future.
for (const auto& soname : sonames) {
@@ -387,13 +396,43 @@ class LibraryNamespaces {
// system libs that are exposed to apps. The libs in the txt files must be
// named as lib<name>.<companyname>.so.
sonames.clear();
- std::string dirname = base::Dirname(public_native_libraries_system_config);
- std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname.c_str()), closedir);
+ ReadExtensionLibraries(base::Dirname(public_native_libraries_system_config).c_str(), &sonames);
+ oem_public_libraries_ = base::Join(sonames, ':');
+
+ // read /product/etc/public.libraries-<companyname>.txt which contain partner defined
+ // product libs that are exposed to apps.
+ sonames.clear();
+ ReadExtensionLibraries(product_public_native_libraries_dir.c_str(), &sonames);
+ product_public_libraries_ = base::Join(sonames, ':');
+
+ // Insert VNDK version to llndk and vndksp config file names.
+ insert_vndk_version_str(&llndk_native_libraries_system_config);
+ insert_vndk_version_str(&vndksp_native_libraries_system_config);
+
+ sonames.clear();
+ ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
+ system_llndk_libraries_ = base::Join(sonames, ':');
+
+ sonames.clear();
+ ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
+ system_vndksp_libraries_ = base::Join(sonames, ':');
+
+ sonames.clear();
+ // This file is optional, quietly ignore if the file does not exist.
+ ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames, always_true, nullptr);
+
+ vendor_public_libraries_ = base::Join(sonames, ':');
+ }
+
+ void Reset() { namespaces_.clear(); }
+
+ private:
+ void ReadExtensionLibraries(const char* dirname, std::vector<std::string>* sonames) {
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname), closedir);
if (dir != nullptr) {
// Failing to opening the dir is not an error, which can happen in
// webview_zygote.
- struct dirent* ent;
- while ((ent = readdir(dir.get())) != nullptr) {
+ while (struct dirent* ent = readdir(dir.get())) {
if (ent->d_type != DT_REG && ent->d_type != DT_LNK) {
continue;
}
@@ -403,14 +442,17 @@ class LibraryNamespaces {
const size_t start = kPublicNativeLibrariesExtensionConfigPrefixLen;
const size_t end = filename.size() - kPublicNativeLibrariesExtensionConfigSuffixLen;
const std::string company_name = filename.substr(start, end - start);
- const std::string config_file_path = dirname + "/" + filename;
+ const std::string config_file_path = dirname + "/"s + filename;
LOG_ALWAYS_FATAL_IF(
company_name.empty(),
"Error extracting company name from public native library list file path \"%s\"",
config_file_path.c_str());
+
+ std::string error_msg;
+
LOG_ALWAYS_FATAL_IF(
!ReadConfig(
- config_file_path, &sonames,
+ config_file_path, sonames,
[&company_name](const std::string& soname, std::string* error_msg) {
if (android::base::StartsWith(soname, "lib") &&
android::base::EndsWith(soname, "." + company_name + ".so")) {
@@ -427,32 +469,9 @@ class LibraryNamespaces {
}
}
}
- oem_public_libraries_ = base::Join(sonames, ':');
-
- // Insert VNDK version to llndk and vndksp config file names.
- insert_vndk_version_str(&llndk_native_libraries_system_config);
- insert_vndk_version_str(&vndksp_native_libraries_system_config);
-
- sonames.clear();
- ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
- system_llndk_libraries_ = base::Join(sonames, ':');
-
- sonames.clear();
- ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
- system_vndksp_libraries_ = base::Join(sonames, ':');
-
- sonames.clear();
- // This file is optional, quietly ignore if the file does not exist.
- ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames, always_true, nullptr);
-
- vendor_public_libraries_ = base::Join(sonames, ':');
}
- void Reset() {
- namespaces_.clear();
- }
- private:
bool ReadConfig(const std::string& configFile, std::vector<std::string>* sonames,
const std::function<bool(const std::string& /* soname */,
std::string* /* error_msg */)>& check_soname,
@@ -559,6 +578,7 @@ class LibraryNamespaces {
std::string system_public_libraries_;
std::string vendor_public_libraries_;
std::string oem_public_libraries_;
+ std::string product_public_libraries_;
std::string system_llndk_libraries_;
std::string system_vndksp_libraries_;