blob: 4a3108082415d5f5fad771bace9f0ed579aa9a27 [file] [log] [blame]
Steven Moreland02f75652018-09-18 14:08:30 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android/binder_ibinder_jni.h>
18#include "ibinder_internal.h"
19
Steven Moreland81311c02019-01-22 16:02:02 -080020#include <android-base/logging.h>
21#include <binder/IBinder.h>
22
23#include <mutex>
24
25#include <dlfcn.h>
Steven Moreland02f75652018-09-18 14:08:30 -070026
27using ::android::IBinder;
Steven Moreland02f75652018-09-18 14:08:30 -070028using ::android::sp;
29
Steven Moreland81311c02019-01-22 16:02:02 -080030struct LazyAndroidRuntime {
31 typedef sp<IBinder> (*FromJava)(JNIEnv* env, jobject obj);
32 typedef jobject (*ToJava)(JNIEnv* env, const sp<IBinder>& val);
33
34 static FromJava ibinderForJavaObject;
35 static ToJava javaObjectForIBinder;
36
37 static void load() {
38 std::call_once(mLoadFlag, []() {
39 void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY);
40 if (handle == nullptr) {
41 LOG(WARNING) << "Could not open libandroid_runtime.";
42 return;
43 }
44
45 ibinderForJavaObject = reinterpret_cast<FromJava>(
46 dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject"));
47 if (ibinderForJavaObject == nullptr) {
48 LOG(WARNING) << "Could not find ibinderForJavaObject.";
49 // no return
50 }
51
52 javaObjectForIBinder = reinterpret_cast<ToJava>(dlsym(
53 handle, "_ZN7android20javaObjectForIBinderEP7_JNIEnvRKNS_2spINS_7IBinderEEE"));
54 if (javaObjectForIBinder == nullptr) {
55 LOG(WARNING) << "Could not find javaObjectForIBinder.";
56 // no return
57 }
58 });
59 }
60
61 private:
62 static std::once_flag mLoadFlag;
63
64 LazyAndroidRuntime(){};
65};
66
67LazyAndroidRuntime::FromJava LazyAndroidRuntime::ibinderForJavaObject = nullptr;
68LazyAndroidRuntime::ToJava LazyAndroidRuntime::javaObjectForIBinder = nullptr;
69std::once_flag LazyAndroidRuntime::mLoadFlag;
70
Steven Moreland02f75652018-09-18 14:08:30 -070071AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder) {
Steven Moreland81311c02019-01-22 16:02:02 -080072 if (binder == nullptr) {
73 return nullptr;
74 }
75
76 LazyAndroidRuntime::load();
77 if (LazyAndroidRuntime::ibinderForJavaObject == nullptr) {
78 return nullptr;
79 }
80
81 sp<IBinder> ibinder = (LazyAndroidRuntime::ibinderForJavaObject)(env, binder);
Steven Moreland02f75652018-09-18 14:08:30 -070082
83 sp<AIBinder> cbinder = ABpBinder::lookupOrCreateFromBinder(ibinder);
84 AIBinder_incStrong(cbinder.get());
85
86 return cbinder.get();
87}
88
89jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder) {
90 if (binder == nullptr) {
91 return nullptr;
92 }
93
Steven Moreland81311c02019-01-22 16:02:02 -080094 LazyAndroidRuntime::load();
95 if (LazyAndroidRuntime::javaObjectForIBinder == nullptr) {
96 return nullptr;
97 }
98
99 return (LazyAndroidRuntime::javaObjectForIBinder)(env, binder->getBinder());
Steven Moreland02f75652018-09-18 14:08:30 -0700100}