diff options
author | Inseob Kim <inseob@google.com> | 2018-05-04 11:39:12 +0900 |
---|---|---|
committer | Inseob Kim <inseob@google.com> | 2018-05-16 01:36:25 +0000 |
commit | 67cb05654cfa677fd5db33ea0629a9496a9ae907 (patch) | |
tree | 09bf4faaeccf76fa4016db43d231c897a2435bd6 /libnativeloader/native_loader.cpp | |
parent | a3d95cf2f8f5b9acca9be690bc3c6904de6677de (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.cpp | 86 |
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_; |