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
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index bbf87f0..35e0665 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -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 @@
 }
 
 //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 @@
             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 @@
     }
 }
 
+//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 @@
 
     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;
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index 55654f1..e5c67e1 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -48,8 +48,10 @@
     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);
 
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index bbd2afa..bb3dc99 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -34,22 +34,19 @@
 
 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 += \
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 4980316..9f3746f 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -21,6 +21,16 @@
 
 # extractor libraries
 LOCAL_REQUIRED_MODULES := \
+    libaacextractor \
+    libamrextractor \
+    libflacextractor \
+    libmidiextractor \
+    libmkvextractor \
+    libmp3extractor \
+    libmp4extractor \
+    libmpeg2extractor \
+    liboggextractor \
+    libwavextractor \
     MediaComponents \
 
 LOCAL_SRC_FILES := main_extractorservice.cpp