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 package android.jni.cts;
18 
19 import android.os.Build;
20 import android.os.Process;
21 
22 import com.android.compatibility.common.util.PropertyUtil;
23 
24 import java.io.File;
25 import java.io.IOException;
26 
27 /**
28  * Basic static method tests. The "nonce" class being tested by this
29  * class is a class defined in this package that declares the bulk of
30  * its methods as native.
31  */
32 public class JniStaticTest extends JniTestCase {
33 
34     static {
35         if (!JniTestCase.isCpuAbiNone()) {
36             System.loadLibrary("jnitest");
37         }
38     }
39 
40     /**
41      * Test library accessibility. Internal platform libraries should not
42      * be accessible from the jni code.
43      */
test_linker_namespaces()44     public void test_linker_namespaces() throws IOException {
45         String error = LinkerNamespacesHelper.runAccessibilityTest();
46         if (error != null) {
47             fail(error);
48         }
49     }
50 
test_linker_namespaces_classloaders()51     public void test_linker_namespaces_classloaders() throws Exception {
52         String error = LinkerNamespacesHelper.runClassLoaderNamespaces();
53         if (error != null) {
54             fail(error);
55         }
56     }
57 
test_loader_basic()58     public void test_loader_basic() throws Exception {
59         String error = BasicLoaderTestHelper.nativeRunTests();
60         if (error != null) {
61             fail(error);
62         }
63     }
64 
65     /**
66      * Test that accessing classes true JNI works as expected. b/19382130
67      */
test_classload()68     public void test_classload() {
69         // Use an independent class to do this.
70         assertEquals(true, ClassLoaderHelper.run());
71     }
72 
73     /**
74      * Test native method call without implementation.
75      */
test_missing()76     public void test_missing() {
77         try {
78             StaticNonce.missing();
79             throw new Error("Unreachable");
80         } catch (UnsatisfiedLinkError expected) {
81         }
82     }
test_missingFast()83     public void test_missingFast() {
84         try {
85             StaticNonce.missingFast();
86             throw new Error("Unreachable");
87         } catch (UnsatisfiedLinkError expected) {
88         }
89     }
test_missingCritical()90     public void test_missingCritical() {
91         try {
92             StaticNonce.missingCritical();
93             throw new Error("Unreachable");
94         } catch (UnsatisfiedLinkError expected) {
95         }
96     }
97 
98     /**
99      * Test a simple no-op and void-returning method call.
100      *
101      * The "Dlsym" versions use dynamic lookup instead of explicitly
102      * registering the native method implementation.
103      */
test_nop()104     public void test_nop() {
105         StaticNonce.nop();
106     }
test_nopDlsym()107     public void test_nopDlsym() {
108         StaticNonce.nopDlsym();
109     }
test_nopFast()110     public void test_nopFast() {
111         StaticNonce.nopFast();
112     }
test_nopFastDlsym()113     public void test_nopFastDlsym() {
114         StaticNonce.nopFastDlsym();
115     }
test_nopCritical()116     public void test_nopCritical() {
117         StaticNonce.nopCritical();
118     }
test_nopCriticalDlsym()119     public void test_nopCriticalDlsym() {
120         StaticNonce.nopCriticalDlsym();
121     }
122 
123     /**
124      * Test a simple value-returning (but otherwise no-op) method call.
125      */
test_returnBoolean()126     public void test_returnBoolean() {
127         assertEquals(true, StaticNonce.returnBoolean());
128     }
test_returnBooleanFast()129     public void test_returnBooleanFast() {
130         assertEquals(true, StaticNonce.returnBooleanFast());
131     }
test_returnBooleanCritical()132     public void test_returnBooleanCritical() {
133         assertEquals(true, StaticNonce.returnBooleanCritical());
134     }
135 
136     /**
137      * Test a simple value-returning (but otherwise no-op) method call.
138      */
test_returnByte()139     public void test_returnByte() {
140         assertEquals(123, StaticNonce.returnByte());
141     }
test_returnByteFast()142     public void test_returnByteFast() {
143         assertEquals(123, StaticNonce.returnByteFast());
144     }
test_returnByteCritical()145     public void test_returnByteCritical() {
146         assertEquals(123, StaticNonce.returnByteCritical());
147     }
148 
149     /**
150      * Test a simple value-returning (but otherwise no-op) method call.
151      */
test_returnShort()152     public void test_returnShort() {
153         assertEquals(-12345, StaticNonce.returnShort());
154     }
test_returnShortFast()155     public void test_returnShortFast() {
156         assertEquals(-12345, StaticNonce.returnShortFast());
157     }
test_returnShortCritical()158     public void test_returnShortCritical() {
159         assertEquals(-12345, StaticNonce.returnShortCritical());
160     }
161 
162     /**
163      * Test a simple value-returning (but otherwise no-op) method call.
164      */
test_returnChar()165     public void test_returnChar() {
166         assertEquals(34567, StaticNonce.returnChar());
167     }
test_returnCharFast()168     public void test_returnCharFast() {
169         assertEquals(34567, StaticNonce.returnCharFast());
170     }
test_returnCharCritical()171     public void test_returnCharCritical() {
172         assertEquals(34567, StaticNonce.returnCharCritical());
173     }
174 
175     /**
176      * Test a simple value-returning (but otherwise no-op) method call.
177      */
test_returnInt()178     public void test_returnInt() {
179         assertEquals(12345678, StaticNonce.returnInt());
180     }
test_returnIntFast()181     public void test_returnIntFast() {
182         assertEquals(12345678, StaticNonce.returnIntFast());
183     }
test_returnIntCritical()184     public void test_returnIntCritical() {
185         assertEquals(12345678, StaticNonce.returnIntCritical());
186     }
187 
188     /**
189      * Test a simple value-returning (but otherwise no-op) method call.
190      */
test_returnLong()191     public void test_returnLong() {
192         assertEquals(-1098765432109876543L, StaticNonce.returnLong());
193     }
test_returnLongFast()194     public void test_returnLongFast() {
195         assertEquals(-1098765432109876543L, StaticNonce.returnLongFast());
196     }
test_returnLongCritical()197     public void test_returnLongCritical() {
198         assertEquals(-1098765432109876543L, StaticNonce.returnLongCritical());
199     }
200 
201     /**
202      * Test a simple value-returning (but otherwise no-op) method call.
203      */
test_returnFloat()204     public void test_returnFloat() {
205         assertEquals(-98765.4321F, StaticNonce.returnFloat());
206     }
test_returnFloatFast()207     public void test_returnFloatFast() {
208         assertEquals(-98765.4321F, StaticNonce.returnFloatFast());
209     }
test_returnFloatCritical()210     public void test_returnFloatCritical() {
211         assertEquals(-98765.4321F, StaticNonce.returnFloatCritical());
212     }
213 
214     /**
215      * Test a simple value-returning (but otherwise no-op) method call.
216      */
test_returnDouble()217     public void test_returnDouble() {
218         assertEquals(12345678.9, StaticNonce.returnDouble());
219     }
test_returnDoubleFast()220     public void test_returnDoubleFast() {
221         assertEquals(12345678.9, StaticNonce.returnDoubleFast());
222     }
test_returnDoubleCritical()223     public void test_returnDoubleCritical() {
224         assertEquals(12345678.9, StaticNonce.returnDoubleCritical());
225     }
226 
227     /**
228      * Test a simple value-returning (but otherwise no-op) method call.
229      */
test_returnNull()230     public void test_returnNull() {
231         assertNull(StaticNonce.returnNull());
232     }
test_returnNullFast()233     public void test_returnNullFast() {
234         assertNull(StaticNonce.returnNullFast());
235     }
236 
237     /**
238      * Test a simple value-returning (but otherwise no-op) method call.
239      */
test_returnString()240     public void test_returnString() {
241         assertEquals("blort", StaticNonce.returnString());
242     }
test_returnStringFast()243     public void test_returnStringFast() {
244         assertEquals("blort", StaticNonce.returnStringFast());
245     }
246 
247     /**
248      * Test a simple value-returning (but otherwise no-op) method call.
249      */
test_returnShortArray()250     public void test_returnShortArray() {
251         checkShortArray(StaticNonce.returnShortArray());
252     }
test_returnShortArrayFast()253     public void test_returnShortArrayFast() {
254         checkShortArray(StaticNonce.returnShortArrayFast());
255     }
checkShortArray(short[] array)256     private void checkShortArray(short[] array) {
257         assertSame(short[].class, array.getClass());
258         assertEquals(3, array.length);
259         assertEquals(10, array[0]);
260         assertEquals(20, array[1]);
261         assertEquals(30, array[2]);
262     }
263 
264     /**
265      * Test a simple value-returning (but otherwise no-op) method call.
266      */
test_returnStringArray()267     public void test_returnStringArray() {
268         checkStringArray(StaticNonce.returnStringArray());
269     }
test_returnStringArrayFast()270     public void test_returnStringArrayFast() {
271         checkStringArray(StaticNonce.returnStringArrayFast());
272     }
checkStringArray(String[] array)273     private void checkStringArray(String[] array) {
274         assertSame(String[].class, array.getClass());
275         assertEquals(100, array.length);
276         assertEquals("blort", array[0]);
277         assertEquals(null,    array[1]);
278         assertEquals("zorch", array[50]);
279         assertEquals("fizmo", array[99]);
280     }
281 
282     /**
283      * Test a simple value-returning (but otherwise no-op) method call,
284      * that returns the class that the method is defined on.
285      */
test_returnThisClass()286     public void test_returnThisClass() {
287         assertSame(StaticNonce.class, StaticNonce.returnThisClass());
288     }
test_returnThisClassFast()289     public void test_returnThisClassFast() {
290         assertSame(StaticNonce.class, StaticNonce.returnThisClassFast());
291     }
292 
293     /**
294      * Test a simple value-returning (but otherwise no-op) method call,
295      * that returns the class that the method is defined on.
296      */
test_returnInstance()297     public void test_returnInstance() {
298         StaticNonce nonce = StaticNonce.returnInstance();
299         assertSame(StaticNonce.class, nonce.getClass());
300     }
test_returnInstanceFast()301     public void test_returnInstanceFast() {
302         StaticNonce nonce = StaticNonce.returnInstanceFast();
303         assertSame(StaticNonce.class, nonce.getClass());
304     }
305 
306     /**
307      * Test a simple value-taking method call, that returns whether it
308      * got the expected value.
309      */
test_takeBoolean()310     public void test_takeBoolean() {
311         assertTrue(StaticNonce.takeBoolean(true));
312     }
test_takeBooleanFast()313     public void test_takeBooleanFast() {
314         assertTrue(StaticNonce.takeBooleanFast(true));
315     }
test_takeBooleanCritical()316     public void test_takeBooleanCritical() {
317         assertTrue(StaticNonce.takeBooleanCritical(true));
318     }
319 
320     /**
321      * Test a simple value-taking method call, that returns whether it
322      * got the expected value.
323      */
test_takeByte()324     public void test_takeByte() {
325         assertTrue(StaticNonce.takeByte((byte) -99));
326     }
test_takeByteFast()327     public void test_takeByteFast() {
328         assertTrue(StaticNonce.takeByteFast((byte) -99));
329     }
test_takeByteCritical()330     public void test_takeByteCritical() {
331         assertTrue(StaticNonce.takeByteCritical((byte) -99));
332     }
333 
334     /**
335      * Test a simple value-taking method call, that returns whether it
336      * got the expected value.
337      */
test_takeShort()338     public void test_takeShort() {
339         assertTrue(StaticNonce.takeShort((short) 19991));
340     }
test_takeShortFast()341     public void test_takeShortFast() {
342         assertTrue(StaticNonce.takeShortFast((short) 19991));
343     }
test_takeShortCritical()344     public void test_takeShortCritical() {
345         assertTrue(StaticNonce.takeShortCritical((short) 19991));
346     }
347 
348     /**
349      * Test a simple value-taking method call, that returns whether it
350      * got the expected value.
351      */
test_takeChar()352     public void test_takeChar() {
353         assertTrue(StaticNonce.takeChar((char) 999));
354     }
test_takeCharFast()355     public void test_takeCharFast() {
356         assertTrue(StaticNonce.takeCharFast((char) 999));
357     }
test_takeCharCritical()358     public void test_takeCharCritical() {
359         assertTrue(StaticNonce.takeCharCritical((char) 999));
360     }
361 
362     /**
363      * Test a simple value-taking method call, that returns whether it
364      * got the expected value.
365      */
test_takeInt()366     public void test_takeInt() {
367         assertTrue(StaticNonce.takeInt(-999888777));
368     }
test_takeIntFast()369     public void test_takeIntFast() {
370         assertTrue(StaticNonce.takeIntFast(-999888777));
371     }
test_takeIntCritical()372     public void test_takeIntCritical() {
373         assertTrue(StaticNonce.takeIntCritical(-999888777));
374     }
375 
376     /**
377      * Test a simple value-taking method call, that returns whether it
378      * got the expected value.
379      */
test_takeLong()380     public void test_takeLong() {
381         assertTrue(StaticNonce.takeLong(999888777666555444L));
382     }
test_takeLongFast()383     public void test_takeLongFast() {
384         assertTrue(StaticNonce.takeLongFast(999888777666555444L));
385     }
test_takeLongCritical()386     public void test_takeLongCritical() {
387         assertTrue(StaticNonce.takeLongCritical(999888777666555444L));
388     }
389 
390     /**
391      * Test a simple value-taking method call, that returns whether it
392      * got the expected value.
393      */
test_takeFloat()394     public void test_takeFloat() {
395         assertTrue(StaticNonce.takeFloat(-9988.7766F));
396     }
test_takeFloatFast()397     public void test_takeFloatFast() {
398         assertTrue(StaticNonce.takeFloatFast(-9988.7766F));
399     }
test_takeFloatCritical()400     public void test_takeFloatCritical() {
401         assertTrue(StaticNonce.takeFloatCritical(-9988.7766F));
402     }
403 
404     /**
405      * Test a simple value-taking method call, that returns whether it
406      * got the expected value.
407      */
test_takeDouble()408     public void test_takeDouble() {
409         assertTrue(StaticNonce.takeDouble(999888777.666555));
410     }
test_takeDoubleFast()411     public void test_takeDoubleFast() {
412         assertTrue(StaticNonce.takeDoubleFast(999888777.666555));
413     }
test_takeDoubleCritical()414     public void test_takeDoubleCritical() {
415         assertTrue(StaticNonce.takeDoubleCritical(999888777.666555));
416     }
417 
418     /**
419      * Test a simple value-taking method call, that returns whether it
420      * got the expected value.
421      */
test_takeNull()422     public void test_takeNull() {
423         assertTrue(StaticNonce.takeNull(null));
424     }
test_takeNullFast()425     public void test_takeNullFast() {
426         assertTrue(StaticNonce.takeNullFast(null));
427     }
428 
429     /**
430      * Test a simple value-taking method call, that returns whether it
431      * got the expected value.
432      */
test_takeString()433     public void test_takeString() {
434         assertTrue(StaticNonce.takeString("fuzzbot"));
435     }
test_takeStringFast()436     public void test_takeStringFast() {
437         assertTrue(StaticNonce.takeStringFast("fuzzbot"));
438     }
439 
440     /**
441      * Test a simple value-taking method call, that returns whether it
442      * got the expected value. In particular, this test passes the
443      * class the method is defined on.
444      */
test_takeThisClass()445     public void test_takeThisClass() {
446         assertTrue(StaticNonce.takeThisClass(StaticNonce.class));
447     }
test_takeThisClassFast()448     public void test_takeThisClassFast() {
449         assertTrue(StaticNonce.takeThisClassFast(StaticNonce.class));
450     }
451 
452     /**
453      * Test a simple multiple value-taking method call, that returns whether it
454      * got the expected values.
455      */
test_takeIntLong()456     public void test_takeIntLong() {
457         assertTrue(StaticNonce.takeIntLong(914, 9140914091409140914L));
458     }
test_takeIntLongFast()459     public void test_takeIntLongFast() {
460         assertTrue(StaticNonce.takeIntLongFast(914, 9140914091409140914L));
461     }
test_takeIntLongCritical()462     public void test_takeIntLongCritical() {
463         assertTrue(StaticNonce.takeIntLongCritical(914, 9140914091409140914L));
464     }
465 
466     /**
467      * Test a simple multiple value-taking method call, that returns whether it
468      * got the expected values.
469      */
test_takeLongInt()470     public void test_takeLongInt() {
471         assertTrue(StaticNonce.takeLongInt(-4321L, 12341234));
472     }
test_takeLongIntFast()473     public void test_takeLongIntFast() {
474         assertTrue(StaticNonce.takeLongIntFast(-4321L, 12341234));
475     }
test_takeLongIntCritical()476     public void test_takeLongIntCritical() {
477         assertTrue(StaticNonce.takeLongIntCritical(-4321L, 12341234));
478     }
479 
480     /**
481      * Test a simple multiple value-taking method call, that returns whether it
482      * got the expected values.
483      *
484      * The "Dlsym" versions use dynamic lookup instead of explicitly
485      * registering the native method implementation.
486      */
test_takeOneOfEach()487     public void test_takeOneOfEach() {
488         assertTrue(StaticNonce.takeOneOfEach((boolean) false, (byte) 1,
489                         (short) 2, (char) 3, (int) 4, 5L, "six", 7.0f, 8.0,
490                         new int[] { 9, 10 }));
491     }
test_takeOneOfEachDlsym()492     public void test_takeOneOfEachDlsym() {
493         assertTrue(StaticNonce.takeOneOfEachDlsym((boolean) false,
494                         (byte) 1, (short) 2, (char) 3, (int) 4, 5L, "six",
495                         7.0f, 8.0, new int[] { 9, 10 }));
496     }
test_takeOneOfEachFast()497     public void test_takeOneOfEachFast() {
498         assertTrue(StaticNonce.takeOneOfEachFast((boolean) false, (byte) 1,
499                         (short) 2, (char) 3, (int) 4, 5L, "six", 7.0f, 8.0,
500                         new int[] { 9, 10 }));
501     }
test_takeOneOfEachFastDlsym()502     public void test_takeOneOfEachFastDlsym() {
503         assertTrue(StaticNonce.takeOneOfEachFastDlsym((boolean) false,
504                         (byte) 1, (short) 2, (char) 3, (int) 4, 5L, "six",
505                         7.0f, 8.0, new int[] { 9, 10 }));
506     }
test_takeOneOfEachCritical()507     public void test_takeOneOfEachCritical() {
508         assertTrue(StaticNonce.takeOneOfEachCritical((boolean) false, (byte) 1,
509                         (short) 2, (char) 3, (int) 4, 5L, 6.0f, 7.0));
510     }
test_takeOneOfEachCriticalDlsym()511     public void test_takeOneOfEachCriticalDlsym() {
512         assertTrue(StaticNonce.takeOneOfEachCriticalDlsym((boolean) false,
513                         (byte) 1, (short) 2, (char) 3, (int) 4, 5L, 6.0f,
514                         7.0));
515     }
516 
517     /**
518      * Test a simple multiple value-taking method call, that returns whether it
519      * got the expected values.
520      */
test_takeCoolHandLuke()521     public void test_takeCoolHandLuke() {
522         assertTrue(StaticNonce.takeCoolHandLuke(1, 2, 3, 4, 5, 6, 7, 8, 9,
523                         10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
524                         20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
525                         30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
526                         40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
527                         50));
528     }
test_takeCoolHandLukeFast()529     public void test_takeCoolHandLukeFast() {
530         assertTrue(StaticNonce.takeCoolHandLukeFast(1, 2, 3, 4, 5, 6, 7, 8, 9,
531                         10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
532                         20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
533                         30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
534                         40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
535                         50));
536     }
test_takeCoolHandLukeCritical()537     public void test_takeCoolHandLukeCritical() {
538         assertTrue(StaticNonce.takeCoolHandLukeCritical(
539                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
540                         11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
541                         21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
542                         31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
543                         41, 42, 43, 44, 45, 46, 47, 48, 49, 50));
544     }
545 
test_takeCoolHandLukeWithFloatsCritical()546     public void test_takeCoolHandLukeWithFloatsCritical() {
547         assertTrue(StaticNonce.takeCoolHandLukeWithFloatsCritical(
548                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14));
549     }
550 
551     /**
552      * dlopen(3) any of the public lib via file name (non-absolute path) should succeed.
553      */
test_dlopenPublicLibraries()554     public void test_dlopenPublicLibraries() {
555         if (PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.R)) {
556             String error = LinkerNamespacesHelper.runDlopenPublicLibraries();
557             if (error != null) {
558                 fail(error);
559             }
560         }
561     }
562 
563     /**
564      * If ICU4C native libraries, i.e. libicuuc.so and libicui18n.so, have been moved into APEX,
565      * app with targetSdkVersion < Q can still dlopen the /system/{LIB}/libicuuc.so even though
566      * the file does not exist in the file system. It's done by a redirect in linker.
567      * http://b/121248172
568      *
569      * This test ensures that dlopen fail with a target version SDK of Q or above.
570      */
test_dlopenIcu4cInSystemShouldFail()571     public void test_dlopenIcu4cInSystemShouldFail() {
572         File systemBaseDir = new File("/system/lib" + (Process.is64Bit() ? "64" : ""));
573         String[] libs = new String[] { "libicuuc.so", "libicui18n.so"};
574 
575         for (String lib : libs) {
576             File f = new File(systemBaseDir, lib);
577             assertFalse("The same native library should exist in the Runtime APEX."
578                 + " It should not exist in /system: " + f , f.exists());
579             String error = LinkerNamespacesHelper.tryDlopen(f.toString());
580             assertNotNull("The native library file does not exist in the file system, "
581                 + "but dlopen(" + f + ", RTLD_NOW) succeeds.", error);
582         }
583     }
584 }
585