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