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