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 import java.lang.reflect.Method;
18 import java.lang.System;
19 import java.lang.Exception;
20 
21 // This is named Main as it is a copy of JniTest, so that we can re-use the native implementations
22 // from libarttest.
23 class Main {
main(String[] args)24     public static void main(String[] args) {
25         testFindClassOnAttachedNativeThread();
26         testFindFieldOnAttachedNativeThread();
27         testCallStaticVoidMethodOnSubClass();
28         testGetMirandaMethod();
29         testZeroLengthByteBuffers();
30         testByteMethod();
31         testShortMethod();
32         testBooleanMethod();
33         testCharMethod();
34         testEnvironment();
35         testNewStringObject();
36         testSignalHandler();
37         testGetErrorByLoadInvalidLibrary();
38         testSignalHandlerNotReturn();
39     }
40 
testFindClassOnAttachedNativeThread()41     public static native void testFindClassOnAttachedNativeThread();
42 
43     public static boolean testFindFieldOnAttachedNativeThreadField;
44 
testFindFieldOnAttachedNativeThread()45     public static void testFindFieldOnAttachedNativeThread() {
46       testFindFieldOnAttachedNativeThreadNative();
47       if (!testFindFieldOnAttachedNativeThreadField) {
48             throw new AssertionError();
49         }
50     }
51 
testFindFieldOnAttachedNativeThreadNative()52     private static native void testFindFieldOnAttachedNativeThreadNative();
53 
testCallStaticVoidMethodOnSubClass()54     private static void testCallStaticVoidMethodOnSubClass() {
55         testCallStaticVoidMethodOnSubClassNative();
56         if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
57             throw new AssertionError();
58         }
59     }
60 
testCallStaticVoidMethodOnSubClassNative()61     private static native void testCallStaticVoidMethodOnSubClassNative();
62 
63     private static class testCallStaticVoidMethodOnSubClass_SuperClass {
64         private static boolean executed = false;
execute()65         private static void execute() {
66             executed = true;
67         }
68     }
69 
70     private static class testCallStaticVoidMethodOnSubClass_SubClass
71         extends testCallStaticVoidMethodOnSubClass_SuperClass {
72     }
73 
testGetMirandaMethodNative()74     private static native Method testGetMirandaMethodNative();
75 
testGetMirandaMethod()76     private static void testGetMirandaMethod() {
77         Method m = testGetMirandaMethodNative();
78         if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) {
79             throw new AssertionError();
80         }
81     }
82 
testZeroLengthByteBuffers()83     private static native void testZeroLengthByteBuffers();
84 
85     private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface {
inAbstract()86         public boolean inAbstract() {
87             return true;
88         }
89     }
90 
91     private static interface testGetMirandaMethod_MirandaInterface {
inInterface()92         public boolean inInterface();
93     }
94 
95     // Test sign-extension for values < 32b
96 
byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10)97     native static byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
98         byte b8, byte b9, byte b10);
99 
testByteMethod()100     public static void testByteMethod() {
101       byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
102       for (int i = 0; i < returns.length; i++) {
103         byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
104             (byte)(-7), (byte)8, (byte)(-9), (byte)10);
105         if (returns[i] != result) {
106           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
107           throw new AssertionError();
108         }
109       }
110     }
111 
shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10)112     native static short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
113         short s8, short s9, short s10);
114 
testShortMethod()115     private static void testShortMethod() {
116       short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
117       for (int i = 0; i < returns.length; i++) {
118         short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
119             (short)(-7), (short)8, (short)(-9), (short)10);
120         if (returns[i] != result) {
121           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
122           throw new AssertionError();
123         }
124       }
125     }
126 
127     // Test zero-extension for values < 32b
128 
booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10)129     native static boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
130         boolean b8, boolean b9, boolean b10);
131 
testBooleanMethod()132     public static void testBooleanMethod() {
133       if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
134         throw new AssertionError();
135       }
136 
137       if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
138         throw new AssertionError();
139       }
140     }
141 
charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10)142     native static char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
143         char c8, char c9, char c10);
144 
testCharMethod()145     private static void testCharMethod() {
146       char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
147           (char)34000 };
148       for (int i = 0; i < returns.length; i++) {
149         char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
150             (char)3456);
151         if (returns[i] != result) {
152           System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
153           throw new AssertionError();
154         }
155       }
156     }
157 
testEnvironment()158     private static void testEnvironment() {
159       String osArch = System.getProperty("os.arch");
160       if (!"os.arch".equals(osArch)) {
161         throw new AssertionError("unexpected value for os.arch: " + osArch);
162       }
163       // TODO: improve the build script to get these running as well.
164       // if (!"cpu_abi".equals(Build.CPU_ABI)) {
165       //   throw new AssertionError("unexpected value for cpu_abi");
166       // }
167       // if (!"cpu_abi2".equals(Build.CPU_ABI2)) {
168       //   throw new AssertionError("unexpected value for cpu_abi2");
169       // }
170       // String[] expectedSupportedAbis = {"supported1", "supported2", "supported3"};
171       // if (Arrays.equals(expectedSupportedAbis, Build.SUPPORTED_ABIS)) {
172       //   throw new AssertionError("unexpected value for supported_abis");
173       // }
174     }
175 
testNewStringObject()176     private static native void testNewStringObject();
177 
178     // Test v2 special signal handlers. This uses the native code from 004-SignalTest to cause
179     // a non-managed segfault.
testSignalHandler()180     private static void testSignalHandler() {
181         // This uses code from 004-SignalTest.
182         int x = testSignal();
183         if (x != 1234) {
184             throw new AssertionError();
185         }
186     }
187 
testSignal()188     private static native int testSignal();
189 
190     // Test the path from Java to getError() of NativeBridge.
191     //
192     // Load invalid library 'libinvalid.so' from Java. Library loading will fail since it's
193     // invalid (empty file). ART, NativeLoader actually, calls getError() to dump error message.
194     // After that in Java, catch UnsatisfiedLinkError exception to confirm.
testGetErrorByLoadInvalidLibrary()195     private static void testGetErrorByLoadInvalidLibrary() {
196         System.out.println("Loading invalid library 'libinvalid.so' from Java, which will fail.");
197         try {
198             System.loadLibrary("invalid");
199         } catch (java.lang.UnsatisfiedLinkError e){
200             System.out.println("Catch UnsatisfiedLinkError exception as expected.");
201         }
202     }
203 
testSignalHandlerNotReturn()204     private static native void testSignalHandlerNotReturn();
205 }
206 
207 public class NativeBridgeMain {
main(String[] args)208     static public void main(String[] args) throws Exception {
209         System.out.println("Ready for native bridge tests.");
210 
211         System.loadLibrary(args[0]);
212 
213         Main.main(null);
214     }
215 }
216