• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <unordered_map>
19 #include <map>
20 #include <tuple>
21 
22 #include <jni.h>
23 
24 class JNIBridge {
25     JavaVM* jvm;
26     JNIEnv* env;
27     std::unordered_map<std::string, jclass> classes;
28     // Using tuples as unordered maps keys in not very good in C++.
29     std::map<std::tuple<jclass, std::string, std::string>, jmethodID> methods;
30 
31   public:
JNIBridge(JavaVM * jvm)32     JNIBridge(JavaVM* jvm) : jvm(jvm), env(nullptr) {}
~JNIBridge()33     ~JNIBridge() {
34         if (env) {
35             for (const auto& kv : classes) {
36                 env->DeleteGlobalRef(kv.second);
37             }
38             jvm->DetachCurrentThread();
39         }
40     }
41 
init()42     bool init() {
43         if (jvm->AttachCurrentThreadAsDaemon(&env, nullptr) != 0) {
44             fprintf(stderr, "Cannot attach current thread to JVM\n");
45             return false;
46         }
47         return true;
48     }
49 
makeString(const char * str)50     jstring makeString(const char* str) {
51         return env->NewStringUTF(str);
52     }
53 
getStringUTFChars(jstring str,jboolean * isCopy)54     const char* getStringUTFChars(jstring str, jboolean *isCopy) {
55         return env->GetStringUTFChars(str, isCopy);
56     }
57 
releaseStringUTFChars(jstring str,const char * chars)58     void releaseStringUTFChars(jstring str, const char* chars) {
59         env->ReleaseStringUTFChars(str, chars);
60     }
61 
getObjectClass(jobject obj)62     jclass getObjectClass(jobject obj) {
63         return env->GetObjectClass(obj);
64     }
65 
findClass(const char * clazz)66     jclass findClass(const char* clazz) {
67         auto it = classes.find(clazz);
68         if (it == classes.end()) {
69             auto result = env->FindClass(clazz);
70             classes[clazz] = (jclass)env->NewGlobalRef(result);
71             return result;
72         } else {
73             return it->second;
74         }
75     }
76 
newObject(jclass clazz,jmethodID methodID,...)77     jobject newObject(jclass clazz, jmethodID methodID, ...) {
78         va_list args;
79         jobject result;
80         va_start(args, methodID);
81         result = env->NewObjectV(clazz, methodID, args);
82         va_end(args);
83         return result;
84     }
85 
getMethodID(jclass clazz,const char * method,const char * sig)86     jmethodID getMethodID(jclass clazz, const char* method, const char* sig) {
87         auto key = std::make_tuple(clazz, method, sig);
88         auto it = methods.find(key);
89         if (it == methods.end()) {
90             auto result = env->GetMethodID(clazz, method, sig);
91             methods[key] = result;
92             return result;
93         } else {
94             return it->second;
95         }
96     }
97 
getStaticMethodID(jclass clazz,const char * method,const char * sig)98     jmethodID getStaticMethodID(jclass clazz, const char* method, const char* sig) {
99         return env->GetStaticMethodID(clazz, method, sig);
100     }
101 
callStaticVoidMethod(jclass clazz,jmethodID methodID,...)102     void callStaticVoidMethod(jclass clazz, jmethodID methodID, ...) {
103         va_list args;
104         va_start(args, methodID);
105         env->CallStaticVoidMethodV(clazz, methodID, args);
106         va_end(args);
107     }
108 
callStaticObjectMethod(jclass clazz,jmethodID methodID,...)109     jobject callStaticObjectMethod(jclass clazz, jmethodID methodID, ...) {
110         va_list args;
111         jobject result;
112         va_start(args, methodID);
113         result = env->CallStaticObjectMethodV(clazz, methodID, args);
114         va_end(args);
115         return result;
116     }
117 
callObjectMethod(jobject obj,jmethodID methodID,...)118     jobject callObjectMethod(jobject obj, jmethodID methodID, ...) {
119         va_list args;
120         jobject result;
121         va_start(args, methodID);
122         result = env->CallObjectMethodV(obj, methodID, args);
123         va_end(args);
124         return result;
125     }
126 
callVoidMethod(jobject obj,jmethodID methodID,...)127     void callVoidMethod(jobject obj, jmethodID methodID, ...) {
128         va_list args;
129         va_start(args, methodID);
130         env->CallVoidMethodV(obj, methodID, args);
131         va_end(args);
132     }
133 
callBooleanMethod(jobject obj,jmethodID methodID,...)134     jboolean callBooleanMethod(jobject obj, jmethodID methodID, ...) {
135         va_list args;
136         jboolean result;
137         va_start(args, methodID);
138         result = env->CallBooleanMethodV(obj, methodID, args);
139         va_end(args);
140         return result;
141     }
142 
getStaticFieldID(jclass clazz,const char * name,const char * sig)143     jfieldID getStaticFieldID(jclass clazz, const char *name, const char *sig) {
144         return env->GetStaticFieldID(clazz, name, sig);
145     }
146 
getStaticIntField(jclass clazz,jfieldID fieldID)147     jint getStaticIntField(jclass clazz, jfieldID fieldID) {
148         return env->GetStaticIntField(clazz, fieldID);
149     }
150 
getStaticObjectField(jclass clazz,jfieldID fieldID)151     jobject getStaticObjectField(jclass clazz, jfieldID fieldID) {
152         return env->GetStaticObjectField(clazz, fieldID);
153     }
154 
callIntMethod(jobject obj,jmethodID methodID,...)155     jint callIntMethod(jobject obj, jmethodID methodID, ...) {
156         va_list args;
157         jint result;
158         va_start(args, methodID);
159         result = env->CallIntMethodV(obj, methodID, args);
160         va_end(args);
161         return result;
162     }
163 
callFloatMethod(jobject obj,jmethodID methodID,...)164     jfloat callFloatMethod(jobject obj, jmethodID methodID, ...) {
165         va_list args;
166         jint result;
167         va_start(args, methodID);
168         result = env->CallFloatMethodV(obj, methodID, args);
169         va_end(args);
170         return result;
171     }
172 
check()173     bool check() {
174         if (env->ExceptionCheck()) {
175             env->ExceptionDescribe();
176             env->ExceptionClear();
177             return false;
178         }
179         return true;
180     }
181 
makeArray(jclass clazz,jsize length,jobject initialElement)182     jobjectArray makeArray(jclass clazz, jsize length, jobject initialElement) {
183         return env->NewObjectArray(length, clazz, initialElement);
184     }
185 
setArrayElement(jobjectArray array,jsize index,jobject value)186     void setArrayElement(jobjectArray array, jsize index, jobject value) {
187         env->SetObjectArrayElement(array, index, value);
188     }
189 
getArrayElement(jobjectArray array,jsize index)190     jobject getArrayElement(jobjectArray array, jsize index) {
191         return env->GetObjectArrayElement(array, index);
192     }
193 
getFloatArrayElement(jfloatArray array)194     jfloat* getFloatArrayElement(jfloatArray array) {
195         return env->GetFloatArrayElements(array, 0);
196     }
197 };