1 /*
2  * Copyright (C) 2009 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 /*
18  * Native implementation for the StaticNonce class. See the test code
19  * in JniStaticTest for more info.
20  */
21 
22 #include <jni.h>
23 #include <nativehelper/JNIHelp.h>
24 
25 #include <stdbool.h>
26 #include <string.h>
27 
28 // public static native void nop();
StaticNonce_nop(JNIEnv * env,jclass clazz)29 static void StaticNonce_nop(JNIEnv *env, jclass clazz) {
30     // This space intentionally left blank.
31 }
32 
33 // public static native boolean returnBoolean();
StaticNonce_returnBoolean(JNIEnv * env,jclass clazz)34 static jboolean StaticNonce_returnBoolean(JNIEnv *env, jclass clazz) {
35     return (jboolean) true;
36 }
37 
38 // public static native byte returnByte();
StaticNonce_returnByte(JNIEnv * env,jclass clazz)39 static jbyte StaticNonce_returnByte(JNIEnv *env, jclass clazz) {
40     return (jbyte) 123;
41 }
42 
43 // public static native short returnShort();
StaticNonce_returnShort(JNIEnv * env,jclass clazz)44 static jshort StaticNonce_returnShort(JNIEnv *env, jclass clazz) {
45     return (jshort) -12345;
46 }
47 
48 // public static native char returnChar();
StaticNonce_returnChar(JNIEnv * env,jclass clazz)49 static jchar StaticNonce_returnChar(JNIEnv *env, jclass clazz) {
50     return (jchar) 34567;
51 }
52 
53 // public static native int returnInt();
StaticNonce_returnInt(JNIEnv * env,jclass clazz)54 static jint StaticNonce_returnInt(JNIEnv *env, jclass clazz) {
55     return 12345678;
56 }
57 
58 // public static native long returnLong();
StaticNonce_returnLong(JNIEnv * env,jclass clazz)59 static jlong StaticNonce_returnLong(JNIEnv *env, jclass clazz) {
60     return (jlong) -1098765432109876543LL;
61 }
62 
63 // public static native float returnFloat();
StaticNonce_returnFloat(JNIEnv * env,jclass clazz)64 static jfloat StaticNonce_returnFloat(JNIEnv *env, jclass clazz) {
65     return (jfloat) -98765.4321F;
66 }
67 
68 // public static native double returnDouble();
StaticNonce_returnDouble(JNIEnv * env,jclass clazz)69 static jdouble StaticNonce_returnDouble(JNIEnv *env, jclass clazz) {
70     return 12345678.9;
71 }
72 
73 // public static native Object returnNull();
StaticNonce_returnNull(JNIEnv * env,jclass clazz)74 static jobject StaticNonce_returnNull(JNIEnv *env, jclass clazz) {
75     return NULL;
76 }
77 
78 // public static native String returnString();
StaticNonce_returnString(JNIEnv * env,jclass clazz)79 static jstring StaticNonce_returnString(JNIEnv *env, jclass clazz) {
80     return (*env)->NewStringUTF(env, "blort");
81 }
82 
83 // public static native short[] returnShortArray();
StaticNonce_returnShortArray(JNIEnv * env,jclass clazz)84 static jshortArray StaticNonce_returnShortArray(JNIEnv *env, jclass clazz) {
85     static jshort contents[] = { 10, 20, 30 };
86 
87     jshortArray result = (*env)->NewShortArray(env, 3);
88 
89     if (result == NULL) {
90         return NULL;
91     }
92 
93     (*env)->SetShortArrayRegion(env, result, 0, 3, contents);
94     return result;
95 }
96 
97 // public static native String[] returnStringArray();
StaticNonce_returnStringArray(JNIEnv * env,jclass clazz)98 static jobjectArray StaticNonce_returnStringArray(JNIEnv *env, jclass clazz) {
99     static int indices[] = { 0, 50, 99 };
100     static const char *contents[] = { "blort", "zorch", "fizmo" };
101 
102     jclass stringClass = (*env)->FindClass(env, "java/lang/String");
103 
104     if ((*env)->ExceptionOccurred(env) != NULL) {
105         return NULL;
106     }
107 
108     if (stringClass == NULL) {
109         jniThrowException(env, "java/lang/AssertionError",
110                 "class String not found");
111         return NULL;
112     }
113 
114     jobjectArray result = (*env)->NewObjectArray(env, 100, stringClass, NULL);
115 
116     if (result == NULL) {
117         return NULL;
118     }
119 
120     jsize i;
121     for (i = 0; i < 3; i++) {
122         jstring s = (*env)->NewStringUTF(env, contents[i]);
123 
124         if (s == NULL) {
125             return NULL;
126         }
127 
128         (*env)->SetObjectArrayElement(env, result, indices[i], s);
129 
130         if ((*env)->ExceptionOccurred(env) != NULL) {
131             return NULL;
132         }
133     }
134 
135     return result;
136 }
137 
138 // public static native Class returnThisClass();
StaticNonce_returnThisClass(JNIEnv * env,jclass clazz)139 static jclass StaticNonce_returnThisClass(JNIEnv *env, jclass clazz) {
140     return clazz;
141 }
142 
143 // public static native StaticNonce returnInstance();
StaticNonce_returnInstance(JNIEnv * env,jclass clazz)144 static jobject StaticNonce_returnInstance(JNIEnv *env, jclass clazz) {
145     jmethodID id = (*env)->GetMethodID(env, clazz, "<init>", "()V");
146 
147     if ((*env)->ExceptionOccurred(env) != NULL) {
148         return NULL;
149     }
150 
151     if (id == NULL) {
152         jniThrowException(env, "java/lang/AssertionError",
153                 "constructor not found");
154         return NULL;
155     }
156 
157     return (*env)->NewObjectA(env, clazz, id, NULL);
158 }
159 
160 // public static native boolean takeBoolean(boolean v);
StaticNonce_takeBoolean(JNIEnv * env,jclass clazz,jboolean v)161 static jboolean StaticNonce_takeBoolean(JNIEnv *env, jclass clazz,
162         jboolean v) {
163     return v == true;
164 }
165 
166 // public static native boolean takeByte(byte v);
StaticNonce_takeByte(JNIEnv * env,jclass clazz,jbyte v)167 static jboolean StaticNonce_takeByte(JNIEnv *env, jclass clazz, jbyte v) {
168     return v == -99;
169 }
170 
171 // public static native boolean takeShort(short v);
StaticNonce_takeShort(JNIEnv * env,jclass clazz,jshort v)172 static jboolean StaticNonce_takeShort(JNIEnv *env, jclass clazz, jshort v) {
173     return v == 19991;
174 }
175 
176 // public static native boolean takeChar(char v);
StaticNonce_takeChar(JNIEnv * env,jclass clazz,jchar v)177 static jboolean StaticNonce_takeChar(JNIEnv *env, jclass clazz, jchar v) {
178     return v == 999;
179 }
180 
181 // public static native boolean takeInt(int v);
StaticNonce_takeInt(JNIEnv * env,jclass clazz,jint v)182 static jboolean StaticNonce_takeInt(JNIEnv *env, jclass clazz, jint v) {
183     return v == -999888777;
184 }
185 
186 // public static native boolean takeLong(long v);
StaticNonce_takeLong(JNIEnv * env,jclass clazz,jlong v)187 static jboolean StaticNonce_takeLong(JNIEnv *env, jclass clazz, jlong v) {
188     return v == 999888777666555444LL;
189 }
190 
191 // public static native boolean takeFloat(float v);
StaticNonce_takeFloat(JNIEnv * env,jclass clazz,jfloat v)192 static jboolean StaticNonce_takeFloat(JNIEnv *env, jclass clazz, jfloat v) {
193     return v == -9988.7766F;
194 }
195 
196 // public static native boolean takeDouble(double v);
StaticNonce_takeDouble(JNIEnv * env,jclass clazz,jdouble v)197 static jboolean StaticNonce_takeDouble(JNIEnv *env, jclass clazz, jdouble v) {
198     return v == 999888777.666555;
199 }
200 
201 // public static native boolean takeNull(Object v);
StaticNonce_takeNull(JNIEnv * env,jclass clazz,jobject v)202 static jboolean StaticNonce_takeNull(JNIEnv *env, jclass clazz, jobject v) {
203     return v == NULL;
204 }
205 
206 // public static native boolean takeString(String v);
StaticNonce_takeString(JNIEnv * env,jclass clazz,jstring v)207 static jboolean StaticNonce_takeString(JNIEnv *env, jclass clazz, jstring v) {
208     if (v == NULL) {
209         return false;
210     }
211 
212     const char *utf = (*env)->GetStringUTFChars(env, v, NULL);
213     jboolean result = (strcmp("fuzzbot", utf) == 0);
214 
215     (*env)->ReleaseStringUTFChars(env, v, utf);
216     return result;
217 }
218 
219 // public static native boolean takeThisClass(Class v);
StaticNonce_takeThisClass(JNIEnv * env,jclass clazz,jclass v)220 static jboolean StaticNonce_takeThisClass(JNIEnv *env, jclass clazz,
221         jclass v) {
222     return (*env)->IsSameObject(env, clazz, v);
223 }
224 
225 // public static native boolean takeIntLong(int v1, long v2);
StaticNonce_takeIntLong(JNIEnv * env,jclass clazz,jint v1,jlong v2)226 static jboolean StaticNonce_takeIntLong(JNIEnv *env, jclass clazz,
227         jint v1, jlong v2) {
228     return (v1 == 914) && (v2 == 9140914091409140914LL);
229 }
230 
231 // public static native boolean takeLongInt(long v1, int v2);
StaticNonce_takeLongInt(JNIEnv * env,jclass clazz,jlong v1,jint v2)232 static jboolean StaticNonce_takeLongInt(JNIEnv *env, jclass clazz,
233         jlong v1, jint v2) {
234     return (v1 == -4321LL) && (v2 == 12341234);
235 }
236 
237 // public static native boolean takeOneOfEach(boolean v0, byte v1, short v2,
238 //         char v3, int v4, long v5, String v6, float v7, double v8,
239 //         int[] v9);
StaticNonce_takeOneOfEach(JNIEnv * env,jclass clazz,jboolean v0,jbyte v1,jshort v2,jchar v3,jint v4,jlong v5,jstring v6,jfloat v7,jdouble v8,jintArray v9)240 static jboolean StaticNonce_takeOneOfEach(JNIEnv *env, jclass clazz,
241         jboolean v0, jbyte v1, jshort v2, jchar v3, jint v4, jlong v5,
242         jstring v6, jfloat v7, jdouble v8, jintArray v9) {
243     jsize length;
244     jboolean result;
245 
246     if ((v0 != false) || (v1 != 1) || (v2 != 2) || (v3 != 3) ||
247             (v4 != 4) || (v5 != 5) || (v7 != 7.0f) || (v8 != 8.0)) {
248         return false;
249     }
250 
251     length = (*env)->GetStringUTFLength(env, v6);
252 
253     if (length != 3) {
254         jniThrowException(env, "java/lang/AssertionError",
255                 "bad string length");
256         return false;
257     }
258 
259     const char *utf = (*env)->GetStringUTFChars(env, v6, NULL);
260     result = (strncmp("six", utf, 3) == 0);
261 
262     (*env)->ReleaseStringUTFChars(env, v6, utf);
263 
264     if (! result) {
265         return false;
266     }
267 
268     length = (*env)->GetArrayLength(env, v9);
269     if (length != 2) {
270         jniThrowException(env, "java/lang/AssertionError",
271                 "bad array length");
272         return false;
273     }
274 
275     jint *elements = (*env)->GetIntArrayElements(env, v9, NULL);
276     result = (elements[0] == 9) && (elements[1] == 10);
277     (*env)->ReleaseIntArrayElements(env, v9, elements, JNI_ABORT);
278 
279     return result;
280 }
281 
282 // public static native boolean takeCoolHandLuke(
283 //         int v1, int v2, int v3, int v4,
284 //         int v5, int v6, int v7, int v8, int v9,
285 //         int v10, int v11, int v12, int v13, int v14,
286 //         int v15, int v16, int v17, int v18, int v19,
287 //         int v20, int v21, int v22, int v23, int v24,
288 //         int v25, int v26, int v27, int v28, int v29,
289 //         int v30, int v31, int v32, int v33, int v34,
290 //         int v35, int v36, int v37, int v38, int v39,
291 //         int v40, int v41, int v42, int v43, int v44,
292 //         int v45, int v46, int v47, int v48, int v49,
293 //         int v50);
StaticNonce_takeCoolHandLuke(JNIEnv * env,jclass clazz,jint v1,jint v2,jint v3,jint v4,jint v5,jint v6,jint v7,jint v8,jint v9,jint v10,jint v11,jint v12,jint v13,jint v14,jint v15,jint v16,jint v17,jint v18,jint v19,jint v20,jint v21,jint v22,jint v23,jint v24,jint v25,jint v26,jint v27,jint v28,jint v29,jint v30,jint v31,jint v32,jint v33,jint v34,jint v35,jint v36,jint v37,jint v38,jint v39,jint v40,jint v41,jint v42,jint v43,jint v44,jint v45,jint v46,jint v47,jint v48,jint v49,jint v50)294 static jboolean StaticNonce_takeCoolHandLuke(JNIEnv *env, jclass clazz,
295         jint v1, jint v2, jint v3, jint v4,
296         jint v5, jint v6, jint v7, jint v8, jint v9,
297         jint v10, jint v11, jint v12, jint v13, jint v14,
298         jint v15, jint v16, jint v17, jint v18, jint v19,
299         jint v20, jint v21, jint v22, jint v23, jint v24,
300         jint v25, jint v26, jint v27, jint v28, jint v29,
301         jint v30, jint v31, jint v32, jint v33, jint v34,
302         jint v35, jint v36, jint v37, jint v38, jint v39,
303         jint v40, jint v41, jint v42, jint v43, jint v44,
304         jint v45, jint v46, jint v47, jint v48, jint v49,
305         jint v50) {
306     return (v1 == 1) && (v2 == 2) && (v3 == 3) &&
307         (v4 == 4) && (v5 == 5) && (v6 == 6) && (v7 == 7) &&
308         (v8 == 8) && (v9 == 9) &&
309         (v10 == 10) && (v11 == 11) && (v12 == 12) && (v13 == 13) &&
310         (v14 == 14) && (v15 == 15) && (v16 == 16) && (v17 == 17) &&
311         (v18 == 18) && (v19 == 19) &&
312         (v20 == 20) && (v21 == 21) && (v22 == 22) && (v23 == 23) &&
313         (v24 == 24) && (v25 == 25) && (v26 == 26) && (v27 == 27) &&
314         (v28 == 28) && (v29 == 29) &&
315         (v30 == 30) && (v31 == 31) && (v32 == 32) && (v33 == 33) &&
316         (v34 == 34) && (v35 == 35) && (v36 == 36) && (v37 == 37) &&
317         (v38 == 38) && (v39 == 39) &&
318         (v40 == 40) && (v41 == 41) && (v42 == 42) && (v43 == 43) &&
319         (v44 == 44) && (v45 == 45) && (v46 == 46) && (v47 == 47) &&
320         (v48 == 48) && (v49 == 49) &&
321         (v50 == 50);
322 }
323 
324 static JNINativeMethod methods[] = {
325     // name, signature, function
326     { "nop",               "()V", StaticNonce_nop },
327     { "returnBoolean",     "()Z", StaticNonce_returnBoolean },
328     { "returnByte",        "()B", StaticNonce_returnByte },
329     { "returnShort",       "()S", StaticNonce_returnShort },
330     { "returnChar",        "()C", StaticNonce_returnChar },
331     { "returnInt",         "()I", StaticNonce_returnInt },
332     { "returnLong",        "()J", StaticNonce_returnLong },
333     { "returnFloat",       "()F", StaticNonce_returnFloat },
334     { "returnDouble",      "()D", StaticNonce_returnDouble },
335     { "returnNull",        "()Ljava/lang/Object;", StaticNonce_returnNull },
336     { "returnString",      "()Ljava/lang/String;", StaticNonce_returnString },
337     { "returnShortArray",  "()[S", StaticNonce_returnShortArray },
338     { "returnStringArray", "()[Ljava/lang/String;",
339       StaticNonce_returnStringArray },
340     { "returnThisClass",   "()Ljava/lang/Class;",
341       StaticNonce_returnThisClass },
342     { "returnInstance",    "()Landroid/jni/cts/StaticNonce;",
343       StaticNonce_returnInstance },
344     { "takeBoolean",       "(Z)Z", StaticNonce_takeBoolean },
345     { "takeByte",          "(B)Z", StaticNonce_takeByte },
346     { "takeShort",         "(S)Z", StaticNonce_takeShort },
347     { "takeChar",          "(C)Z", StaticNonce_takeChar },
348     { "takeInt",           "(I)Z", StaticNonce_takeInt },
349     { "takeLong",          "(J)Z", StaticNonce_takeLong },
350     { "takeFloat",         "(F)Z", StaticNonce_takeFloat },
351     { "takeDouble",        "(D)Z", StaticNonce_takeDouble },
352     { "takeNull",          "(Ljava/lang/Object;)Z", StaticNonce_takeNull },
353     { "takeString",        "(Ljava/lang/String;)Z", StaticNonce_takeString },
354     { "takeThisClass",     "(Ljava/lang/Class;)Z", StaticNonce_takeThisClass },
355     { "takeIntLong",       "(IJ)Z", StaticNonce_takeIntLong },
356     { "takeLongInt",       "(JI)Z", StaticNonce_takeLongInt },
357     { "takeOneOfEach",     "(ZBSCIJLjava/lang/String;FD[I)Z",
358       StaticNonce_takeOneOfEach },
359     { "takeCoolHandLuke",
360       "(IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII)Z",
361       StaticNonce_takeCoolHandLuke },
362 };
363 
register_StaticNonce(JNIEnv * env)364 int register_StaticNonce(JNIEnv *env) {
365     return jniRegisterNativeMethods(
366             env, "android/jni/cts/StaticNonce",
367             methods, sizeof(methods) / sizeof(JNINativeMethod));
368 }
369