Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80587c45 authored by Yiwei Zhang's avatar Yiwei Zhang Committed by Android (Google) Code Review
Browse files

Merge "Updatable Driver: Decouple gfx_driver from sphal"

parents 4f16b43f 64d89214
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -22,8 +22,9 @@ cc_library_shared {
    cflags: ["-Wall", "-Werror"],

    shared_libs: [
        "liblog",
        "libbase",
        "libcutils",
        "liblog",
    ],

    export_include_dirs: ["include"],
+114 −26
Original line number Diff line number Diff line
@@ -18,23 +18,27 @@
#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,
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,
@@ -44,6 +48,69 @@ extern "C" {

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());
@@ -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,
                                                    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;
}