Merge "Use libandroid_runtime lazily"
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index f71237d..5ece67d 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -77,12 +77,17 @@
         "libutils",
         "libcutils",
         "libnativewindow",
-        "libandroid_runtime",
         "libbinder",
         "libgui",
         "libui",
     ],
 
+    required: [
+        // libmediandk may be used by Java and non-Java things. When lower-level things use it,
+        // they shouldn't have to take on the cost of loading libandroid_runtime.
+        "libandroid_runtime",
+    ],
+
     export_include_dirs: ["include"],
 
     product_variables: {
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 15f3237..9d00df6 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -25,7 +25,7 @@
 #include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <android_media_Utils.h>
-#include <android_runtime/android_view_Surface.h>
+#include <ui/PublicFormat.h>
 #include <private/android/AHardwareBufferHelpers.h>
 #include <grallocusage/GrallocUsageConversion.h>
 
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index d7193ca..00d4520 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -29,7 +29,6 @@
 #include <binder/IServiceManager.h>
 #include <media/ICrypto.h>
 #include <media/IMediaDrmService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index ac837a3..4be71ac 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -33,13 +33,70 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/NuMediaExtractor.h>
 #include <media/IMediaHTTPService.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <android_util_Binder.h>
 
 #include <jni.h>
 
+#include <mutex> // std::call_once,once_flag
+#include <dlfcn.h> // dlopen
+
 using namespace android;
 
+// load libandroid_runtime.so lazily.
+// A vendor process may use libmediandk but should not depend on libandroid_runtime.
+// TODO(jooyung): remove duplicate (b/125550121)
+// frameworks/native/libs/binder/ndk/ibinder_jni.cpp
+namespace {
+
+typedef JNIEnv* (*getJNIEnv_t)();
+typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj);
+
+getJNIEnv_t getJNIEnv_;
+ibinderForJavaObject_t ibinderForJavaObject_;
+
+std::once_flag mLoadFlag;
+
+void load() {
+    std::call_once(mLoadFlag, []() {
+        void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY);
+        if (handle == nullptr) {
+            ALOGE("Could not open libandroid_runtime.");
+            return;
+        }
+
+        getJNIEnv_ = reinterpret_cast<getJNIEnv_t>(
+                dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv"));
+        if (getJNIEnv_ == nullptr) {
+            ALOGE("Could not find AndroidRuntime::getJNIEnv.");
+            // no return
+        }
+
+        ibinderForJavaObject_ = reinterpret_cast<ibinderForJavaObject_t>(
+                dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject"));
+        if (ibinderForJavaObject_ == nullptr) {
+            ALOGE("Could not find ibinderForJavaObject.");
+            // no return
+        }
+    });
+}
+
+JNIEnv* getJNIEnv() {
+    load();
+    if (getJNIEnv_ == nullptr) {
+        return nullptr;
+    }
+    return (getJNIEnv_)();
+}
+
+sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) {
+    load();
+    if (ibinderForJavaObject_ == nullptr) {
+        return nullptr;
+    }
+    return (ibinderForJavaObject_)(env, obj);
+}
+
+} // namespace
+
 static media_status_t translate_error(status_t err) {
     if (err == OK) {
         return AMEDIA_OK;
@@ -87,7 +144,7 @@
     ALOGV("setDataSource(%s)", location);
     // TODO: add header support
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    JNIEnv *env = getJNIEnv();
     jobject service = NULL;
     if (env == NULL) {
         ALOGE("setDataSource(path) must be called from Java thread");
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index f32b83e..20707cc 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -25,7 +25,6 @@
 #include <utils/StrongPointer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index dffc4d7..44cafb2 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -29,7 +29,6 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaMuxer.h>
 #include <media/IMediaHTTPService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>