xref: /aosp_15_r20/external/libtextclassifier/native/utils/java/jni-helper.h (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker  *
4*993b0882SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker  *
8*993b0882SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker  *
10*993b0882SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker  * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker  */
16*993b0882SAndroid Build Coastguard Worker 
17*993b0882SAndroid Build Coastguard Worker // Utility class that provides similar calls like JNIEnv, but performs
18*993b0882SAndroid Build Coastguard Worker // additional checks on them, so that it's harder to use them incorrectly.
19*993b0882SAndroid Build Coastguard Worker 
20*993b0882SAndroid Build Coastguard Worker #ifndef LIBTEXTCLASSIFIER_UTILS_JAVA_JNI_HELPER_H_
21*993b0882SAndroid Build Coastguard Worker #define LIBTEXTCLASSIFIER_UTILS_JAVA_JNI_HELPER_H_
22*993b0882SAndroid Build Coastguard Worker 
23*993b0882SAndroid Build Coastguard Worker #include <jni.h>
24*993b0882SAndroid Build Coastguard Worker 
25*993b0882SAndroid Build Coastguard Worker #include <string>
26*993b0882SAndroid Build Coastguard Worker 
27*993b0882SAndroid Build Coastguard Worker #include "utils/base/status.h"
28*993b0882SAndroid Build Coastguard Worker #include "utils/base/statusor.h"
29*993b0882SAndroid Build Coastguard Worker #include "utils/java/jni-base.h"
30*993b0882SAndroid Build Coastguard Worker 
31*993b0882SAndroid Build Coastguard Worker #define TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN             \
32*993b0882SAndroid Build Coastguard Worker   if (!EnsureLocalCapacity(env, 1)) {                   \
33*993b0882SAndroid Build Coastguard Worker     TC3_LOG(ERROR) << "EnsureLocalCapacity(1) failed."; \
34*993b0882SAndroid Build Coastguard Worker     return {Status::UNKNOWN};                           \
35*993b0882SAndroid Build Coastguard Worker   }
36*993b0882SAndroid Build Coastguard Worker 
37*993b0882SAndroid Build Coastguard Worker #define TC3_NO_EXCEPTION_OR_RETURN      \
38*993b0882SAndroid Build Coastguard Worker   if (JniExceptionCheckAndClear(env)) { \
39*993b0882SAndroid Build Coastguard Worker     return {Status::UNKNOWN};           \
40*993b0882SAndroid Build Coastguard Worker   }
41*993b0882SAndroid Build Coastguard Worker 
42*993b0882SAndroid Build Coastguard Worker #define TC3_NOT_NULL_OR_RETURN \
43*993b0882SAndroid Build Coastguard Worker   if (result == nullptr) {     \
44*993b0882SAndroid Build Coastguard Worker     return {Status::UNKNOWN};  \
45*993b0882SAndroid Build Coastguard Worker   }
46*993b0882SAndroid Build Coastguard Worker 
47*993b0882SAndroid Build Coastguard Worker #define TC3_DEFINE_VARIADIC_SCOPED_LOCAL_REF_ENV_METHOD(                   \
48*993b0882SAndroid Build Coastguard Worker     METHOD_NAME, RETURN_TYPE, INPUT_TYPE, POST_CHECK)                      \
49*993b0882SAndroid Build Coastguard Worker   template <typename T = RETURN_TYPE>                                      \
50*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<T>> METHOD_NAME(                          \
51*993b0882SAndroid Build Coastguard Worker       JNIEnv* env, INPUT_TYPE object, jmethodID method_id, ...) {          \
52*993b0882SAndroid Build Coastguard Worker     TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;                                   \
53*993b0882SAndroid Build Coastguard Worker                                                                            \
54*993b0882SAndroid Build Coastguard Worker     va_list args;                                                          \
55*993b0882SAndroid Build Coastguard Worker     va_start(args, method_id);                                             \
56*993b0882SAndroid Build Coastguard Worker     ScopedLocalRef<T> result(                                              \
57*993b0882SAndroid Build Coastguard Worker         reinterpret_cast<T>(env->METHOD_NAME##V(object, method_id, args)), \
58*993b0882SAndroid Build Coastguard Worker         env);                                                              \
59*993b0882SAndroid Build Coastguard Worker     POST_CHECK                                                             \
60*993b0882SAndroid Build Coastguard Worker     va_end(args);                                                          \
61*993b0882SAndroid Build Coastguard Worker                                                                            \
62*993b0882SAndroid Build Coastguard Worker     TC3_NO_EXCEPTION_OR_RETURN;                                            \
63*993b0882SAndroid Build Coastguard Worker     return result;                                                         \
64*993b0882SAndroid Build Coastguard Worker   }
65*993b0882SAndroid Build Coastguard Worker 
66*993b0882SAndroid Build Coastguard Worker #define TC3_JNI_NO_CHECK \
67*993b0882SAndroid Build Coastguard Worker   {}
68*993b0882SAndroid Build Coastguard Worker 
69*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 {
70*993b0882SAndroid Build Coastguard Worker 
71*993b0882SAndroid Build Coastguard Worker class JniHelper {
72*993b0882SAndroid Build Coastguard Worker  public:
73*993b0882SAndroid Build Coastguard Worker   // Misc methods.
74*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jclass>> FindClass(JNIEnv* env,
75*993b0882SAndroid Build Coastguard Worker                                                     const char* class_name);
76*993b0882SAndroid Build Coastguard Worker 
77*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jclass>> GetObjectClass(JNIEnv* env,
78*993b0882SAndroid Build Coastguard Worker                                                          jobject object);
79*993b0882SAndroid Build Coastguard Worker 
80*993b0882SAndroid Build Coastguard Worker   template <typename T = jobject>
81*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<T>> GetObjectArrayElement(JNIEnv* env,
82*993b0882SAndroid Build Coastguard Worker                                                            jobjectArray array,
83*993b0882SAndroid Build Coastguard Worker                                                            jsize index);
84*993b0882SAndroid Build Coastguard Worker   static StatusOr<jmethodID> GetMethodID(JNIEnv* env, jclass clazz,
85*993b0882SAndroid Build Coastguard Worker                                          const char* method_name,
86*993b0882SAndroid Build Coastguard Worker                                          const char* signature);
87*993b0882SAndroid Build Coastguard Worker   static StatusOr<jmethodID> GetStaticMethodID(JNIEnv* env, jclass clazz,
88*993b0882SAndroid Build Coastguard Worker                                                const char* method_name,
89*993b0882SAndroid Build Coastguard Worker                                                const char* signature);
90*993b0882SAndroid Build Coastguard Worker 
91*993b0882SAndroid Build Coastguard Worker   static StatusOr<jfieldID> GetFieldID(JNIEnv* env, jclass clazz,
92*993b0882SAndroid Build Coastguard Worker                                        const char* field_name,
93*993b0882SAndroid Build Coastguard Worker                                        const char* signature);
94*993b0882SAndroid Build Coastguard Worker   static StatusOr<jfieldID> GetStaticFieldID(JNIEnv* env, jclass clazz,
95*993b0882SAndroid Build Coastguard Worker                                              const char* field_name,
96*993b0882SAndroid Build Coastguard Worker                                              const char* signature);
97*993b0882SAndroid Build Coastguard Worker 
98*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jobject>> GetStaticObjectField(
99*993b0882SAndroid Build Coastguard Worker       JNIEnv* env, jclass class_name, jfieldID field_id);
100*993b0882SAndroid Build Coastguard Worker   static StatusOr<jint> GetStaticIntField(JNIEnv* env, jclass class_name,
101*993b0882SAndroid Build Coastguard Worker                                           jfieldID field_id);
102*993b0882SAndroid Build Coastguard Worker 
103*993b0882SAndroid Build Coastguard Worker   // New* methods.
104*993b0882SAndroid Build Coastguard Worker   TC3_DEFINE_VARIADIC_SCOPED_LOCAL_REF_ENV_METHOD(NewObject, jobject, jclass,
105*993b0882SAndroid Build Coastguard Worker                                                   TC3_NOT_NULL_OR_RETURN);
106*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jobjectArray>> NewObjectArray(
107*993b0882SAndroid Build Coastguard Worker       JNIEnv* env, jsize length, jclass element_class,
108*993b0882SAndroid Build Coastguard Worker       jobject initial_element = nullptr);
109*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jbyteArray>> NewByteArray(JNIEnv* env,
110*993b0882SAndroid Build Coastguard Worker                                                            jsize length);
111*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jintArray>> NewIntArray(JNIEnv* env,
112*993b0882SAndroid Build Coastguard Worker                                                          jsize length);
113*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jstring>> NewStringUTF(JNIEnv* env,
114*993b0882SAndroid Build Coastguard Worker                                                         const char* bytes);
115*993b0882SAndroid Build Coastguard Worker   static StatusOr<ScopedLocalRef<jfloatArray>> NewFloatArray(JNIEnv* env,
116*993b0882SAndroid Build Coastguard Worker                                                              jsize length);
117*993b0882SAndroid Build Coastguard Worker 
118*993b0882SAndroid Build Coastguard Worker   static StatusOr<jsize> GetArrayLength(JNIEnv* env, jarray array);
119*993b0882SAndroid Build Coastguard Worker 
120*993b0882SAndroid Build Coastguard Worker   static Status SetObjectArrayElement(JNIEnv* env, jobjectArray array,
121*993b0882SAndroid Build Coastguard Worker                                       jsize index, jobject val);
122*993b0882SAndroid Build Coastguard Worker 
123*993b0882SAndroid Build Coastguard Worker   static Status GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start,
124*993b0882SAndroid Build Coastguard Worker                                    jsize len, jbyte* buf);
125*993b0882SAndroid Build Coastguard Worker 
126*993b0882SAndroid Build Coastguard Worker   static Status SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start,
127*993b0882SAndroid Build Coastguard Worker                                    jsize len, const jbyte* buf);
128*993b0882SAndroid Build Coastguard Worker 
129*993b0882SAndroid Build Coastguard Worker   static Status SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start,
130*993b0882SAndroid Build Coastguard Worker                                   jsize len, const jint* buf);
131*993b0882SAndroid Build Coastguard Worker 
132*993b0882SAndroid Build Coastguard Worker   static Status SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start,
133*993b0882SAndroid Build Coastguard Worker                                     jsize len, const jfloat* buf);
134*993b0882SAndroid Build Coastguard Worker 
135*993b0882SAndroid Build Coastguard Worker   // Call* methods.
136*993b0882SAndroid Build Coastguard Worker   TC3_DEFINE_VARIADIC_SCOPED_LOCAL_REF_ENV_METHOD(CallObjectMethod, jobject,
137*993b0882SAndroid Build Coastguard Worker                                                   jobject, TC3_JNI_NO_CHECK);
138*993b0882SAndroid Build Coastguard Worker   TC3_DEFINE_VARIADIC_SCOPED_LOCAL_REF_ENV_METHOD(CallStaticObjectMethod,
139*993b0882SAndroid Build Coastguard Worker                                                   jobject, jclass,
140*993b0882SAndroid Build Coastguard Worker                                                   TC3_JNI_NO_CHECK);
141*993b0882SAndroid Build Coastguard Worker   static Status CallVoidMethod(JNIEnv* env, jobject object, jmethodID method_id,
142*993b0882SAndroid Build Coastguard Worker                                ...);
143*993b0882SAndroid Build Coastguard Worker   static StatusOr<bool> CallBooleanMethod(JNIEnv* env, jobject object,
144*993b0882SAndroid Build Coastguard Worker                                           jmethodID method_id, ...);
145*993b0882SAndroid Build Coastguard Worker   static StatusOr<int32> CallIntMethod(JNIEnv* env, jobject object,
146*993b0882SAndroid Build Coastguard Worker                                        jmethodID method_id, ...);
147*993b0882SAndroid Build Coastguard Worker   static StatusOr<int64> CallLongMethod(JNIEnv* env, jobject object,
148*993b0882SAndroid Build Coastguard Worker                                         jmethodID method_id, ...);
149*993b0882SAndroid Build Coastguard Worker   static StatusOr<float> CallFloatMethod(JNIEnv* env, jobject object,
150*993b0882SAndroid Build Coastguard Worker                                          jmethodID method_id, ...);
151*993b0882SAndroid Build Coastguard Worker   static StatusOr<double> CallDoubleMethod(JNIEnv* env, jobject object,
152*993b0882SAndroid Build Coastguard Worker                                            jmethodID method_id, ...);
153*993b0882SAndroid Build Coastguard Worker 
154*993b0882SAndroid Build Coastguard Worker   template <class T>
155*993b0882SAndroid Build Coastguard Worker   static StatusOr<T> CallStaticIntMethod(JNIEnv* env,
156*993b0882SAndroid Build Coastguard Worker                                          bool print_exception_on_error,
157*993b0882SAndroid Build Coastguard Worker                                          jclass clazz, jmethodID method_id,
158*993b0882SAndroid Build Coastguard Worker                                          ...);
159*993b0882SAndroid Build Coastguard Worker };
160*993b0882SAndroid Build Coastguard Worker 
161*993b0882SAndroid Build Coastguard Worker template <typename T>
GetObjectArrayElement(JNIEnv * env,jobjectArray array,jsize index)162*993b0882SAndroid Build Coastguard Worker StatusOr<ScopedLocalRef<T>> JniHelper::GetObjectArrayElement(JNIEnv* env,
163*993b0882SAndroid Build Coastguard Worker                                                              jobjectArray array,
164*993b0882SAndroid Build Coastguard Worker                                                              jsize index) {
165*993b0882SAndroid Build Coastguard Worker   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
166*993b0882SAndroid Build Coastguard Worker   ScopedLocalRef<T> result(
167*993b0882SAndroid Build Coastguard Worker       reinterpret_cast<T>(env->GetObjectArrayElement(array, index)), env);
168*993b0882SAndroid Build Coastguard Worker 
169*993b0882SAndroid Build Coastguard Worker   TC3_NO_EXCEPTION_OR_RETURN;
170*993b0882SAndroid Build Coastguard Worker   return result;
171*993b0882SAndroid Build Coastguard Worker }
172*993b0882SAndroid Build Coastguard Worker 
173*993b0882SAndroid Build Coastguard Worker template <class T>
CallStaticIntMethod(JNIEnv * env,bool print_exception_on_error,jclass clazz,jmethodID method_id,...)174*993b0882SAndroid Build Coastguard Worker StatusOr<T> JniHelper::CallStaticIntMethod(JNIEnv* env,
175*993b0882SAndroid Build Coastguard Worker                                            bool print_exception_on_error,
176*993b0882SAndroid Build Coastguard Worker                                            jclass clazz, jmethodID method_id,
177*993b0882SAndroid Build Coastguard Worker                                            ...) {
178*993b0882SAndroid Build Coastguard Worker   va_list args;
179*993b0882SAndroid Build Coastguard Worker   va_start(args, method_id);
180*993b0882SAndroid Build Coastguard Worker   jint result = env->CallStaticIntMethodV(clazz, method_id, args);
181*993b0882SAndroid Build Coastguard Worker   va_end(args);
182*993b0882SAndroid Build Coastguard Worker 
183*993b0882SAndroid Build Coastguard Worker   if (JniExceptionCheckAndClear(env, print_exception_on_error)) {
184*993b0882SAndroid Build Coastguard Worker     return {Status::UNKNOWN};
185*993b0882SAndroid Build Coastguard Worker   }
186*993b0882SAndroid Build Coastguard Worker 
187*993b0882SAndroid Build Coastguard Worker   return result;
188*993b0882SAndroid Build Coastguard Worker }
189*993b0882SAndroid Build Coastguard Worker 
190*993b0882SAndroid Build Coastguard Worker // Converts Java byte[] object to std::string.
191*993b0882SAndroid Build Coastguard Worker StatusOr<std::string> JByteArrayToString(JNIEnv* env, jbyteArray array);
192*993b0882SAndroid Build Coastguard Worker 
193*993b0882SAndroid Build Coastguard Worker // Converts Java String object to UTF8-encoded std::string.
194*993b0882SAndroid Build Coastguard Worker StatusOr<std::string> JStringToUtf8String(JNIEnv* env, jstring jstr);
195*993b0882SAndroid Build Coastguard Worker 
196*993b0882SAndroid Build Coastguard Worker }  // namespace libtextclassifier3
197*993b0882SAndroid Build Coastguard Worker 
198*993b0882SAndroid Build Coastguard Worker #endif  // LIBTEXTCLASSIFIER_UTILS_JAVA_JNI_HELPER_H_
199