blob: 8062be676d616b1db3ed306e4620ef4180d10de1 [file] [log] [blame]
Jooyung Han1f65e772019-03-07 16:55:04 +09001/*
2 * Copyright (C) 2019 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#define LOG_TAG "ANDROID_RUNTIME_LAZY"
17#include "android_runtime/AndroidRuntime.h"
Steven Moreland7c615582020-01-06 16:34:39 -080018#include "android_os_Parcel.h"
Jooyung Han1f65e772019-03-07 16:55:04 +090019#include "android_util_Binder.h"
20
21#include <dlfcn.h>
22#include <mutex>
23
24#include <log/log.h>
25
26namespace android {
27namespace {
28
29std::once_flag loadFlag;
30
31typedef JNIEnv* (*getJNIEnv_t)();
Steven Moreland7c615582020-01-06 16:34:39 -080032
33// android_util_Binder.h
Jooyung Han1f65e772019-03-07 16:55:04 +090034typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj);
35typedef jobject (*javaObjectForIBinder_t)(JNIEnv* env, const sp<IBinder>& val);
36
Steven Moreland7c615582020-01-06 16:34:39 -080037// android_os_Parcel.h
38typedef Parcel* (*parcelForJavaObject_t)(JNIEnv* env, jobject obj);
39
Jooyung Han1f65e772019-03-07 16:55:04 +090040getJNIEnv_t _getJNIEnv;
41ibinderForJavaObject_t _ibinderForJavaObject;
42javaObjectForIBinder_t _javaObjectForIBinder;
Steven Moreland7c615582020-01-06 16:34:39 -080043parcelForJavaObject_t _parcelForJavaObject;
Jooyung Han1f65e772019-03-07 16:55:04 +090044
45void load() {
46 std::call_once(loadFlag, []() {
47 void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY);
48 if (handle == nullptr) {
49 ALOGE("Could not open libandroid_runtime.");
50 return;
51 }
52
53 _getJNIEnv = reinterpret_cast<getJNIEnv_t>(
54 dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv"));
55 if (_getJNIEnv == nullptr) {
56 ALOGW("Could not find getJNIEnv.");
57 // no return
58 }
59
60 _ibinderForJavaObject = reinterpret_cast<ibinderForJavaObject_t>(
61 dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject"));
62 if (_ibinderForJavaObject == nullptr) {
63 ALOGW("Could not find ibinderForJavaObject.");
64 // no return
65 }
66
67 _javaObjectForIBinder = reinterpret_cast<javaObjectForIBinder_t>(
68 dlsym(handle,
69 "_ZN7android20javaObjectForIBinderEP7_JNIEnvRKNS_2spINS_7IBinderEEE"));
70 if (_javaObjectForIBinder == nullptr) {
71 ALOGW("Could not find javaObjectForIBinder.");
72 // no return
73 }
Steven Moreland7c615582020-01-06 16:34:39 -080074
75 _parcelForJavaObject = reinterpret_cast<parcelForJavaObject_t>(
76 dlsym(handle, "_ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject"));
77 if (_parcelForJavaObject == nullptr) {
78 ALOGW("Could not find parcelForJavaObject.");
79 // no return
80 }
Jooyung Han1f65e772019-03-07 16:55:04 +090081 });
82}
83
84} // namespace
85
86// exports delegate functions
87
88JNIEnv* AndroidRuntime::getJNIEnv() {
89 load();
90 if (_getJNIEnv == nullptr) {
91 return nullptr;
92 }
93 return _getJNIEnv();
94}
95
96sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) {
97 load();
98 if (_ibinderForJavaObject == nullptr) {
99 return nullptr;
100 }
101 return _ibinderForJavaObject(env, obj);
102}
103
104jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) {
105 load();
106 if (_javaObjectForIBinder == nullptr) {
107 return nullptr;
108 }
109 return _javaObjectForIBinder(env, val);
110}
111
Steven Moreland7c615582020-01-06 16:34:39 -0800112Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) {
113 load();
114 if (_parcelForJavaObject == nullptr) {
115 return nullptr;
116 }
117 return _parcelForJavaObject(env, obj);
118}
119
Jooyung Han1f65e772019-03-07 16:55:04 +0900120} // namespace android