1 /*
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 #pragma clang diagnostic push
18 #pragma clang diagnostic ignored "-Wused-but-marked-unused"
19 #pragma clang diagnostic ignored "-Wdeprecated"
20 #include <gtest/gtest.h>
21 #pragma clang diagnostic pop
22 #include <sstream>
23
24 #define PARSE_FAILURES_NONFATAL // return empty optionals wherever possible instead of asserting.
25 #include "nativehelper/jni_macros.h"
26
27 // Provide static storage to these values so they can be used in a runtime context.
28 // This has to be defined local to the test translation unit to avoid ODR violations prior to C++17.
29 #define STORAGE_FN_FOR_JNI_TRAITS(jtype, ...) \
30 constexpr char nativehelper::detail::jni_type_trait<jtype>::type_descriptor[]; \
31 constexpr char nativehelper::detail::jni_type_trait<jtype>::type_name[];
32
DEFINE_JNI_TYPE_TRAIT(STORAGE_FN_FOR_JNI_TRAITS)33 DEFINE_JNI_TYPE_TRAIT(STORAGE_FN_FOR_JNI_TRAITS)
34
35 template <typename T>
36 std::string stringify_helper(const T& val) {
37 std::stringstream ss;
38 ss << val;
39 return ss.str();
40 }
41
42 #define EXPECT_STRINGIFY_EQ(x, y) EXPECT_EQ(stringify_helper(x), stringify_helper(y))
43
TEST(JniSafeRegisterNativeMethods,StringParsing)44 TEST(JniSafeRegisterNativeMethods, StringParsing) {
45 using namespace nativehelper::detail; // NOLINT
46
47 // Super basic bring-up tests for core functionality.
48
49 {
50 constexpr ConstexprStringView v_str = "V";
51 EXPECT_EQ(1u, v_str.size());
52 EXPECT_EQ(false, v_str.empty());
53
54 std::stringstream ss;
55 ss << v_str;
56 EXPECT_EQ("V", ss.str());
57 }
58
59 {
60 auto parse = ParseSingleTypeDescriptor("", /*allow_void*/true);
61 EXPECT_EQ("", parse->token);
62 EXPECT_EQ("", parse->remainder);
63 }
64
65 {
66 auto parse = ParseSingleTypeDescriptor("V", /*allow_void*/true);
67 EXPECT_EQ("V", parse->token);
68 EXPECT_EQ("", parse->remainder);
69 }
70
71 {
72 auto parse = ParseSingleTypeDescriptor("[I");
73 EXPECT_EQ("[I", parse->token);
74 EXPECT_EQ("", parse->remainder);
75 }
76
77 {
78 auto parse = ParseSingleTypeDescriptor("LObject;");
79 EXPECT_EQ("LObject;", parse->token);
80 EXPECT_EQ("", parse->remainder);
81 }
82
83 {
84 auto parse = ParseSingleTypeDescriptor("LBadObject);");
85 EXPECT_FALSE(parse.has_value());
86 }
87
88 {
89 auto parse = ParseSingleTypeDescriptor("LBadObject(;");
90 EXPECT_FALSE(parse.has_value());
91 }
92
93 {
94 auto parse = ParseSingleTypeDescriptor("LBadObject[;");
95 EXPECT_FALSE(parse.has_value());
96 }
97
98 // Stringify is used for convenience to make writing out tests easier.
99 // Transforms as "(XYZ)W" -> "args={X,Y,Z}, ret=W"
100
101 #define PARSE_SIGNATURE_AS_LIST(str) (ParseSignatureAsList<sizeof(str)>(str))
102
103 {
104 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST("()V");
105 EXPECT_STRINGIFY_EQ("args={}, ret=V", jni_descriptor);
106 }
107
108 {
109 constexpr auto
110 jni_descriptor = PARSE_SIGNATURE_AS_LIST("()Ljava/lang/Object;");
111 EXPECT_STRINGIFY_EQ("args={}, ret=Ljava/lang/Object;", jni_descriptor);
112 }
113
114 {
115 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST("()[I");
116 EXPECT_STRINGIFY_EQ("args={}, ret=[I", jni_descriptor);
117 }
118
119 #define EXPECT_OK_SIGNATURE_PARSE(signature, args, ret) \
120 do { \
121 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST(signature); \
122 EXPECT_EQ(true, jni_descriptor.has_value()); \
123 EXPECT_STRINGIFY_EQ("args={" args "}, ret=" ret, jni_descriptor); \
124 } while (0)
125
126 // Exhaustive tests for successful parsing.
127
128 EXPECT_OK_SIGNATURE_PARSE("()V", /*args*/"", /*ret*/"V");
129 EXPECT_OK_SIGNATURE_PARSE("()Z", /*args*/"", /*ret*/"Z");
130 EXPECT_OK_SIGNATURE_PARSE("()B", /*args*/"", /*ret*/"B");
131 EXPECT_OK_SIGNATURE_PARSE("()C", /*args*/"", /*ret*/"C");
132 EXPECT_OK_SIGNATURE_PARSE("()S", /*args*/"", /*ret*/"S");
133 EXPECT_OK_SIGNATURE_PARSE("()I", /*args*/"", /*ret*/"I");
134 EXPECT_OK_SIGNATURE_PARSE("()F", /*args*/"", /*ret*/"F");
135 EXPECT_OK_SIGNATURE_PARSE("()J", /*args*/"", /*ret*/"J");
136 EXPECT_OK_SIGNATURE_PARSE("()D", /*args*/"", /*ret*/"D");
137 EXPECT_OK_SIGNATURE_PARSE("()Ljava/lang/Object;", /*args*/"", /*ret*/"Ljava/lang/Object;");
138 EXPECT_OK_SIGNATURE_PARSE("()[Ljava/lang/Object;", /*args*/"", /*ret*/"[Ljava/lang/Object;");
139 EXPECT_OK_SIGNATURE_PARSE("()[I", /*args*/"", /*ret*/"[I");
140 EXPECT_OK_SIGNATURE_PARSE("()[[I", /*args*/"", /*ret*/"[[I");
141 EXPECT_OK_SIGNATURE_PARSE("()[[[I", /*args*/"", /*ret*/"[[[I");
142
143
144 EXPECT_OK_SIGNATURE_PARSE("(Z)V", /*args*/"Z", /*ret*/"V");
145 EXPECT_OK_SIGNATURE_PARSE("(B)V", /*args*/"B", /*ret*/"V");
146 EXPECT_OK_SIGNATURE_PARSE("(C)D", /*args*/"C", /*ret*/"D");
147 EXPECT_OK_SIGNATURE_PARSE("(S)V", /*args*/"S", /*ret*/"V");
148 EXPECT_OK_SIGNATURE_PARSE("(I)V", /*args*/"I", /*ret*/"V");
149 EXPECT_OK_SIGNATURE_PARSE("(F)V", /*args*/"F", /*ret*/"V");
150 EXPECT_OK_SIGNATURE_PARSE("(J)F", /*args*/"J", /*ret*/"F");
151 EXPECT_OK_SIGNATURE_PARSE("(D)V", /*args*/"D", /*ret*/"V");
152 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;)V", "Ljava/lang/Object;", "V");
153 EXPECT_OK_SIGNATURE_PARSE("([Ljava/lang/Object;)V",
154 "[Ljava/lang/Object;",
155 "V");
156 EXPECT_OK_SIGNATURE_PARSE("([I)V", /*ret*/"[I", "V");
157 EXPECT_OK_SIGNATURE_PARSE("([[I)V", /*ret*/"[[I", "V");
158 EXPECT_OK_SIGNATURE_PARSE("([[[I)V", /*ret*/"[[[I", "V");
159
160 EXPECT_OK_SIGNATURE_PARSE("(ZIJ)V", /*args*/"Z,I,J", /*ret*/"V");
161 EXPECT_OK_SIGNATURE_PARSE("(B[IJ)V", /*args*/"B,[I,J", /*ret*/"V");
162 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;B)D",
163 /*args*/"Ljava/lang/Object;,B",
164 /*ret*/"D");
165 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;Ljava/lang/String;IF)D",
166 /*args*/"Ljava/lang/Object;,Ljava/lang/String;,I,F",
167 /*ret*/"D");
168 EXPECT_OK_SIGNATURE_PARSE("([[[Ljava/lang/Object;Ljava/lang/String;IF)D",
169 /*args*/"[[[Ljava/lang/Object;,Ljava/lang/String;,I,F",
170 /*ret*/"D");
171
172 /*
173 * Test Failures in Parsing
174 */
175
176 #define EXPECT_FAILED_SIGNATURE_PARSE(jni_descriptor) \
177 EXPECT_STRINGIFY_EQ(ConstexprOptional<JniSignatureDescriptor<sizeof(jni_descriptor)>>{},\
178 ParseSignatureAsList<sizeof(jni_descriptor)>(jni_descriptor))
179
180 // For the failures to work we must turn off 'PARSE_FAILURES_FATAL'.
181 // Otherwise they immediately cause a crash, which is actually the desired behavior
182 // when this is used by the end-user in REGISTER_NATIVE_METHOD.
183 {
184 EXPECT_FAILED_SIGNATURE_PARSE("");
185 EXPECT_FAILED_SIGNATURE_PARSE("A");
186 EXPECT_FAILED_SIGNATURE_PARSE(")");
187 EXPECT_FAILED_SIGNATURE_PARSE("V");
188 EXPECT_FAILED_SIGNATURE_PARSE("(");
189 EXPECT_FAILED_SIGNATURE_PARSE("(A");
190 EXPECT_FAILED_SIGNATURE_PARSE("()");
191 EXPECT_FAILED_SIGNATURE_PARSE("()A");
192 EXPECT_FAILED_SIGNATURE_PARSE("()VV");
193 EXPECT_FAILED_SIGNATURE_PARSE("()L");
194 EXPECT_FAILED_SIGNATURE_PARSE("()L;");
195 EXPECT_FAILED_SIGNATURE_PARSE("()BAD;");
196 EXPECT_FAILED_SIGNATURE_PARSE("()Ljava/lang/Object");
197 EXPECT_FAILED_SIGNATURE_PARSE("()Ljava/lang/Object;X");
198
199 EXPECT_FAILED_SIGNATURE_PARSE("(V)V");
200 EXPECT_FAILED_SIGNATURE_PARSE("(ILcat)V");
201 EXPECT_FAILED_SIGNATURE_PARSE("([dog)V");
202 EXPECT_FAILED_SIGNATURE_PARSE("(IV)V");
203 EXPECT_FAILED_SIGNATURE_PARSE("([V)V");
204 EXPECT_FAILED_SIGNATURE_PARSE("([[V)V");
205 EXPECT_FAILED_SIGNATURE_PARSE("()v");
206 EXPECT_FAILED_SIGNATURE_PARSE("()i");
207 EXPECT_FAILED_SIGNATURE_PARSE("()f");
208 }
209
210 }
211
212 #define EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(expected, expr) \
213 { constexpr bool is_valid = (expr); \
214 EXPECT_EQ(expected, is_valid) << #expr; \
215 }
216
217 // Basic smoke tests for parameter validity.
218 // See below for more exhaustive tests.
TEST(JniSafeRegisterNativeMethods,ParameterTypes)219 TEST(JniSafeRegisterNativeMethods, ParameterTypes) {
220 using namespace nativehelper::detail; // NOLINT
221 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 0u));
222 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 1u));
223 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 2u));
224 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 3u));
225 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 4u));
226
227 EXPECT_FALSE(IsJniParameterCountValid(kNormalNative, 0u));
228 EXPECT_FALSE(IsJniParameterCountValid(kNormalNative, 1u));
229 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 2u));
230 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 3u));
231 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 4u));
232
233 EXPECT_TRUE((IsValidJniParameter<void>(kNormalNative, kReturnPosition)));
234 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/0u, JNIEnv*>::value));
235 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jobject>::value));
236 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jclass>::value));
237 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(false,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jstring>::value));
238 }
239
240 struct TestReturnAnything {
241 template <typename T>
operator TTestReturnAnything242 operator T() const { // NOLINT
243 return T{};
244 }
245 };
246
247 namespace test_jni {
empty_fn()248 void empty_fn() {}
249 }
250 struct TestJni {
251
252 #pragma clang diagnostic push
253 #pragma clang diagnostic ignored "-Wunused-parameter"
254
255 // Always bad.
bad_cptrTestJni256 static void bad_cptr(const char* ptr) {}
bad_ret_ptrTestJni257 static void* bad_ret_ptr() { return nullptr; }
bad_ret_envTestJni258 static JNIEnv* bad_ret_env() { return nullptr; }
bad_wrongplace_envTestJni259 static void bad_wrongplace_env(jobject, JNIEnv*) {}
bad_wrongplace_env2TestJni260 static void bad_wrongplace_env2(jobject, jobject, JNIEnv*) {}
v_eTestJni261 static void v_e(JNIEnv*) {}
v_eiTestJni262 static void v_ei(JNIEnv*, jint l) {}
v_elTestJni263 static void v_el(JNIEnv*, jlong l) {}
v_etTestJni264 static void v_et(JNIEnv*, jstring) {}
o_noneTestJni265 static jobject o_none() { return nullptr; }
bad_noref_jint_normTestJni266 static void bad_noref_jint_norm(JNIEnv*, jclass, jint&) {}
bad_noref_jint_critTestJni267 static void bad_noref_jint_crit(jint&) {}
268
269 // Good depending on the context:
270
271 // CriticalNative
empty_fnTestJni272 static void empty_fn() {}
int_fnTestJni273 static jint int_fn() { return 0; }
274
v_TestJni275 static void v_() {}
276 // Note: volatile,const don't participate in the function signature
277 // but we still have these here to clarify that it is indeed allowed.
v_vol_iTestJni278 static void v_vol_i(volatile jint) {}
v_const_iTestJni279 static void v_const_i(const jint) {}
v_iTestJni280 static void v_i(jint) {}
v_lTestJni281 static void v_l(jlong) {}
v_libTestJni282 static void v_lib(jlong, jint, jboolean) {}
s_libTestJni283 static jshort s_lib(jlong, jint, jboolean) { return 0; }
284
285 // Normal or FastNative.
v_eoTestJni286 static void v_eo(JNIEnv*, jobject) {}
v_eooTestJni287 static void v_eoo(JNIEnv*, jobject, jobject) {}
v_ekTestJni288 static void v_ek(JNIEnv*, jclass) {}
v_eolibTestJni289 static void v_eolib(JNIEnv*, jobject, jlong, jint, jboolean) {}
s_eolAibATestJni290 static jshort s_eolAibA(JNIEnv*, jobject, jlongArray, jint, jbooleanArray) { return 0; }
291
292 #define DEC_TEST_FN_IMPL(name, ret_t, ...) \
293 static ret_t name (__VA_ARGS__) { return TestReturnAnything{}; }
294
295 #define DEC_TEST_FN(name, correct, ret_t, ...) \
296 DEC_TEST_FN_IMPL(normal_ ## name, ret_t, JNIEnv*, jobject, __VA_ARGS__) \
297 DEC_TEST_FN_IMPL(normal2_ ## name, ret_t, JNIEnv*, jclass, __VA_ARGS__) \
298 DEC_TEST_FN_IMPL(critical_ ## name, ret_t, __VA_ARGS__)
299
300 #define DEC_TEST_FN0(name, correct, ret_t) \
301 DEC_TEST_FN_IMPL(normal_ ## name, ret_t, JNIEnv*, jobject) \
302 DEC_TEST_FN_IMPL(normal2_ ## name, ret_t, JNIEnv*, jclass) \
303 DEC_TEST_FN_IMPL(critical_ ## name, ret_t)
304
305 #define JNI_TEST_FN(FN, FN0) \
306 FN0(a0,CRITICAL,void) \
307 FN0(a ,CRITICAL,jboolean) \
308 FN0(a1,CRITICAL,jbyte) \
309 FN0(g, CRITICAL,jchar) \
310 FN0(c, CRITICAL,jshort) \
311 FN0(b, CRITICAL,jint) \
312 FN0(f, CRITICAL,jlong) \
313 FN0(d, CRITICAL,jfloat) \
314 FN0(e, CRITICAL,jdouble) \
315 FN0(f2,NORMAL ,jobject) \
316 FN0(f3,NORMAL ,jclass) \
317 FN0(fr,NORMAL ,jstring) \
318 FN0(fa,NORMAL ,jarray) \
319 FN0(fb,NORMAL ,jobjectArray) \
320 FN0(fc,NORMAL ,jbooleanArray) \
321 FN0(fd,NORMAL ,jcharArray) \
322 FN0(fe,NORMAL ,jshortArray) \
323 FN0(ff,NORMAL ,jintArray) \
324 FN0(fg,NORMAL ,jlongArray) \
325 FN0(fk,NORMAL ,jfloatArray) \
326 FN0(fi,NORMAL ,jdoubleArray) \
327 FN0(fl,NORMAL ,jthrowable) \
328 FN(aa, CRITICAL,jboolean,jboolean) \
329 FN(ax, CRITICAL,jbyte,jbyte) \
330 FN(ag, CRITICAL,jchar,jchar) \
331 FN(ac, CRITICAL,jshort,jshort) \
332 FN(ac2,CRITICAL,jshort,jshort,jchar) \
333 FN(ab, CRITICAL,jint,jint) \
334 FN(af, CRITICAL,jlong,jlong) \
335 FN(ad, CRITICAL,jfloat,jfloat) \
336 FN(ae, CRITICAL,jdouble,jdouble) \
337 FN(af2,NORMAL ,jobject,jobject) \
338 FN(af3,NORMAL ,jclass,jclass) \
339 FN(afr,NORMAL ,jstring,jstring) \
340 FN(afa,NORMAL ,jarray,jarray) \
341 FN(afb,NORMAL ,jobjectArray,jobjectArray) \
342 FN(afc,NORMAL ,jbooleanArray,jbooleanArray) \
343 FN(afd,NORMAL ,jcharArray,jcharArray) \
344 FN(afe,NORMAL ,jshortArray,jshortArray) \
345 FN(aff,NORMAL ,jintArray,jintArray) \
346 FN(afg,NORMAL ,jlongArray,jlongArray) \
347 FN(afk,NORMAL ,jfloatArray,jfloatArray) \
348 FN(afi,NORMAL ,jdoubleArray,jdoubleArray) \
349 FN(agi,NORMAL ,jdoubleArray,jdoubleArray,jobject) \
350 FN(afl,NORMAL ,jthrowable,jthrowable) \
351 \
352 FN0(z0,ILLEGAL ,JNIEnv*) \
353 FN(z1, ILLEGAL ,void, JNIEnv*) \
354 FN(z2, ILLEGAL ,JNIEnv*, JNIEnv*) \
355 FN(z3, ILLEGAL ,void, void*) \
356 FN0(z4,ILLEGAL ,void*) \
357
358 #define JNI_TEST_FN_BOTH(x) JNI_TEST_FN(x,x)
359
360 // we generate a return statement because some functions are non-void.
361 // disable the useless warning about returning from a non-void function.
362 #pragma clang diagnostic push
363 #pragma clang diagnostic ignored "-Wreturn-type"
364 JNI_TEST_FN(DEC_TEST_FN, DEC_TEST_FN0);
365 #pragma clang diagnostic pop
366
367 // TODO: probably should be an x-macro table
368 // and that way we can add critical/normal to it as well
369 // and also the type descriptor, and reuse this for multiple tests.
370
371 #pragma clang diagnostic pop
372 };
373 // Note: Using function-local structs does not work.
374 // Template parameters must have linkage, which function-local structs lack.
375
TEST(JniSafeRegisterNativeMethods,FunctionTypes)376 TEST(JniSafeRegisterNativeMethods, FunctionTypes) {
377 using namespace nativehelper::detail; // NOLINT
378 // The exact error messages are not tested but they would be seen in the compiler
379 // stack trace when used from a constexpr context.
380
381 #define IS_VALID_JNI_FUNCTION_TYPE(native_kind, func) \
382 (IsValidJniFunctionType<native_kind, decltype(func), (func)>())
383 #define IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func) IS_VALID_JNI_FUNCTION_TYPE(kNormalNative, func)
384 #define IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func) IS_VALID_JNI_FUNCTION_TYPE(kCriticalNative, func)
385
386 #define EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(func) \
387 do { \
388 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
389 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
390 } while (false)
391
392 #define EXPECT_NORMAL_JNI_FUNCTION_TYPE(func) \
393 do { \
394 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
395 EXPECT_TRUE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
396 } while (false)
397
398 #define EXPECT_CRITICAL_JNI_FUNCTION_TYPE(func) \
399 do { \
400 EXPECT_TRUE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
401 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
402 } while (false)
403
404 {
405 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_cptr);
406 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_ret_ptr);
407 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_ret_env);
408 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_wrongplace_env);
409 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_wrongplace_env2);
410
411 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::empty_fn);
412 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(test_jni::empty_fn);
413 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::int_fn);
414
415 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_);
416 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_vol_i);
417 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_const_i);
418 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_i);
419 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_l);
420
421 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_e);
422 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_ei);
423 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_el);
424 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_et);
425
426 EXPECT_NORMAL_JNI_FUNCTION_TYPE(TestJni::v_eo);
427 EXPECT_NORMAL_JNI_FUNCTION_TYPE(TestJni::v_ek);
428
429 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::o_none);
430 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_noref_jint_norm);
431 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_noref_jint_crit);
432 }
433
434 enum class TestJniKind {
435 ILLEGAL,
436 NORMAL,
437 CRITICAL
438 };
439
440 // ILLEGAL signatures are always illegal.
441 bool kExpected_ILLEGAL_against_NORMAL = false;
442 bool kExpected_ILLEGAL_against_CRITICAL = false;
443 // NORMAL signatures are only legal for Normal JNI.
444 bool kExpected_NORMAL_against_NORMAL = true;
445 bool kExpected_NORMAL_against_CRITICAL = false;
446 // CRITICAL signatures are legal for both Normal+Critical JNI.
447 bool kExpected_CRITICAL_against_CRITICAL = true;
448 bool kExpected_CRITICAL_against_NORMAL = true;
449 // Note that we munge normal and critical type signatures separately
450 // and that a normal_ prefixed is always a bad critical signature,
451 // and a critical_ prefixed signature is always a bad normal signature.
452 // See JNI_TEST_FN_MAKE_TEST for the implementation of this logic.
453
454 #undef EXPECTED_FOR
455 #define EXPECTED_FOR(jni_kind, context) \
456 (kExpected_ ## jni_kind ## _against_ ## context)
457
458 {
459 #define JNI_TEST_FN_MAKE_TEST(name, jni_kind, ...) \
460 do { \
461 EXPECT_EQ(EXPECTED_FOR(jni_kind, NORMAL), \
462 IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::normal_ ## name)); \
463 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::normal_ ## name)); \
464 EXPECT_EQ(EXPECTED_FOR(jni_kind, NORMAL), \
465 IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::normal2_ ## name)); \
466 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::normal2_ ## name)); \
467 EXPECT_EQ(EXPECTED_FOR(jni_kind, CRITICAL), \
468 IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::critical_ ## name)); \
469 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::critical_ ## name)); \
470 } while (false);
471
472 JNI_TEST_FN_BOTH(JNI_TEST_FN_MAKE_TEST);
473 }
474 }
475
476 #define EXPECT_CONSTEXPR_EQ(lhs, rhs) \
477 { constexpr auto lhs_val = (lhs); \
478 constexpr auto rhs_val = (rhs); \
479 EXPECT_EQ(lhs_val, rhs_val) << "LHS: " << #lhs << ", RHS: " << #rhs; \
480 }
481
TEST(JniSafeRegisterNativeMethods,FunctionTypeDescriptorConversion)482 TEST(JniSafeRegisterNativeMethods, FunctionTypeDescriptorConversion) {
483 using namespace nativehelper::detail; // NOLINT
484 {
485 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kCriticalNative,
486 decltype(TestJni::v_i),
487 TestJni::v_i>();
488 ASSERT_TRUE(cvrt.has_value());
489 EXPECT_CONSTEXPR_EQ(2u, cvrt->max_size);
490 EXPECT_CONSTEXPR_EQ(1u, cvrt->args.size());
491 EXPECT_STRINGIFY_EQ("args={jint}, ret=void", cvrt.value());
492 }
493
494 {
495 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kNormalNative,
496 decltype(TestJni::v_i),
497 TestJni::v_i>();
498 EXPECT_FALSE(cvrt.has_value());
499 }
500
501 {
502 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kNormalNative,
503 decltype(TestJni::normal_agi),
504 TestJni::normal_agi>();
505 ASSERT_TRUE(cvrt.has_value());
506 EXPECT_EQ(2u, cvrt->args.size());
507 EXPECT_STRINGIFY_EQ("args={jdoubleArray,jobject}, ret=jdoubleArray", cvrt.value());
508 }
509
510 {
511 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kCriticalNative,
512 decltype(TestJni::critical_ac2),
513 TestJni::critical_ac2>();
514 ASSERT_TRUE(cvrt.has_value());
515 EXPECT_EQ(2u, cvrt->args.size());
516 EXPECT_STRINGIFY_EQ("args={jshort,jchar}, ret=jshort", cvrt.value());
517 }
518
519 // TODO: use JNI_TEST_FN to generate these tests automatically.
520 }
521
522 struct test_function_traits {
int_returning_functiontest_function_traits523 static int int_returning_function() { return 0; }
524 };
525
526 template <typename T>
527 struct apply_return_type {
operator ()apply_return_type528 constexpr int operator()() const {
529 return sizeof(T) == sizeof(int);
530 }
531 };
532
533 #define FN_ARGS_PAIR(fn) decltype(fn), (fn)
534
TEST(JniSafeRegisterNativeMethods,FunctionTraits)535 TEST(JniSafeRegisterNativeMethods, FunctionTraits) {
536 using namespace nativehelper::detail; // NOLINT
537 using traits_for_int_ret =
538 FunctionTypeMetafunction<FN_ARGS_PAIR(test_function_traits::int_returning_function)>;
539 int applied = traits_for_int_ret::map_return<apply_return_type>();
540 EXPECT_EQ(1, applied);
541
542 auto arr = traits_for_int_ret::map_args<apply_return_type>();
543 EXPECT_EQ(0u, arr.size());
544 }
545
546 struct IntHolder {
547 int value;
548 };
549
GetTestValue(const IntHolder & i)550 constexpr int GetTestValue(const IntHolder& i) {
551 return i.value;
552 }
553
GetTestValue(int i)554 constexpr int GetTestValue(int i) {
555 return i;
556 }
557
558 template <typename T, size_t kMaxSize>
SumUpVector(const nativehelper::detail::ConstexprVector<T,kMaxSize> & vec)559 constexpr size_t SumUpVector(const nativehelper::detail::ConstexprVector<T, kMaxSize>& vec) {
560 size_t s = 0;
561 for (const T& elem : vec) {
562 s += static_cast<size_t>(GetTestValue(elem));
563 }
564 return s;
565 }
566
567 template <typename T>
make_test_int_vector()568 constexpr auto make_test_int_vector() {
569 using namespace nativehelper::detail; // NOLINT
570 ConstexprVector<T, 5> vec_int;
571 vec_int.push_back(T{1});
572 vec_int.push_back(T{2});
573 vec_int.push_back(T{3});
574 vec_int.push_back(T{4});
575 vec_int.push_back(T{5});
576 return vec_int;
577 }
578
TEST(JniSafeRegisterNativeMethods,ConstexprOptional)579 TEST(JniSafeRegisterNativeMethods, ConstexprOptional) {
580 using namespace nativehelper::detail; // NOLINT
581
582 ConstexprOptional<int> int_opt;
583 EXPECT_FALSE(int_opt.has_value());
584
585 int_opt = ConstexprOptional<int>(12345);
586 EXPECT_EQ(12345, int_opt.value());
587 EXPECT_EQ(12345, *int_opt);
588 }
589
TEST(JniSafeRegisterNativeMethods,ConstexprVector)590 TEST(JniSafeRegisterNativeMethods, ConstexprVector) {
591 using namespace nativehelper::detail; // NOLINT
592 {
593 constexpr ConstexprVector<IntHolder, 5> vec_int = make_test_int_vector<IntHolder>();
594 constexpr size_t the_sum = SumUpVector(vec_int);
595 EXPECT_EQ(15u, the_sum);
596 }
597
598 {
599 constexpr ConstexprVector<int, 5> vec_int = make_test_int_vector<int>();
600 constexpr size_t the_sum = SumUpVector(vec_int);
601 EXPECT_EQ(15u, the_sum);
602 }
603 }
604
605 // Need this intermediate function to make a JniDescriptorNode from a string literal.
606 // C++ doesn't do implicit conversion through two+ type constructors.
MakeNode(nativehelper::detail::ConstexprStringView str)607 constexpr nativehelper::detail::JniDescriptorNode MakeNode(
608 nativehelper::detail::ConstexprStringView str) {
609 return nativehelper::detail::JniDescriptorNode{str};
610 }
611
612 #define EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived, cond) \
613 do { \
614 constexpr bool res = \
615 CompareJniDescriptorNodeErased(MakeNode(user_desc), \
616 ReifiedJniTypeTrait::Reify<derived>()); \
617 (void)res; \
618 EXPECT_ ## cond(CompareJniDescriptorNodeErased(MakeNode(user_desc), \
619 ReifiedJniTypeTrait::Reify<derived>())); \
620 } while (0);
621
622 #define EXPECT_EQUALISH_JNI_DESCRIPTORS(user_desc, derived_desc) \
623 EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived_desc, TRUE)
624
625 #define EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS(user_desc, derived_desc) \
626 EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived_desc, FALSE)
627
TEST(JniSafeRegisterNativeMethods,CompareJniDescriptorNodeErased)628 TEST(JniSafeRegisterNativeMethods, CompareJniDescriptorNodeErased) {
629 using namespace nativehelper::detail; // NOLINT
630 EXPECT_EQUALISH_JNI_DESCRIPTORS("V", void);
631 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("V", jint);
632 EXPECT_EQUALISH_JNI_DESCRIPTORS("Z", jboolean);
633 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Z", void);
634 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Z", jobject);
635 EXPECT_EQUALISH_JNI_DESCRIPTORS("J", jlong);
636 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jobject);
637 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jthrowable);
638 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jint);
639 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/String;", jstring);
640 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Class;", jclass);
641 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jobject);
642 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jobject);
643 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jthrowable);
644 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jobjectArray);
645 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jintArray);
646 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jarray);
647 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jarray);
648
649 // Stricter checks.
650 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jobjectArray);
651 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/String;", jobject);
652 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Class;", jobject);
653 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jobject);
654 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Ljava/lang/Object;", jobject);
655 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jarray);
656
657 // Permissive checks that are weaker than normal.
658 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Exception;", jobject);
659 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Error;", jobject);
660 EXPECT_EQUALISH_JNI_DESCRIPTORS("[Z", jarray);
661 EXPECT_EQUALISH_JNI_DESCRIPTORS("[I", jarray);
662 EXPECT_EQUALISH_JNI_DESCRIPTORS("[[Z", jarray);
663 EXPECT_EQUALISH_JNI_DESCRIPTORS("[[Ljava/lang/Object;", jarray);
664
665 // jthrowable-related checks.
666 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Throwable;", jobject);
667 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Throwable;", jthrowable);
668 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Exception;", jthrowable);
669 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Error;", jthrowable);
670 }
671
672 #define EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH(type_desc, type) \
673 do { \
674 constexpr auto res = ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc); \
675 EXPECT_TRUE((ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc)).has_value()); \
676 if (res.has_value()) EXPECT_EQ(ReifiedJniTypeTrait::Reify<type>(), res.value()); \
677 } while (false)
678
679 #define EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH(type_desc) \
680 do { \
681 auto res = ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc); \
682 EXPECT_FALSE(res.has_value()); \
683 } while (false)
684
685 #define JNI_TYPE_TRAIT_MUST_BE_SAME_FN(type_name, type_desc, ...) \
686 /* skip jarray because it aliases Ljava/lang/Object; */ \
687 do { \
688 constexpr auto str_type_name = ConstexprStringView(#type_name); \
689 if (str_type_name != "jarray" && str_type_name != "JNIEnv*") { \
690 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH(type_desc, type_name); \
691 } \
692 } while(false);
693
TEST(JniSafeRegisterNativeMethods,MostSimilarTypeDescriptor)694 TEST(JniSafeRegisterNativeMethods, MostSimilarTypeDescriptor) {
695 using namespace nativehelper::detail; // NOLINT
696 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("Z", jboolean);
697 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[[I", jobjectArray);
698 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[[Z", jobjectArray);
699 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[Ljava/lang/String;", jobjectArray);
700 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[Ljava/lang/Integer;", jobjectArray);
701 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("illegal");
702 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("?");
703 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("");
704
705 DEFINE_JNI_TYPE_TRAIT(JNI_TYPE_TRAIT_MUST_BE_SAME_FN);
706 }
707
708 #define ENFORCE_CONSTEXPR(expr) \
709 static_assert(__builtin_constant_p(expr), "Expression must be constexpr")
710
711 #define EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(cond, native_kind, func, desc) \
712 do { \
713 ENFORCE_CONSTEXPR((MatchJniDescriptorWithFunctionType< \
714 native_kind, \
715 decltype(func), \
716 func, \
717 sizeof(desc)>(desc))); \
718 EXPECT_ ## cond((MatchJniDescriptorWithFunctionType< \
719 native_kind, \
720 decltype(func), \
721 func, \
722 sizeof(desc)>(desc))); \
723 } while(0)
724
725 #define EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(native_kind, func, desc) \
726 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(TRUE, native_kind, func, desc)
727
728 #define EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(native_kind, func, desc) \
729 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(FALSE, native_kind, func, desc)
730
TEST(JniSafeRegisterNativeMethods,MatchJniDescriptorWithFunctionType)731 TEST(JniSafeRegisterNativeMethods, MatchJniDescriptorWithFunctionType) {
732 using namespace nativehelper::detail; // NOLINT
733 // Bad C++ signature.
734 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::bad_cptr, "()V");
735 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::bad_cptr, "()V");
736
737 // JNI type descriptor is not legal (by itself).
738 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_, "BAD");
739 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eo, "BAD");
740
741 // Number of parameters in signature vs C++ function does not match.
742 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "()V");
743 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eoo, "()V");
744
745 // Return types don't match.
746 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_, "()Z");
747 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kFastNative, TestJni::v_eo, "()Z");
748
749 // Argument types don't match.
750 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "(Z)V");
751 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative,
752 TestJni::v_eoo,
753 "(Ljava/lang/Class;)V");
754
755 // OK.
756 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "(I)V");
757 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative,
758 TestJni::v_eoo,
759 "(Ljava/lang/Object;)V");
760
761 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_lib, "(JIZ)V");
762 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eolib, "(JIZ)V");
763 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::s_lib, "(JIZ)S");
764 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::s_eolAibA, "([JI[Z)S");
765 }
766
TEST(JniSafeRegisterNativeMethods,Infer)767 TEST(JniSafeRegisterNativeMethods, Infer) {
768 using namespace nativehelper::detail; // NOLINT
769 {
770 using Infer_v_eolib_t = InferJniDescriptor<kNormalNative,
771 decltype(TestJni::v_eolib),
772 TestJni::v_eolib>;
773 EXPECT_CONSTEXPR_EQ(6u, Infer_v_eolib_t::kMaxStringSize);
774 std::string x = Infer_v_eolib_t::GetStringAtRuntime();
775 EXPECT_STRINGIFY_EQ("(JIZ)V", x.c_str());
776 }
777
778 {
779 using Infer_v_eolib_t = InferJniDescriptor<kNormalNative,
780 decltype(TestJni::s_eolAibA),
781 TestJni::s_eolAibA>;
782 EXPECT_STRINGIFY_EQ("args={[J,I,[Z}, ret=S", Infer_v_eolib_t::FromFunctionType().value());
783 EXPECT_CONSTEXPR_EQ(8u, Infer_v_eolib_t::kMaxStringSize);
784 std::string x = Infer_v_eolib_t::GetStringAtRuntime();
785 EXPECT_STRINGIFY_EQ("([JI[Z)S", x.c_str());
786 }
787 }
788
789 // Test the macro definition only. See other tests above for signature-match testing.
TEST(JniSafeRegisterNativeMethods,MakeCheckedJniNativeMethod)790 TEST(JniSafeRegisterNativeMethods, MakeCheckedJniNativeMethod) {
791 // Ensure the temporary variables don't conflict with other local vars of same name.
792 JNINativeMethod tmp_native_method; // shadow test.
793 (void) tmp_native_method;
794 bool is_signature_valid = true; // shadow test.
795 (void) is_signature_valid;
796
797 // Ensure it works with critical.
798 {
799 JNINativeMethod m =
800 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
801 "v_lib",
802 "(JIZ)V",
803 TestJni::v_lib);
804 (void)m;
805 }
806
807 // Ensure it works with normal.
808 {
809 JNINativeMethod m =
810 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
811 "v_eolib",
812 "(JIZ)V",
813 TestJni::v_eolib);
814 (void)m;
815 }
816
817 // Make sure macros properly expand inside of an array.
818 {
819 JNINativeMethod m_array[] = {
820 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
821 "v_lib",
822 "(JIZ)V",
823 TestJni::v_lib),
824 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
825 "v_eolib",
826 "(JIZ)V",
827 TestJni::v_eolib),
828 };
829 (void)m_array;
830 }
831 {
832 JNINativeMethod m_array_direct[] {
833 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
834 "v_lib",
835 "(JIZ)V",
836 TestJni::v_lib),
837 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
838 "v_eolib",
839 "(JIZ)V",
840 TestJni::v_eolib),
841 };
842 (void)m_array_direct;
843 }
844
845 }
846
847 static auto sTestCheckedAtFileScope =
848 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
849 "v_lib",
850 "(JIZ)V",
851 TestJni::v_lib);
852
853 static auto sTestInferredAtFileScope =
854 MAKE_INFERRED_JNI_NATIVE_METHOD(kCriticalNative,
855 "v_lib",
856 TestJni::v_lib);
857
TEST(JniSafeRegisterNativeMethods,TestInferredJniNativeMethod)858 TEST(JniSafeRegisterNativeMethods, TestInferredJniNativeMethod) {
859 (void) sTestCheckedAtFileScope;
860 (void) sTestInferredAtFileScope;
861
862 // Ensure it works with critical.
863 {
864 JNINativeMethod m =
865 MAKE_INFERRED_JNI_NATIVE_METHOD(kCriticalNative,
866 "v_lib",
867 TestJni::v_lib);
868 (void)m;
869 }
870
871 // Ensure it works with normal.
872 {
873 JNINativeMethod m =
874 MAKE_INFERRED_JNI_NATIVE_METHOD(kNormalNative,
875 "v_eolib",
876 TestJni::v_eolib);
877 (void)m;
878 }
879 }
880
TestJniMacros_v_lib(jlong,jint,jboolean)881 static void TestJniMacros_v_lib(jlong, jint, jboolean) {}
TestJniMacros_v_lib_od(jlong,jint,jboolean)882 static void TestJniMacros_v_lib_od(jlong, jint, jboolean) {}
TestJniMacros_v_eolib(JNIEnv *,jobject,jlong,jint,jboolean)883 static void TestJniMacros_v_eolib(JNIEnv*, jobject, jlong, jint, jboolean) {}
TestJniMacros_v_eolib_od(JNIEnv *,jobject,jlong,jint,jboolean)884 static void TestJniMacros_v_eolib_od(JNIEnv*, jobject, jlong, jint, jboolean) {}
885
886 #pragma clang diagnostic push
887 #pragma clang diagnostic ignored "-Wunused-parameter"
888
android_os_Parcel_dataSize(jlong)889 static jint android_os_Parcel_dataSize(jlong) { return 0; }
android_os_Parcel_dataAvail(jlong)890 static jint android_os_Parcel_dataAvail(jlong) { return 0; }
android_os_Parcel_dataPosition(jlong)891 static jint android_os_Parcel_dataPosition(jlong) { return 0; }
android_os_Parcel_dataCapacity(jlong)892 static jint android_os_Parcel_dataCapacity(jlong) { return 0; }
android_os_Parcel_setDataSize(JNIEnv *,jclass,jlong,jint)893 static jlong android_os_Parcel_setDataSize(JNIEnv*, jclass, jlong, jint) { return 0; }
android_os_Parcel_setDataPosition(jlong,jint)894 static void android_os_Parcel_setDataPosition(jlong, jint) {}
android_os_Parcel_setDataCapacity(JNIEnv *,jclass,jlong,jint)895 static void android_os_Parcel_setDataCapacity(JNIEnv*, jclass, jlong, jint) {}
android_os_Parcel_pushAllowFds(jlong,jboolean)896 static jboolean android_os_Parcel_pushAllowFds(jlong, jboolean) { return true; }
android_os_Parcel_restoreAllowFds(jlong,jboolean)897 static void android_os_Parcel_restoreAllowFds(jlong, jboolean) {}
android_os_Parcel_writeByteArray(JNIEnv *,jclass,jlong,jbyteArray,jint,jint)898 static void android_os_Parcel_writeByteArray(JNIEnv*, jclass, jlong, jbyteArray, jint, jint) {}
899
android_os_Parcel_writeBlob(JNIEnv *,jclass,jlong,jbyteArray,jint,jint)900 static void android_os_Parcel_writeBlob(JNIEnv*, jclass, jlong, jbyteArray, jint, jint) {}
android_os_Parcel_writeInt(JNIEnv *,jclass,jlong,jint)901 static void android_os_Parcel_writeInt(JNIEnv*, jclass, jlong, jint) {}
android_os_Parcel_writeLong(JNIEnv * env,jclass clazz,jlong nativePtr,jlong val)902 static void android_os_Parcel_writeLong(JNIEnv* env,
903 jclass clazz,
904 jlong nativePtr,
905 jlong val) {}
android_os_Parcel_writeFloat(JNIEnv * env,jclass clazz,jlong nativePtr,jfloat val)906 static void android_os_Parcel_writeFloat(JNIEnv* env,
907 jclass clazz,
908 jlong nativePtr,
909 jfloat val) {}
android_os_Parcel_writeDouble(JNIEnv * env,jclass clazz,jlong nativePtr,jdouble val)910 static void android_os_Parcel_writeDouble(JNIEnv* env,
911 jclass clazz,
912 jlong nativePtr,
913 jdouble val) {}
android_os_Parcel_writeString(JNIEnv * env,jclass clazz,jlong nativePtr,jstring val)914 static void android_os_Parcel_writeString(JNIEnv* env,
915 jclass clazz,
916 jlong nativePtr,
917 jstring val) {}
android_os_Parcel_writeStrongBinder(JNIEnv * env,jclass clazz,jlong nativePtr,jobject object)918 static void android_os_Parcel_writeStrongBinder(JNIEnv* env,
919 jclass clazz,
920 jlong nativePtr,
921 jobject object) {}
android_os_Parcel_writeFileDescriptor(JNIEnv * env,jclass clazz,jlong nativePtr,jobject object)922 static jlong android_os_Parcel_writeFileDescriptor(JNIEnv* env,
923 jclass clazz,
924 jlong nativePtr,
925 jobject object) { return 0; }
android_os_Parcel_createByteArray(JNIEnv * env,jclass clazz,jlong nativePtr)926 static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env,
927 jclass clazz,
928 jlong nativePtr) { return nullptr; }
929
android_os_Parcel_readByteArray(JNIEnv * env,jclass clazz,jlong nativePtr,jbyteArray dest,jint destLen)930 static jboolean android_os_Parcel_readByteArray(JNIEnv* env,
931 jclass clazz,
932 jlong nativePtr,
933 jbyteArray dest,
934 jint destLen) { return false; }
android_os_Parcel_readBlob(JNIEnv * env,jclass clazz,jlong nativePtr)935 static jbyteArray android_os_Parcel_readBlob(JNIEnv* env,
936 jclass clazz,
937 jlong nativePtr) { return nullptr; }
938
android_os_Parcel_readInt(jlong nativePtr)939 static jint android_os_Parcel_readInt(jlong nativePtr) { return 0; }
940
android_os_Parcel_readLong(jlong nativePtr)941 static jlong android_os_Parcel_readLong(jlong nativePtr) { return 0; }
942
android_os_Parcel_readFloat(jlong nativePtr)943 static jfloat android_os_Parcel_readFloat(jlong nativePtr) { return 0.0f; }
android_os_Parcel_readDouble(jlong nativePtr)944 static jdouble android_os_Parcel_readDouble(jlong nativePtr) { return 0.0; }
945
android_os_Parcel_readString(JNIEnv * env,jclass clazz,jlong nativePtr)946 static jstring android_os_Parcel_readString(JNIEnv* env,
947 jclass clazz,
948 jlong nativePtr) { return nullptr; }
949
android_os_Parcel_readStrongBinder(JNIEnv * env,jclass clazz,jlong nativePtr)950 static jobject android_os_Parcel_readStrongBinder(JNIEnv* env,
951 jclass clazz,
952 jlong nativePtr) { return nullptr; }
953
954
android_os_Parcel_readFileDescriptor(JNIEnv * env,jclass clazz,jlong nativePtr)955 static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env,
956 jclass clazz,
957 jlong nativePtr) { return nullptr; }
958
android_os_Parcel_openFileDescriptor(JNIEnv * env,jclass clazz,jstring name,jint mode)959 static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env,
960 jclass clazz,
961 jstring name,
962 jint mode) { return 0; }
963
964
android_os_Parcel_dupFileDescriptor(JNIEnv * env,jclass clazz,jobject orig)965 static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env,
966 jclass clazz,
967 jobject orig) { return 0; }
968
969
android_os_Parcel_closeFileDescriptor(JNIEnv * env,jclass clazz,jobject object)970 static void android_os_Parcel_closeFileDescriptor(JNIEnv* env,
971 jclass clazz,
972 jobject object) {}
973
974
android_os_Parcel_clearFileDescriptor(JNIEnv * env,jclass clazz,jobject object)975 static void android_os_Parcel_clearFileDescriptor(JNIEnv* env,
976 jclass clazz,
977 jobject object) {}
978
979
android_os_Parcel_create(JNIEnv * env,jclass clazz)980 static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz) { return 0; }
981
982
android_os_Parcel_freeBuffer(JNIEnv * env,jclass clazz,jlong nativePtr)983 static jlong android_os_Parcel_freeBuffer(JNIEnv* env,
984 jclass clazz,
985 jlong nativePtr) { return 0; }
986
987
android_os_Parcel_destroy(JNIEnv * env,jclass clazz,jlong nativePtr)988 static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr) {}
989
990
android_os_Parcel_marshall(JNIEnv * env,jclass clazz,jlong nativePtr)991 static jbyteArray android_os_Parcel_marshall(JNIEnv* env,
992 jclass clazz,
993 jlong nativePtr) { return 0; }
994
995
android_os_Parcel_unmarshall(JNIEnv * env,jclass clazz,jlong nativePtr,jbyteArray data,jint offset,jint length)996 static jlong android_os_Parcel_unmarshall(JNIEnv* env,
997 jclass clazz,
998 jlong nativePtr,
999 jbyteArray data,
1000 jint offset,
1001 jint length) { return 0; }
1002
1003
android_os_Parcel_compareData(JNIEnv * env,jclass clazz,jlong thisNativePtr,jlong otherNativePtr)1004 static jint android_os_Parcel_compareData(JNIEnv* env,
1005 jclass clazz,
1006 jlong thisNativePtr,
1007 jlong otherNativePtr) { return 0; }
1008
1009
android_os_Parcel_appendFrom(JNIEnv * env,jclass clazz,jlong thisNativePtr,jlong otherNativePtr,jint offset,jint length)1010 static jlong android_os_Parcel_appendFrom(JNIEnv* env,
1011 jclass clazz,
1012 jlong thisNativePtr,
1013 jlong otherNativePtr,
1014 jint offset,
1015 jint length) { return 0; }
1016
1017
android_os_Parcel_hasFileDescriptors(jlong nativePtr)1018 static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) { return 0; }
1019
1020
android_os_Parcel_writeInterfaceToken(JNIEnv * env,jclass clazz,jlong nativePtr,jstring name)1021 static void android_os_Parcel_writeInterfaceToken(JNIEnv* env,
1022 jclass clazz,
1023 jlong nativePtr,
1024 jstring name) {}
1025
1026
android_os_Parcel_enforceInterface(JNIEnv * env,jclass clazz,jlong nativePtr,jstring name)1027 static void android_os_Parcel_enforceInterface(JNIEnv* env,
1028 jclass clazz,
1029 jlong nativePtr,
1030 jstring name) {}
1031
1032
android_os_Parcel_getGlobalAllocSize(JNIEnv * env,jclass clazz)1033 static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz) { return 0; }
1034
1035
android_os_Parcel_getGlobalAllocCount(JNIEnv * env,jclass clazz)1036 static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz) { return 0; }
1037
1038
android_os_Parcel_getBlobAshmemSize(jlong nativePtr)1039 static jlong android_os_Parcel_getBlobAshmemSize(jlong nativePtr) { return 0; }
1040
1041 #pragma clang diagnostic pop
1042
TEST(JniSafeRegisterNativeMethods,ParcelExample)1043 TEST(JniSafeRegisterNativeMethods, ParcelExample) {
1044 // Test a wide range of automatic signature inferencing.
1045 // This is taken from real code in android_os_Parcel.cpp.
1046
1047 const JNINativeMethod gParcelMethods[] = {
1048 // @CriticalNative
1049 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1050 "nativeDataSize", android_os_Parcel_dataSize),
1051 // @CriticalNative
1052 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1053 "nativeDataAvail", android_os_Parcel_dataAvail),
1054 // @CriticalNative
1055 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1056 "nativeDataPosition", android_os_Parcel_dataPosition),
1057 // @CriticalNative
1058 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1059 "nativeDataCapacity", android_os_Parcel_dataCapacity),
1060 // @FastNative
1061 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1062 "nativeSetDataSize", android_os_Parcel_setDataSize),
1063 // @CriticalNative
1064 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1065 "nativeSetDataPosition", android_os_Parcel_setDataPosition),
1066 // @FastNative
1067 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1068 "nativeSetDataCapacity", android_os_Parcel_setDataCapacity),
1069 // @CriticalNative
1070 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1071 "nativePushAllowFds", android_os_Parcel_pushAllowFds),
1072 // @CriticalNative
1073 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1074 "nativeRestoreAllowFds", android_os_Parcel_restoreAllowFds),
1075 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1076 "nativeWriteByteArray", android_os_Parcel_writeByteArray),
1077 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1078 "nativeWriteBlob", android_os_Parcel_writeBlob),
1079 // @FastNative
1080 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1081 "nativeWriteInt", android_os_Parcel_writeInt),
1082 // @FastNative
1083 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1084 "nativeWriteLong", android_os_Parcel_writeLong),
1085 // @FastNative
1086 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1087 "nativeWriteFloat", android_os_Parcel_writeFloat),
1088 // @FastNative
1089 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG(
1090 "nativeWriteDouble", android_os_Parcel_writeDouble),
1091 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1092 "nativeWriteString", android_os_Parcel_writeString),
1093 MAKE_JNI_NATIVE_METHOD(
1094 "nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", android_os_Parcel_writeStrongBinder),
1095 MAKE_JNI_NATIVE_METHOD(
1096 "nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", android_os_Parcel_writeFileDescriptor),
1097
1098 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1099 "nativeCreateByteArray", android_os_Parcel_createByteArray),
1100 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1101 "nativeReadByteArray", android_os_Parcel_readByteArray),
1102 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1103 "nativeReadBlob", android_os_Parcel_readBlob),
1104 // @CriticalNative
1105 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1106 "nativeReadInt", android_os_Parcel_readInt),
1107 // @CriticalNative
1108 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1109 "nativeReadLong", android_os_Parcel_readLong),
1110 // @CriticalNative
1111 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1112 "nativeReadFloat", android_os_Parcel_readFloat),
1113 // @CriticalNative
1114 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1115 "nativeReadDouble", android_os_Parcel_readDouble),
1116 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1117 "nativeReadString", android_os_Parcel_readString),
1118 MAKE_JNI_NATIVE_METHOD(
1119 "nativeReadStrongBinder", "(J)Landroid/os/IBinder;", android_os_Parcel_readStrongBinder),
1120 MAKE_JNI_NATIVE_METHOD(
1121 "nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", android_os_Parcel_readFileDescriptor),
1122 MAKE_JNI_NATIVE_METHOD(
1123 "openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", android_os_Parcel_openFileDescriptor),
1124 MAKE_JNI_NATIVE_METHOD(
1125 "dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", android_os_Parcel_dupFileDescriptor),
1126 MAKE_JNI_NATIVE_METHOD(
1127 "closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", android_os_Parcel_closeFileDescriptor),
1128 MAKE_JNI_NATIVE_METHOD(
1129 "clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", android_os_Parcel_clearFileDescriptor),
1130
1131 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1132 "nativeCreate", android_os_Parcel_create),
1133 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1134 "nativeFreeBuffer", android_os_Parcel_freeBuffer),
1135 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1136 "nativeDestroy", android_os_Parcel_destroy),
1137
1138 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1139 "nativeMarshall", android_os_Parcel_marshall),
1140 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1141 "nativeUnmarshall", android_os_Parcel_unmarshall),
1142 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1143 "nativeCompareData", android_os_Parcel_compareData),
1144 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1145 "nativeAppendFrom", android_os_Parcel_appendFrom),
1146 // @CriticalNative
1147 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1148 "nativeHasFileDescriptors", android_os_Parcel_hasFileDescriptors),
1149 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1150 "nativeWriteInterfaceToken", android_os_Parcel_writeInterfaceToken),
1151 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1152 "nativeEnforceInterface", android_os_Parcel_enforceInterface),
1153
1154 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1155 "getGlobalAllocSize", android_os_Parcel_getGlobalAllocSize),
1156 MAKE_JNI_NATIVE_METHOD_AUTOSIG(
1157 "getGlobalAllocCount", android_os_Parcel_getGlobalAllocCount),
1158
1159 // @CriticalNative
1160 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG(
1161 "nativeGetBlobAshmemSize", android_os_Parcel_getBlobAshmemSize),
1162 };
1163
1164 const JNINativeMethod gParcelMethodsExpected[] = {
1165 // @CriticalNative
1166 {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize},
1167 // @CriticalNative
1168 {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail},
1169 // @CriticalNative
1170 {"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition},
1171 // @CriticalNative
1172 {"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity},
1173 // @FastNative
1174 {"nativeSetDataSize", "(JI)J", (void*)android_os_Parcel_setDataSize},
1175 // @CriticalNative
1176 {"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition},
1177 // @FastNative
1178 {"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity},
1179
1180 // @CriticalNative
1181 {"nativePushAllowFds", "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
1182 // @CriticalNative
1183 {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
1184
1185 {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
1186 {"nativeWriteBlob", "(J[BII)V", (void*)android_os_Parcel_writeBlob},
1187 // @FastNative
1188 {"nativeWriteInt", "(JI)V", (void*)android_os_Parcel_writeInt},
1189 // @FastNative
1190 {"nativeWriteLong", "(JJ)V", (void*)android_os_Parcel_writeLong},
1191 // @FastNative
1192 {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat},
1193 // @FastNative
1194 {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble},
1195 {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
1196 {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
1197 {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
1198
1199 {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray},
1200 {"nativeReadByteArray", "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
1201 {"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob},
1202 // @CriticalNative
1203 {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt},
1204 // @CriticalNative
1205 {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong},
1206 // @CriticalNative
1207 {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat},
1208 // @CriticalNative
1209 {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble},
1210 {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
1211 {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
1212 {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
1213
1214 {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
1215 {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
1216 {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
1217 {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
1218
1219 {"nativeCreate", "()J", (void*)android_os_Parcel_create},
1220 {"nativeFreeBuffer", "(J)J", (void*)android_os_Parcel_freeBuffer},
1221 {"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy},
1222
1223 {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall},
1224 {"nativeUnmarshall", "(J[BII)J", (void*)android_os_Parcel_unmarshall},
1225 {"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData},
1226 {"nativeAppendFrom", "(JJII)J", (void*)android_os_Parcel_appendFrom},
1227 // @CriticalNative
1228 {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
1229 {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
1230 {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
1231
1232 {"getGlobalAllocSize", "()J", (void*)android_os_Parcel_getGlobalAllocSize},
1233 {"getGlobalAllocCount", "()J", (void*)android_os_Parcel_getGlobalAllocCount},
1234
1235 // @CriticalNative
1236 {"nativeGetBlobAshmemSize", "(J)J", (void*)android_os_Parcel_getBlobAshmemSize},
1237 };
1238
1239 ASSERT_EQ(sizeof(gParcelMethodsExpected)/sizeof(JNINativeMethod),
1240 sizeof(gParcelMethods)/sizeof(JNINativeMethod));
1241
1242
1243 for (size_t i = 0; i < sizeof(gParcelMethods) / sizeof(JNINativeMethod); ++i) {
1244 const JNINativeMethod& actual = gParcelMethods[i];
1245 const JNINativeMethod& expected = gParcelMethodsExpected[i];
1246
1247 EXPECT_STREQ(expected.name, actual.name);
1248 EXPECT_STREQ(expected.signature, actual.signature) << expected.name;
1249 EXPECT_EQ(expected.fnPtr, actual.fnPtr) << expected.name;
1250 }
1251 }
1252
TEST(JniSafeRegisterNativeMethods,JniMacros)1253 TEST(JniSafeRegisterNativeMethods, JniMacros) {
1254 JNINativeMethod tmp_native_method; // shadow variable check.
1255 (void)tmp_native_method;
1256 using Infer_t = int; // shadow using check.
1257 Infer_t unused;
1258 (void)unused;
1259
1260 MAKE_JNI_CRITICAL_NATIVE_METHOD("v_lib", "(JIZ)V", TestJniMacros_v_lib);
1261 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG("v_lib", TestJniMacros_v_lib);
1262 CRITICAL_NATIVE_METHOD(TestJniMacros, v_lib, "(JIZ)V");
1263 OVERLOADED_CRITICAL_NATIVE_METHOD(TestJniMacros, v_lib, "(JIZ)V", v_lib_od);
1264 CRITICAL_NATIVE_METHOD_AUTOSIG(TestJniMacros, v_lib);
1265
1266 MAKE_JNI_FAST_NATIVE_METHOD("v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
1267 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG("v_eolib", TestJniMacros_v_eolib);
1268 FAST_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V");
1269 OVERLOADED_FAST_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V", v_eolib_od);
1270 FAST_NATIVE_METHOD_AUTOSIG(TestJniMacros, v_eolib);
1271
1272 MAKE_JNI_NATIVE_METHOD("v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
1273 MAKE_JNI_NATIVE_METHOD_AUTOSIG("v_eolib", TestJniMacros_v_eolib);
1274 NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V");
1275 OVERLOADED_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V", v_eolib_od);
1276 NATIVE_METHOD_AUTOSIG(TestJniMacros, v_eolib);
1277
1278 _NATIVEHELPER_JNI_MAKE_METHOD_OLD(kNormalNative, "v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
1279 tmp_native_method =
1280 _NATIVEHELPER_JNI_MAKE_METHOD_OLD(kNormalNative, "v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
1281 }
1282