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

Commit d9cf3a2f authored by Chong Zhang's avatar Chong Zhang
Browse files

Load sw C2 codecs from apex

bug: 111407413
test: crosshatch-userdebug builds, verified C2 sw codecs are used in image
decoding and audio playback;
CTS media heavy presubmit:https://atp.googleplex.com/test_runs/32791402 (failures are pre-existing)

Change-Id: I56f1a98d906ecb1b5b56e642b44eb394d58c9318
parent e22ed7bc
Loading
Loading
Loading
Loading
+44 −85
Original line number Diff line number Diff line
@@ -18,14 +18,10 @@
//#define LOG_NDEBUG 0

#include <android/dlext.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <dirent.h>
#include <dlfcn.h>
#include <media/CodecServiceRegistrant.h>
#include <utils/Log.h>
#include <ziparchive/zip_archive.h>
#include <cutils/properties.h>
#include <utils/String8.h>

#include "MediaCodecUpdateService.h"

@@ -47,90 +43,53 @@ extern "C" {
}

namespace android {
namespace media {

binder::Status MediaCodecUpdateService::loadPlugins(const ::std::string& apkPath) {
    ALOGV("loadPlugins %s", apkPath.c_str());
void loadFromApex(const char *libDirPath) {
    ALOGV("loadFromApex: path=%s", libDirPath);

    ZipArchiveHandle zipHandle;
    void *registrantLib = NULL;
    int32_t ret = OpenArchive(apkPath.c_str(), &zipHandle);
    String8 libPath = String8(libDirPath) + "/libmedia_codecserviceregistrant.so";

    if (ret == 0) {
        char abilist32[PROPERTY_VALUE_MAX];
        property_get("ro.product.cpu.abilist32", abilist32, "armeabi-v7a");

        auto abis = base::Split(abilist32, ",");
        if (abis.empty()) {
            ALOGW("abilist is empty, trying armeabi-v7a ...");
            abis.push_back("armeabi-v7a");
        }

        // TODO: Only try the first entry in abilist32 for now.
        // We probably should try the next if it fails.
        String8 libPathInApk = String8("lib/") + String8(abis[0].c_str());
        String8 defaultLibPath = String8(apkPath.c_str()) + "!/" + libPathInApk;
        String8 libPath = defaultLibPath + "/libmedia_codecserviceregistrant.so";
        String8 zipEntryPath = libPathInApk + "/libmedia_codecserviceregistrant.so";

        ZipEntry entry;
        ret = FindEntry(zipHandle, ZipString(zipEntryPath), &entry);

        if (ret == 0) {
    android_namespace_t *codecNs = android_create_namespace("codecs",
            nullptr,  // ld_library_path
                    defaultLibPath.c_str(),
            libDirPath,
            ANDROID_NAMESPACE_TYPE_ISOLATED,
            nullptr,  // permitted_when_isolated_path
            nullptr); // parent

            if (codecNs != nullptr) {
    if (codecNs == nullptr) {
        ALOGE("Failed to create codec namespace");
        return;
    }

    String8 linked_libraries(LINKED_LIBRARIES);
                if (android_link_namespaces(
                        codecNs, nullptr, linked_libraries.c_str())) {
    if (!android_link_namespaces(codecNs, nullptr, linked_libraries.c_str())) {
        ALOGE("Failed to link namespace");
        return;
    }

    const android_dlextinfo dlextinfo = {
            .flags = ANDROID_DLEXT_USE_NAMESPACE,
            .library_namespace = codecNs,
    };

                    registrantLib = android_dlopen_ext(
    void *registrantLib = android_dlopen_ext(
            libPath.string(),
            RTLD_NOW | RTLD_LOCAL, &dlextinfo);

                    if (registrantLib == NULL) {
    if (registrantLib == nullptr) {
        ALOGE("Failed to load lib from archive: %s", dlerror());
    }
                } else {
                    ALOGE("Failed to link namespace");
                }
            } else {
                ALOGE("Failed to create codec namespace");
            }
        } else {
            ALOGE("Failed to find entry (ret=%d)", ret);
        }

        CloseArchive(zipHandle);
    } else {
        ALOGE("Failed to open archive (ret=%d)", ret);
    }

    if (registrantLib) {
    RegisterCodecServicesFunc registerCodecServices =
            reinterpret_cast<RegisterCodecServicesFunc>(
            dlsym(registrantLib, "RegisterCodecServices"));
        if (registerCodecServices) {
            registerCodecServices();
        } else {
            LOG(WARNING) << "Cannot register codec services "
                    "-- corrupted library.";
        }
    } else {
        LOG(ERROR) << "Cannot find codec service registrant.";

    if (registerCodecServices == nullptr) {
        ALOGE("Cannot register codec services -- corrupted library.");
        return;
    }

    return binder::Status::ok();
    registerCodecServices();
}

}   // namespace media
}   // namespace android
+1 −15
Original line number Diff line number Diff line
@@ -17,24 +17,10 @@
#ifndef ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
#define ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H

#include <binder/BinderService.h>
#include <android/media/BnMediaUpdateService.h>

namespace android {
namespace media {

class MediaCodecUpdateService
    : public BinderService<MediaCodecUpdateService>, public BnMediaUpdateService
{
    friend class BinderService<MediaCodecUpdateService>;
public:
    MediaCodecUpdateService() : BnMediaUpdateService() { }
    virtual ~MediaCodecUpdateService() { }
    static const char* getServiceName() { return "media.codec.update"; }
    binder::Status loadPlugins(const ::std::string& apkPath);
};
void loadFromApex(const char *libDirPath);

}   // namespace media
}   // namespace android

#endif  // ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
+2 −28
Original line number Diff line number Diff line
@@ -20,11 +20,7 @@
// from LOCAL_C_INCLUDES
#include "minijail.h"

#include <android-base/properties.h>
#include <binder/ProcessState.h>
#include <dlfcn.h>
#include <hidl/HidlTransportSupport.h>
#include <media/CodecServiceRegistrant.h>

#include "MediaCodecUpdateService.h"

@@ -49,32 +45,10 @@ int main(int argc __unused, char** /*argv*/)
    signal(SIGPIPE, SIG_IGN);
    SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);

    std::string value = base::GetProperty("ro.build.type", "unknown");
    if (value == "userdebug" || value == "eng") {
        media::MediaCodecUpdateService::instantiate();
    }

    android::ProcessState::self()->startThreadPool();

    ::android::hardware::configureRpcThreadpool(64, false);

    // Registration of customized codec services
    void *registrantLib = dlopen(
            "libmedia_codecserviceregistrant.so",
            RTLD_NOW | RTLD_LOCAL);
    if (registrantLib) {
        RegisterCodecServicesFunc registerCodecServices =
                reinterpret_cast<RegisterCodecServicesFunc>(
                dlsym(registrantLib, "RegisterCodecServices"));
        if (registerCodecServices) {
            registerCodecServices();
        } else {
            LOG(WARNING) << "Cannot register codec services "
                    "-- corrupted library.";
        }
    } else {
        LOG(ERROR) << "Cannot find codec service registrant.";
    }
    // codec libs are currently 32-bit only
    loadFromApex("/apex/com.android.media.swcodec/lib");

    ::android::hardware::joinRpcThreadpool();
}