1 /*
2 * Copyright (C) 2007 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 /*
18 * JNI helper functions.
19 *
20 * This file may be included by C or C++ code, which is trouble because jni.h
21 * uses different typedefs for JNIEnv in each language.
22 */
23 #pragma once
24
25 #include <sys/cdefs.h>
26
27 #include <errno.h>
28 #include <unistd.h>
29
30 #include <jni.h>
31
32 #ifndef NELEM
33 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
34 #endif
35
36 __BEGIN_DECLS
37
38
39 /*
40 * Register one or more native methods with a particular class. "className" looks like
41 * "java/lang/String". Aborts on failure, returns 0 on success.
42 */
43 int jniRegisterNativeMethods(C_JNIEnv* env,
44 const char* className,
45 const JNINativeMethod* gMethods,
46 int numMethods);
47
48 /*
49 * Throw an exception with the specified class and an optional message.
50 *
51 * The "className" argument will be passed directly to FindClass, which
52 * takes strings with slashes (e.g. "java/lang/Object").
53 *
54 * If an exception is currently pending, we log a warning message and
55 * clear it.
56 *
57 * Returns 0 on success, nonzero if something failed (e.g. the exception
58 * class couldn't be found, so *an* exception will still be pending).
59 *
60 * Currently aborts the VM if it can't throw the exception.
61 */
62 int jniThrowException(C_JNIEnv* env, const char* className, const char* msg);
63
64 /*
65 * Throw an exception with the specified class and formatted error message.
66 *
67 * The "className" argument will be passed directly to FindClass, which
68 * takes strings with slashes (e.g. "java/lang/Object").
69 *
70 * If an exception is currently pending, we log a warning message and
71 * clear it.
72 *
73 * Returns 0 on success, nonzero if something failed (e.g. the exception
74 * class couldn't be found, so *an* exception will still be pending).
75 *
76 * Currently aborts the VM if it can't throw the exception.
77 */
78 int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args);
79
80 /*
81 * Throw a java.lang.NullPointerException, with an optional message.
82 */
83 int jniThrowNullPointerException(C_JNIEnv* env, const char* msg);
84
85 /*
86 * Throw a java.lang.RuntimeException, with an optional message.
87 */
88 int jniThrowRuntimeException(C_JNIEnv* env, const char* msg);
89
90 /*
91 * Throw a java.io.IOException, generating the message from errno.
92 */
93 int jniThrowIOException(C_JNIEnv* env, int errnum);
94
95 /*
96 * Returns the reference from a java.lang.ref.Reference.
97 */
98 jobject jniGetReferent(C_JNIEnv* env, jobject ref);
99
100 /*
101 * Returns a Java String object created from UTF-16 data either from jchar or,
102 * if called from C++11, char16_t (a bitwise identical distinct type).
103 */
104 jstring jniCreateString(C_JNIEnv* env, const jchar* unicodeChars, jsize len);
105
106 /*
107 * Allocates a new array for java/lang/String instances with space for |count| elements. Elements
108 * are initially null.
109 *
110 * Returns a new array on success or nullptr in case of failure. This method raises an
111 * OutOfMemoryError exception if allocation fails.
112 */
113 jobjectArray jniCreateStringArray(C_JNIEnv* env, size_t count);
114
115 /*
116 * Log a message and an exception.
117 * If exception is NULL, logs the current exception in the JNI environment.
118 */
119 void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception);
120
121 __END_DECLS
122
123 /*
124 * For C++ code, we provide inlines that map to the C functions. g++ always
125 * inlines these, even on non-optimized builds.
126 */
127 #if defined(__cplusplus)
128
jniRegisterNativeMethods(JNIEnv * env,const char * className,const JNINativeMethod * gMethods,int numMethods)129 inline int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods) {
130 return jniRegisterNativeMethods(&env->functions, className, gMethods, numMethods);
131 }
132
jniThrowException(JNIEnv * env,const char * className,const char * msg)133 inline int jniThrowException(JNIEnv* env, const char* className, const char* msg) {
134 return jniThrowException(&env->functions, className, msg);
135 }
136
137 /*
138 * Equivalent to jniThrowException but with a printf-like format string and
139 * variable-length argument list. This is only available in C++.
140 */
jniThrowExceptionFmt(JNIEnv * env,const char * className,const char * fmt,...)141 inline int jniThrowExceptionFmt(JNIEnv* env, const char* className, const char* fmt, ...) {
142 va_list args;
143 va_start(args, fmt);
144 return jniThrowExceptionFmt(&env->functions, className, fmt, args);
145 va_end(args);
146 }
147
jniThrowNullPointerException(JNIEnv * env,const char * msg)148 inline int jniThrowNullPointerException(JNIEnv* env, const char* msg) {
149 return jniThrowNullPointerException(&env->functions, msg);
150 }
151
jniThrowRuntimeException(JNIEnv * env,const char * msg)152 inline int jniThrowRuntimeException(JNIEnv* env, const char* msg) {
153 return jniThrowRuntimeException(&env->functions, msg);
154 }
155
jniThrowIOException(JNIEnv * env,int errnum)156 inline int jniThrowIOException(JNIEnv* env, int errnum) {
157 return jniThrowIOException(&env->functions, errnum);
158 }
159
jniGetReferent(JNIEnv * env,jobject ref)160 inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
161 return jniGetReferent(&env->functions, ref);
162 }
163
jniCreateString(JNIEnv * env,const jchar * unicodeChars,jsize len)164 inline jstring jniCreateString(JNIEnv* env, const jchar* unicodeChars, jsize len) {
165 return jniCreateString(&env->functions, unicodeChars, len);
166 }
167
jniCreateString(JNIEnv * env,const char16_t * unicodeChars,jsize len)168 inline jstring jniCreateString(JNIEnv* env, const char16_t* unicodeChars, jsize len) {
169 return jniCreateString(&env->functions, reinterpret_cast<const jchar*>(unicodeChars), len);
170 }
171
172 inline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowable exception = NULL) {
173 jniLogException(&env->functions, priority, tag, exception);
174 }
175
176 #endif // defined(__cplusplus)
177
178