diff options
author | 2019-01-25 19:47:41 -0800 | |
---|---|---|
committer | 2019-01-25 19:47:41 -0800 | |
commit | 4ce0dfedaf55a596bde65eb50aa2b7df39e393cb (patch) | |
tree | fe251bfa598c2166bb4fb2a02aef018ce6a39cbb | |
parent | d265ad685a5338dcc7b4dc22f846478598230bd9 (diff) | |
parent | 91ce1b6dde9b8b72959ac6b4c324e34c47bd38d6 (diff) |
Merge "Load libandroid_runtime lazily." am: 5a8d6ccb0f
am: 91ce1b6dde
Change-Id: Id92fc35c0eea82ef56eb68529f32227d16eaa9b1
-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()); } |