diff options
| -rw-r--r-- | libs/graphicsenv/Android.bp | 3 | ||||
| -rw-r--r-- | libs/graphicsenv/GraphicsEnv.cpp | 140 |
2 files changed, 116 insertions, 27 deletions
diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp index bab87acb05..280c14a3ea 100644 --- a/libs/graphicsenv/Android.bp +++ b/libs/graphicsenv/Android.bp @@ -22,8 +22,9 @@ cc_library_shared { cflags: ["-Wall", "-Werror"], shared_libs: [ - "liblog", + "libbase", "libcutils", + "liblog", ], export_include_dirs: ["include"], diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index afa32b6d63..c2a6764338 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -18,32 +18,99 @@ #define LOG_TAG "GraphicsEnv" #include <graphicsenv/GraphicsEnv.h> -#include <sys/prctl.h> - -#include <mutex> +#include <dlfcn.h> +#include <android-base/file.h> +#include <android-base/properties.h> +#include <android-base/strings.h> #include <android/dlext.h> #include <cutils/properties.h> #include <log/log.h> +#include <sys/prctl.h> + +#include <mutex> // TODO(b/37049319) Get this from a header once one exists extern "C" { - android_namespace_t* android_get_exported_namespace(const char*); - android_namespace_t* android_create_namespace(const char* name, - const char* ld_library_path, - const char* default_library_path, - uint64_t type, - const char* permitted_when_isolated_path, - android_namespace_t* parent); +android_namespace_t* android_get_exported_namespace(const char*); +android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path, + const char* default_library_path, uint64_t type, + const char* permitted_when_isolated_path, + android_namespace_t* parent); +bool android_link_namespaces(android_namespace_t* from, android_namespace_t* to, + const char* shared_libs_sonames); - enum { - ANDROID_NAMESPACE_TYPE_ISOLATED = 1, - ANDROID_NAMESPACE_TYPE_SHARED = 2, - }; +enum { + ANDROID_NAMESPACE_TYPE_ISOLATED = 1, + ANDROID_NAMESPACE_TYPE_SHARED = 2, +}; } namespace android { +enum NativeLibrary { + LLNDK = 0, + VNDKSP = 1, +}; + +static constexpr const char* kNativeLibrariesSystemConfigPath[] = {"/etc/llndk.libraries.txt", + "/etc/vndksp.libraries.txt"}; + +static std::string vndkVersionStr() { +#ifdef __BIONIC__ + std::string version = android::base::GetProperty("ro.vndk.version", ""); + if (version != "" && version != "current") { + return "." + version; + } +#endif + return ""; +} + +static void insertVndkVersionStr(std::string* fileName) { + LOG_ALWAYS_FATAL_IF(!fileName, "fileName should never be nullptr"); + size_t insertPos = fileName->find_last_of("."); + if (insertPos == std::string::npos) { + insertPos = fileName->length(); + } + fileName->insert(insertPos, vndkVersionStr()); +} + +static bool readConfig(const std::string& configFile, std::vector<std::string>* soNames) { + // Read list of public native libraries from the config file. + std::string fileContent; + if (!base::ReadFileToString(configFile, &fileContent)) { + return false; + } + + std::vector<std::string> lines = base::Split(fileContent, "\n"); + + for (auto& line : lines) { + auto trimmedLine = base::Trim(line); + if (!trimmedLine.empty()) { + soNames->push_back(trimmedLine); + } + } + + return true; +} + +static const std::string getSystemNativeLibraries(NativeLibrary type) { + static const char* androidRootEnv = getenv("ANDROID_ROOT"); + static const std::string rootDir = androidRootEnv != nullptr ? androidRootEnv : "/system"; + + std::string nativeLibrariesSystemConfig = rootDir + kNativeLibrariesSystemConfigPath[type]; + + insertVndkVersionStr(&nativeLibrariesSystemConfig); + + std::vector<std::string> soNames; + if (!readConfig(nativeLibrariesSystemConfig, &soNames)) { + ALOGE("Failed to retrieve library names from %s", nativeLibrariesSystemConfig.c_str()); + return ""; + } + + return base::Join(soNames, ':'); +} + /*static*/ GraphicsEnv& GraphicsEnv::getInstance() { static GraphicsEnv env; return env; @@ -59,8 +126,8 @@ int GraphicsEnv::getCanLoadSystemLibraries() { void GraphicsEnv::setDriverPath(const std::string path) { if (!mDriverPath.empty()) { - ALOGV("ignoring attempt to change driver path from '%s' to '%s'", - mDriverPath.c_str(), path.c_str()); + ALOGV("ignoring attempt to change driver path from '%s' to '%s'", mDriverPath.c_str(), + path.c_str()); return; } ALOGV("setting driver path to '%s'", path.c_str()); @@ -102,7 +169,7 @@ void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std:: mAppNamespace = appNamespace; } else { ALOGV("Vulkan layer search path already set, not clobbering with '%s' for namespace %p'", - layerPaths.c_str(), appNamespace); + layerPaths.c_str(), appNamespace); } } @@ -154,20 +221,41 @@ void GraphicsEnv::setDebugLayersGLES(const std::string layers) { android_namespace_t* GraphicsEnv::getDriverNamespace() { static std::once_flag once; std::call_once(once, [this]() { - if (mDriverPath.empty()) - return; - // If the sphal namespace isn't configured for a device, don't support updatable drivers. - // We need a parent namespace to inherit the default search path from. - auto sphalNamespace = android_get_exported_namespace("sphal"); - if (!sphalNamespace) return; + if (mDriverPath.empty()) return; + + auto vndkNamespace = android_get_exported_namespace("vndk"); + if (!vndkNamespace) return; + mDriverNamespace = android_create_namespace("gfx driver", mDriverPath.c_str(), // ld_library_path mDriverPath.c_str(), // default_library_path - ANDROID_NAMESPACE_TYPE_SHARED | - ANDROID_NAMESPACE_TYPE_ISOLATED, + ANDROID_NAMESPACE_TYPE_ISOLATED, nullptr, // permitted_when_isolated_path - sphalNamespace); + nullptr); + + const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK); + if (llndkLibraries.empty()) { + mDriverNamespace = nullptr; + return; + } + if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { + ALOGE("Failed to link default namespace[%s]", dlerror()); + mDriverNamespace = nullptr; + return; + } + + const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); + if (vndkspLibraries.empty()) { + mDriverNamespace = nullptr; + return; + } + if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { + ALOGE("Failed to link vndk namespace[%s]", dlerror()); + mDriverNamespace = nullptr; + return; + } }); + return mDriverNamespace; } |