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

Commit 99f4a73a authored by Jooyung Han's avatar Jooyung Han
Browse files

Use libandroid_runtime lazily

This is a part of cutting dependency from libmediandk to
libandroid_runtime.

By making a libandroid_runtime to be loaded lazily,
libmediandk won't load libandroid_runtime when it is used as a LL-NDK.

Bug: 124268753
Test: m -j
Change-Id: Ib040856c58d38e11a5f32cd5dd5519910573334b
parent 5cca289e
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -85,7 +85,6 @@ cc_library_shared {
        "libutils",
        "libcutils",
        "libnativewindow",
        "libandroid_runtime",
        "libbinder",
        "libhidlbase",
        "libgui",
@@ -94,6 +93,12 @@ cc_library_shared {
        "libmediandk_utils",
    ],

    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: {
+0 −1
Original line number Diff line number Diff line
@@ -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>
+67 −5
Original line number Diff line number Diff line
@@ -23,9 +23,7 @@
#include <jni.h>
#include <unistd.h>

#include <android_runtime/AndroidRuntime.h>
#include <android_util_Binder.h>
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
@@ -41,8 +39,67 @@
#include "../../libstagefright/include/NuCachedSource2.h"
#include "NdkMediaDataSourceCallbacksPriv.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

struct AMediaDataSource {
    void *userdata;
    AMediaDataSourceReadAt readAt;
@@ -124,9 +181,14 @@ static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobje
    if (obj == NULL) {
        return NULL;
    }
    sp<IBinder> binder;
    switch (version) {
        case 1:
            return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
            binder = ibinderForJavaObject(env, obj);
            if (binder == NULL) {
                return NULL;
            }
            return interface_cast<IMediaHTTPService>(binder);
        case 2:
            return new JMedia2HTTPService(env, obj);
        default:
@@ -179,7 +241,7 @@ sp<MediaHTTPService> createMediaHttpService(const char *uri, int version) {

    switch (version) {
        case 1:
            env = AndroidRuntime::getJNIEnv();
            env = getJNIEnv();
            clazz = "android/media/MediaHTTPService";
            method = "createHttpServiceBinderIfNecessary";
            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
+0 −1
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
#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>
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,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>
Loading