1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include <jni.h>
20 
21 // Simple testing framework for binary translation.
22 #include "jni_test_main.h"  // NOLINT
23 
24 //------------------------------------------------------------------------------
25 // Test JNI_OnLoad call.
26 
27 static bool gJNIOnLoadCalled = false;
28 
JNI_OnLoad(JavaVM *,void *)29 jint JNI_OnLoad(JavaVM*, void*) {
30   gJNIOnLoadCalled = true;
31   return JNI_VERSION_1_2;
32 }
33 
TEST(JNI,OnLoad)34 TEST(JNI, OnLoad) {
35   EXPECT_TRUE(gJNIOnLoadCalled);
36 }
37 
38 JNIEnv* gEnv;
39 jobject gObj;
40 
test_Ellipsis_Real(JNIEnv * env,jobject obj)41 bool test_Ellipsis_Real(JNIEnv* env, jobject obj) {
42   jclass java_class = env->GetObjectClass(obj);
43   jmethodID arg_test_method = env->GetMethodID(java_class, "jniArgTest", "(JIJIIJ)Z");
44   jboolean res = env->CallBooleanMethod(obj, arg_test_method, 1LL, 2, 3LL, 4, 5, 6LL);
45 
46   jmethodID arg_float_test_method = env->GetMethodID(java_class, "jniFloatArgTest", "(FIFIIF)Z");
47   res &= env->CallBooleanMethod(obj, arg_float_test_method, 1.0f, 2, 3.0f, 4, 5, 6.0f);
48 
49   res &= env->CallNonvirtualBooleanMethod(obj, java_class, arg_test_method, 1LL, 2, 3LL, 4, 5, 6LL);
50   return res;
51 }
52 
53 // We call test_Ellipsis_Real inside these 2 functions in order to test
54 // ellipsis calls when stack is aligned to 8 bytes and when it is not.
55 
test_Ellipsis_F1(JNIEnv * env,jobject obj)56 bool __attribute__((noinline)) test_Ellipsis_F1(JNIEnv* env, jobject obj) {
57   return test_Ellipsis_Real(env, obj);
58 }
59 
test_Ellipsis_F2(JNIEnv * env,jobject obj,int)60 bool __attribute__((noinline)) test_Ellipsis_F2(JNIEnv* env, jobject obj, int /* arg1 */) {
61   return test_Ellipsis_Real(env, obj);
62 }
63 
TEST(JNI,Ellipsis)64 TEST(JNI, Ellipsis) {
65   EXPECT_TRUE(test_Ellipsis_F1(gEnv, gObj));
66   EXPECT_TRUE(test_Ellipsis_F2(gEnv, gObj, 0));
67 }
68 
return42(JNIEnv *,jobject)69 static jint return42(JNIEnv*, jobject) {
70   return 42;
71 }
72 
callJavaIntReturningMethod(const char * method)73 jint callJavaIntReturningMethod(const char* method) {
74   jclass clazz = gEnv->GetObjectClass(gObj);
75   jmethodID caller_method = gEnv->GetMethodID(clazz, method, "()I");
76   return gEnv->CallIntMethod(gObj, caller_method);
77 }
78 
TEST(JNI,RegisterNatives)79 TEST(JNI, RegisterNatives) {
80   JNINativeMethod methods[] = {{"return42", "()I", reinterpret_cast<void*>(&return42)}};
81   jclass clazz = gEnv->GetObjectClass(gObj);
82   gEnv->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[1]));
83   EXPECT_EQ(42, callJavaIntReturningMethod("callReturn42"));
84 }
85 
86 // See comment for NdkTests.wrappersABITest in java part.
TEST(JNI,WrappersABI)87 TEST(JNI, WrappersABI) {
88   jclass java_class = gEnv->GetObjectClass(gObj);
89   jmethodID wrappers_abi_test_method = gEnv->GetMethodID(java_class, "wrappersABITest", "()Z");
90   EXPECT_TRUE(gEnv->CallBooleanMethod(gObj, wrappers_abi_test_method));
91 }
92 
93 //------------------------------------------------------------------------------
94 
Java_com_example_ndk_1tests_NdkTests_returnInt(JNIEnv *,jobject,jint arg)95 extern "C" jint Java_com_example_ndk_1tests_NdkTests_returnInt(JNIEnv*, jobject, jint arg) {
96   return arg;
97 }
98 
99 extern "C" jfloat Java_com_example_ndk_1tests_NdkTests_returnFloat(JNIEnv*, jobject, jfloat arg)
100 #ifdef __arm__
101     // On ARM with 'softfp' these functions are binary interchangeable.
102     __attribute__((alias("Java_com_example_ndk_1tests_NdkTests_returnInt")));
103 #else
104 {
105   return arg;
106 }
107 #endif
108 
Java_com_example_ndk_1tests_NdkTests_runTests(JNIEnv * env,jobject thiz,jstring gtest_list,jstring gtest_filter)109 extern "C" jint Java_com_example_ndk_1tests_NdkTests_runTests(JNIEnv* env,
110                                                               jobject thiz,
111                                                               jstring gtest_list,
112                                                               jstring gtest_filter) {
113   gEnv = env;
114   gObj = thiz;
115 
116   int result = ndk_test::RunAllTests(env, thiz, gtest_list, gtest_filter);
117 
118   gEnv = NULL;
119   gObj = NULL;
120   return result;
121 }
122