diff options
| author | 2019-01-25 19:43:24 -0800 | |
|---|---|---|
| committer | 2019-01-25 19:43:24 -0800 | |
| commit | 91ce1b6dde9b8b72959ac6b4c324e34c47bd38d6 (patch) | |
| tree | 89feb20c2ffae9f8a72a14a750d97a0f4c179bdd | |
| parent | 7f15bb9d575469a8e5443e3cf9567695b82bb3b7 (diff) | |
| parent | 5a8d6ccb0f0bf57214cbda2c7d095049007b1241 (diff) | |
Merge "Load libandroid_runtime lazily."
am: 5a8d6ccb0f
Change-Id: I31fe8e26e6c24d77b5119f3ce976d21cd7118ecf
| -rw-r--r-- | libs/binder/ndk/Android.bp | 7 | ||||
| -rw-r--r-- | libs/binder/ndk/ibinder_jni.cpp | 68 |
2 files changed, 69 insertions, 6 deletions
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index 05655c18c5..0826544d89 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -39,12 +39,17 @@ cc_library { ], shared_libs: [ - "libandroid_runtime", "libbase", "libbinder", "libutils", ], + required: [ + // libbinder_ndk 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", + ], + version_script: "libbinder_ndk.map.txt", stubs: { symbol_file: "libbinder_ndk.map.txt", diff --git a/libs/binder/ndk/ibinder_jni.cpp b/libs/binder/ndk/ibinder_jni.cpp index baea2e87d3..4a31080824 100644 --- a/libs/binder/ndk/ibinder_jni.cpp +++ b/libs/binder/ndk/ibinder_jni.cpp @@ -17,15 +17,68 @@ #include <android/binder_ibinder_jni.h> #include "ibinder_internal.h" -#include <android_util_Binder.h> +#include <android-base/logging.h> +#include <binder/IBinder.h> + +#include <mutex> + +#include <dlfcn.h> using ::android::IBinder; -using ::android::ibinderForJavaObject; -using ::android::javaObjectForIBinder; using ::android::sp; +struct LazyAndroidRuntime { + typedef sp<IBinder> (*FromJava)(JNIEnv* env, jobject obj); + typedef jobject (*ToJava)(JNIEnv* env, const sp<IBinder>& val); + + static FromJava ibinderForJavaObject; + static ToJava javaObjectForIBinder; + + static void load() { + std::call_once(mLoadFlag, []() { + void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY); + if (handle == nullptr) { + LOG(WARNING) << "Could not open libandroid_runtime."; + return; + } + + ibinderForJavaObject = reinterpret_cast<FromJava>( + dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject")); + if (ibinderForJavaObject == nullptr) { + LOG(WARNING) << "Could not find ibinderForJavaObject."; + // no return + } + + javaObjectForIBinder = reinterpret_cast<ToJava>(dlsym( + handle, "_ZN7android20javaObjectForIBinderEP7_JNIEnvRKNS_2spINS_7IBinderEEE")); + if (javaObjectForIBinder == nullptr) { + LOG(WARNING) << "Could not find javaObjectForIBinder."; + // no return + } + }); + } + + private: + static std::once_flag mLoadFlag; + + LazyAndroidRuntime(){}; +}; + +LazyAndroidRuntime::FromJava LazyAndroidRuntime::ibinderForJavaObject = nullptr; +LazyAndroidRuntime::ToJava LazyAndroidRuntime::javaObjectForIBinder = nullptr; +std::once_flag LazyAndroidRuntime::mLoadFlag; + AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder) { - sp<IBinder> ibinder = ibinderForJavaObject(env, binder); + if (binder == nullptr) { + return nullptr; + } + + LazyAndroidRuntime::load(); + if (LazyAndroidRuntime::ibinderForJavaObject == nullptr) { + return nullptr; + } + + sp<IBinder> ibinder = (LazyAndroidRuntime::ibinderForJavaObject)(env, binder); sp<AIBinder> cbinder = ABpBinder::lookupOrCreateFromBinder(ibinder); AIBinder_incStrong(cbinder.get()); @@ -38,5 +91,10 @@ jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder) { return nullptr; } - return javaObjectForIBinder(env, binder->getBinder()); + LazyAndroidRuntime::load(); + if (LazyAndroidRuntime::javaObjectForIBinder == nullptr) { + return nullptr; + } + + return (LazyAndroidRuntime::javaObjectForIBinder)(env, binder->getBinder()); } |