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