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