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

Commit 767456df authored by Dongwon Kang's avatar Dongwon Kang
Browse files

Load system extractor plugins from /system|vendor/lib[64]/extractors.

Plugins will be placed under /system|vendor/lib[64]/extractors and the
device will include a stub MediaComponents apk for later update.

Test: boots and play mp4 files
Bug: 67908547
Change-Id: I5ab30093d9dd50324ba327baa8270a204e10f8a5
parent 3e4d2ed6
Loading
Loading
Loading
Loading
+47 −5
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@

namespace android {

static const char *kSystemApkPath = "/system/app/MediaComponents/MediaComponents.apk";

// static
sp<IMediaExtractor> MediaExtractorFactory::Create(
        const sp<DataSource> &source, const char *mime) {
@@ -246,7 +244,7 @@ void MediaExtractorFactory::RegisterExtractor(const sp<ExtractorPlugin> &plugin,
}

//static
void MediaExtractorFactory::RegisterExtractors(
void MediaExtractorFactory::RegisterExtractorsInApk(
        const char *apkPath, List<sp<ExtractorPlugin>> &pluginList) {
    ALOGV("search for plugins at %s", apkPath);
    ZipArchiveHandle zipHandle;
@@ -264,6 +262,8 @@ void MediaExtractorFactory::RegisterExtractors(
            while (Next(cookie, &entry, &name) == 0) {
                String8 libPath = String8(apkPath) + "!/" +
                    String8(reinterpret_cast<const char*>(name.name), name.name_length);
                // TODO: Open with a linker namespace so that it can be linked with sub-libraries
                // within the apk instead of system libraries already loaded.
                void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
                if (libHandle) {
                    MediaExtractor::GetExtractorDef getDef =
@@ -290,6 +290,38 @@ void MediaExtractorFactory::RegisterExtractors(
    }
}

//static
void MediaExtractorFactory::RegisterExtractorsInSystem(
        const char *libDirPath, List<sp<ExtractorPlugin>> &pluginList) {
    ALOGV("search for plugins at %s", libDirPath);
    DIR *libDir = opendir(libDirPath);
    if (libDir) {
        struct dirent* libEntry;
        while ((libEntry = readdir(libDir))) {
            String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;
            void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
            if (libHandle) {
                MediaExtractor::GetExtractorDef getDef =
                    (MediaExtractor::GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
                if (getDef) {
                    ALOGV("registering sniffer for %s", libPath.string());
                    RegisterExtractor(
                            new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
                } else {
                    ALOGW("%s does not contain sniffer", libPath.string());
                    dlclose(libHandle);
                }
            } else {
                ALOGW("couldn't dlopen(%s) %s", libPath.string(), strerror(errno));
            }
        }

        closedir(libDir);
    } else {
        ALOGE("couldn't opendir(%s)", libDirPath);
    }
}

// static
void MediaExtractorFactory::UpdateExtractors(const char *newUpdateApkPath) {
    Mutex::Autolock autoLock(gPluginMutex);
@@ -302,10 +334,20 @@ void MediaExtractorFactory::UpdateExtractors(const char *newUpdateApkPath) {

    std::shared_ptr<List<sp<ExtractorPlugin>>> newList(new List<sp<ExtractorPlugin>>());

    RegisterExtractors(kSystemApkPath, *newList);
    RegisterExtractorsInSystem("/system/lib"
#ifdef __LP64__
            "64"
#endif
            "/extractors", *newList);

    RegisterExtractorsInSystem("/vendor/lib"
#ifdef __LP64__
            "64"
#endif
            "/extractors", *newList);

    if (newUpdateApkPath != nullptr) {
        RegisterExtractors(newUpdateApkPath, *newList);
        RegisterExtractorsInApk(newUpdateApkPath, *newList);
    }

    gPlugins = newList;
+3 −1
Original line number Diff line number Diff line
@@ -48,8 +48,10 @@ private:
    static std::shared_ptr<List<sp<ExtractorPlugin>>> gPlugins;
    static bool gPluginsRegistered;

    static void RegisterExtractors(
    static void RegisterExtractorsInApk(
            const char *apkPath, List<sp<ExtractorPlugin>> &pluginList);
    static void RegisterExtractorsInSystem(
            const char *libDirPath, List<sp<ExtractorPlugin>> &pluginList);
    static void RegisterExtractor(
            const sp<ExtractorPlugin> &plugin, List<sp<ExtractorPlugin>> &pluginList);

+12 −15
Original line number Diff line number Diff line
@@ -34,22 +34,19 @@ LOCAL_MULTILIB := first

LOCAL_JAVA_LIBRARIES += android-support-annotations

# Embed native libraries in package, rather than installing to /system/lib*.
# TODO: Find a right way to include libs in the apk. b/72066556
LOCAL_MODULE_TAGS := samples

# To embed native libraries in package, uncomment the lines below.
LOCAL_JNI_SHARED_LIBRARIES := \
    libaacextractor \
    libamrextractor \
    libflacextractor \
    libmidiextractor \
    libmkvextractor \
    libmp3extractor \
    libmp4extractor \
    libmpeg2extractor \
    liboggextractor \
    libwavextractor \
#LOCAL_MODULE_TAGS := samples
#LOCAL_JNI_SHARED_LIBRARIES := \
#    libaacextractor \
#    libamrextractor \
#    libflacextractor \
#    libmidiextractor \
#    libmkvextractor \
#    libmp3extractor \
#    libmp4extractor \
#    libmpeg2extractor \
#    liboggextractor \
#    libwavextractor \

# TODO: Remove dependency with other support libraries.
LOCAL_STATIC_ANDROID_LIBRARIES += \
+10 −0
Original line number Diff line number Diff line
@@ -21,6 +21,16 @@ LOCAL_REQUIRED_MODULES_x86 := mediaextractor.policy

# extractor libraries
LOCAL_REQUIRED_MODULES := \
    libaacextractor \
    libamrextractor \
    libflacextractor \
    libmidiextractor \
    libmkvextractor \
    libmp3extractor \
    libmp4extractor \
    libmpeg2extractor \
    liboggextractor \
    libwavextractor \
    MediaComponents \

LOCAL_SRC_FILES := main_extractorservice.cpp