diff options
| author | 2019-03-25 22:08:20 -0700 | |
|---|---|---|
| committer | 2019-03-25 22:08:20 -0700 | |
| commit | 42f8ae9276c7ec45c85b00a93d5b629271f81ab5 (patch) | |
| tree | 10a7e31ab94a0b528aad679be854ff3b44efa781 | |
| parent | a4f57f0496d32af349d5c99aacaa5a0e3437a745 (diff) | |
| parent | 8100a8ac5ef254085977ed03fb25b703aa0945f7 (diff) | |
Merge "Add libandroid_runtime_lazy" am: c10e80f5ea am: 89dd7fe221
am: 8100a8ac5e
Change-Id: I5ebe49b73b85d37998c920e14e9df2bcd502f6bf
| -rw-r--r-- | libs/android_runtime_lazy/Android.bp | 65 | ||||
| -rw-r--r-- | libs/android_runtime_lazy/android_runtime_lazy.cpp | 98 | ||||
| -rw-r--r-- | libs/android_runtime_lazy/include/android_runtime/AndroidRuntime.h | 30 | ||||
| -rw-r--r-- | libs/android_runtime_lazy/include/android_util_Binder.h | 31 | ||||
| -rw-r--r-- | libs/binder/ndk/Android.bp | 7 | ||||
| -rw-r--r-- | libs/binder/ndk/ibinder_jni.cpp | 65 | ||||
| -rw-r--r-- | libs/binder/ndk/test/Android.bp | 2 |
7 files changed, 231 insertions, 67 deletions
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp new file mode 100644 index 0000000000..b200314fed --- /dev/null +++ b/libs/android_runtime_lazy/Android.bp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// libandroid_runtime_lazy is a shim library. +// This provides very limited small set of APIs from libandroid_runtime. +// +// By depending on this instead of libandroid_runtime, +// a library can be loaded without paying the cost of libandroid_runtime +// which is quite huge. The cost will be paid when libandroid_runtime is actually used. +// +// For Partial-source PDK build, there is a constraint that +// frameworks/native modules should not depend on frameworks/base. +// This library can be used to cut down the dependency between them. +// (e.g. libbinder_ndk) +// +// Some libraries which serve as LL-NDK and NDK as well may depend on this +// instead of libandroid_runtime. When they are used by a vendor process, +// depending on libandroid_runtime is meaningless. In this case, +// they can depend on libandroid_runtime_lazy. +cc_library { + name: "libandroid_runtime_lazy", + vendor_available: true, + + cflags: [ + "-Wall", + "-Werror", + "-Wunused", + "-Wunreachable-code", + ], + + srcs: [ + "android_runtime_lazy.cpp", + ], + + shared_libs: [ + "liblog", + "libutils", + ], + + required: [ + "libandroid_runtime", + ], + + export_include_dirs: [ + "include", + ], + + header_libs: [ + "jni_headers", + "libbinder_headers", + ], +} diff --git a/libs/android_runtime_lazy/android_runtime_lazy.cpp b/libs/android_runtime_lazy/android_runtime_lazy.cpp new file mode 100644 index 0000000000..98d8e8a511 --- /dev/null +++ b/libs/android_runtime_lazy/android_runtime_lazy.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "ANDROID_RUNTIME_LAZY" +#include "android_runtime/AndroidRuntime.h" +#include "android_util_Binder.h" + +#include <dlfcn.h> +#include <mutex> + +#include <log/log.h> + +namespace android { +namespace { + +std::once_flag loadFlag; + +typedef JNIEnv* (*getJNIEnv_t)(); +typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj); +typedef jobject (*javaObjectForIBinder_t)(JNIEnv* env, const sp<IBinder>& val); + +getJNIEnv_t _getJNIEnv; +ibinderForJavaObject_t _ibinderForJavaObject; +javaObjectForIBinder_t _javaObjectForIBinder; + +void load() { + std::call_once(loadFlag, []() { + 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) { + ALOGW("Could not find getJNIEnv."); + // no return + } + + _ibinderForJavaObject = reinterpret_cast<ibinderForJavaObject_t>( + dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject")); + if (_ibinderForJavaObject == nullptr) { + ALOGW("Could not find ibinderForJavaObject."); + // no return + } + + _javaObjectForIBinder = reinterpret_cast<javaObjectForIBinder_t>( + dlsym(handle, + "_ZN7android20javaObjectForIBinderEP7_JNIEnvRKNS_2spINS_7IBinderEEE")); + if (_javaObjectForIBinder == nullptr) { + ALOGW("Could not find javaObjectForIBinder."); + // no return + } + }); +} + +} // namespace + +// exports delegate functions + +JNIEnv* AndroidRuntime::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); +} + +jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { + load(); + if (_javaObjectForIBinder == nullptr) { + return nullptr; + } + return _javaObjectForIBinder(env, val); +} + +} // namespace android diff --git a/libs/android_runtime_lazy/include/android_runtime/AndroidRuntime.h b/libs/android_runtime_lazy/include/android_runtime/AndroidRuntime.h new file mode 100644 index 0000000000..85231fa1ad --- /dev/null +++ b/libs/android_runtime_lazy/include/android_runtime/AndroidRuntime.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "jni.h" + +namespace android { + +// Intentionally use the same name with AndroidRuntime in frameworks/base/core/jni/ +// to make the client use this in the same way with the original class. +class AndroidRuntime { +public: + static JNIEnv* getJNIEnv(); +}; + +} // namespace android diff --git a/libs/android_runtime_lazy/include/android_util_Binder.h b/libs/android_runtime_lazy/include/android_util_Binder.h new file mode 100644 index 0000000000..e47390e9e5 --- /dev/null +++ b/libs/android_runtime_lazy/include/android_util_Binder.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <binder/IBinder.h> +#include "jni.h" + +namespace android { + +// The name of this file is same with the file in frameworks/base/core/jni/ +// This is intentional to make the client use these exported functions +// in the same way with the original. + +jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val); +sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj); + +} // namespace android diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index a96c9a0eff..21bef2e930 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -39,17 +39,12 @@ cc_library { ], shared_libs: [ + "libandroid_runtime_lazy", "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", - ], - header_libs: [ "jni_headers", ], diff --git a/libs/binder/ndk/ibinder_jni.cpp b/libs/binder/ndk/ibinder_jni.cpp index 4a31080824..d931785cd4 100644 --- a/libs/binder/ndk/ibinder_jni.cpp +++ b/libs/binder/ndk/ibinder_jni.cpp @@ -17,69 +17,19 @@ #include <android/binder_ibinder_jni.h> #include "ibinder_internal.h" -#include <android-base/logging.h> -#include <binder/IBinder.h> - -#include <mutex> - -#include <dlfcn.h> +#include <android_util_Binder.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) { if (binder == nullptr) { return nullptr; } - LazyAndroidRuntime::load(); - if (LazyAndroidRuntime::ibinderForJavaObject == nullptr) { - return nullptr; - } - - sp<IBinder> ibinder = (LazyAndroidRuntime::ibinderForJavaObject)(env, binder); - + sp<IBinder> ibinder = ibinderForJavaObject(env, binder); sp<AIBinder> cbinder = ABpBinder::lookupOrCreateFromBinder(ibinder); AIBinder_incStrong(cbinder.get()); @@ -91,10 +41,5 @@ jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder) { return nullptr; } - LazyAndroidRuntime::load(); - if (LazyAndroidRuntime::javaObjectForIBinder == nullptr) { - return nullptr; - } - - return (LazyAndroidRuntime::javaObjectForIBinder)(env, binder->getBinder()); + return javaObjectForIBinder(env, binder->getBinder()); } diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp index b29b6e7a3e..8cd4e033df 100644 --- a/libs/binder/ndk/test/Android.bp +++ b/libs/binder/ndk/test/Android.bp @@ -41,7 +41,7 @@ cc_defaults { name: "test_libbinder_ndk_test_defaults", defaults: ["test_libbinder_ndk_defaults"], shared_libs: [ - "libandroid_runtime", + "libandroid_runtime_lazy", "libbase", "libbinder", "libutils", |