1 /*
2  * Copyright (C) 2013 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.InvocationHandler;
18 import java.lang.reflect.Method;
19 import java.lang.reflect.Proxy;
20 
21 public class Main {
main(String[] args)22     public static void main(String[] args) {
23         System.loadLibrary("arttest");
24         testFindClassOnAttachedNativeThread();
25         testFindFieldOnAttachedNativeThread();
26         testReflectFieldGetFromAttachedNativeThreadNative();
27         testCallStaticVoidMethodOnSubClass();
28         testGetMirandaMethod();
29         testZeroLengthByteBuffers();
30         testByteMethod();
31         testShortMethod();
32         testBooleanMethod();
33         testCharMethod();
34         testIsAssignableFromOnPrimitiveTypes();
35         testShallowGetCallingClassLoader();
36         testShallowGetStackClass2();
37         testCallNonvirtual();
38         testNewStringObject();
39         testRemoveLocalObject();
40         testProxyGetMethodID();
41     }
42 
testFindClassOnAttachedNativeThread()43     private static native void testFindClassOnAttachedNativeThread();
44 
45     private static boolean testFindFieldOnAttachedNativeThreadField;
46 
testReflectFieldGetFromAttachedNativeThreadNative()47     private static native void testReflectFieldGetFromAttachedNativeThreadNative();
48 
49     public static boolean testReflectFieldGetFromAttachedNativeThreadField;
50 
testFindFieldOnAttachedNativeThread()51     private static void testFindFieldOnAttachedNativeThread() {
52       testFindFieldOnAttachedNativeThreadNative();
53       if (!testFindFieldOnAttachedNativeThreadField) {
54             throw new AssertionError();
55         }
56     }
57 
testFindFieldOnAttachedNativeThreadNative()58     private static native void testFindFieldOnAttachedNativeThreadNative();
59 
testCallStaticVoidMethodOnSubClass()60     private static void testCallStaticVoidMethodOnSubClass() {
61         testCallStaticVoidMethodOnSubClassNative();
62         if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
63             throw new AssertionError();
64         }
65     }
66 
testCallStaticVoidMethodOnSubClassNative()67     private static native void testCallStaticVoidMethodOnSubClassNative();
68 
69     private static class testCallStaticVoidMethodOnSubClass_SuperClass {
70         private static boolean executed = false;
execute()71         private static void execute() {
72             executed = true;
73         }
74     }
75 
76     private static class testCallStaticVoidMethodOnSubClass_SubClass
77         extends testCallStaticVoidMethodOnSubClass_SuperClass {
78     }
79 
testGetMirandaMethodNative()80     private static native Method testGetMirandaMethodNative();
81 
testGetMirandaMethod()82     private static void testGetMirandaMethod() {
83         Method m = testGetMirandaMethodNative();
84         if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) {
85             throw new AssertionError();
86         }
87     }
88 
testZeroLengthByteBuffers()89     private static native void testZeroLengthByteBuffers();
90 
91     private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface {
inAbstract()92         public boolean inAbstract() {
93             return true;
94         }
95     }
96 
97     private static interface testGetMirandaMethod_MirandaInterface {
inInterface()98         public boolean inInterface();
99     }
100 
101     // Test sign-extension for values < 32b
102 
byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10)103     static native byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
104         byte b8, byte b9, byte b10);
105 
testByteMethod()106     private static void testByteMethod() {
107       byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
108       for (int i = 0; i < returns.length; i++) {
109         byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
110             (byte)(-7), (byte)8, (byte)(-9), (byte)10);
111         if (returns[i] != result) {
112           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
113           throw new AssertionError();
114         }
115       }
116     }
117 
removeLocalObject(Object o)118     private static native void removeLocalObject(Object o);
119 
testRemoveLocalObject()120     private static void testRemoveLocalObject() {
121         removeLocalObject(new Object());
122     }
123 
shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10)124     private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
125         short s8, short s9, short s10);
126 
testShortMethod()127     private static void testShortMethod() {
128       short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
129       for (int i = 0; i < returns.length; i++) {
130         short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
131             (short)(-7), (short)8, (short)(-9), (short)10);
132         if (returns[i] != result) {
133           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
134           throw new AssertionError();
135         }
136       }
137     }
138 
139     // Test zero-extension for values < 32b
140 
booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10)141     private static native boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
142         boolean b8, boolean b9, boolean b10);
143 
testBooleanMethod()144     private static void testBooleanMethod() {
145       if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
146         throw new AssertionError();
147       }
148 
149       if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
150         throw new AssertionError();
151       }
152     }
153 
charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10)154     private static native char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
155         char c8, char c9, char c10);
156 
testCharMethod()157     private static void testCharMethod() {
158       char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
159           (char)34000 };
160       for (int i = 0; i < returns.length; i++) {
161         char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
162             (char)3456);
163         if (returns[i] != result) {
164           System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
165           throw new AssertionError();
166         }
167       }
168     }
169 
170     // http://b/16531674
testIsAssignableFromOnPrimitiveTypes()171     private static void testIsAssignableFromOnPrimitiveTypes() {
172       if (!nativeIsAssignableFrom(int.class, Integer.TYPE)) {
173         System.out.println("IsAssignableFrom(int.class, Integer.TYPE) returned false, expected true");
174         throw new AssertionError();
175       }
176 
177       if (!nativeIsAssignableFrom(Integer.TYPE, int.class)) {
178         System.out.println("IsAssignableFrom(Integer.TYPE, int.class) returned false, expected true");
179         throw new AssertionError();
180       }
181     }
182 
nativeIsAssignableFrom(Class<?> from, Class<?> to)183     private static native boolean nativeIsAssignableFrom(Class<?> from, Class<?> to);
184 
testShallowGetCallingClassLoader()185     private static void testShallowGetCallingClassLoader() {
186         nativeTestShallowGetCallingClassLoader();
187     }
188 
nativeTestShallowGetCallingClassLoader()189     private native static void nativeTestShallowGetCallingClassLoader();
190 
testShallowGetStackClass2()191     private static void testShallowGetStackClass2() {
192         nativeTestShallowGetStackClass2();
193     }
194 
nativeTestShallowGetStackClass2()195     private static native void nativeTestShallowGetStackClass2();
196 
testCallNonvirtual()197     private static native void testCallNonvirtual();
198 
testNewStringObject()199     private static native void testNewStringObject();
200 
201     private interface SimpleInterface {
a()202         void a();
203     }
204 
205     private static class DummyInvocationHandler implements InvocationHandler {
invoke(Object proxy, Method method, Object[] args)206         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
207             return null;
208         }
209     }
210 
testProxyGetMethodID()211     private static void testProxyGetMethodID() {
212         InvocationHandler handler = new DummyInvocationHandler();
213         SimpleInterface proxy =
214                 (SimpleInterface) Proxy.newProxyInstance(SimpleInterface.class.getClassLoader(),
215                         new Class[] {SimpleInterface.class}, handler);
216         if (testGetMethodID(SimpleInterface.class) == 0) {
217             throw new AssertionError();
218         }
219         if (testGetMethodID(proxy.getClass()) == 0) {
220             throw new AssertionError();
221         }
222     }
223 
testGetMethodID(Class<?> c)224     private static native long testGetMethodID(Class<?> c);
225 }
226 
227 class JniCallNonvirtualTest {
228     public boolean nonstaticMethodSuperCalled = false;
229     public boolean nonstaticMethodSubCalled = false;
230 
testCallNonvirtual()231     private static native void testCallNonvirtual();
232 
JniCallNonvirtualTest()233     public JniCallNonvirtualTest() {
234         System.out.println("Super.<init>");
235     }
236 
staticMethod()237     public static void staticMethod() {
238         System.out.println("Super.staticMethod");
239     }
240 
nonstaticMethod()241     public void nonstaticMethod() {
242         System.out.println("Super.nonstaticMethod");
243         nonstaticMethodSuperCalled = true;
244     }
245 }
246 
247 class JniCallNonvirtualTestSubclass extends JniCallNonvirtualTest {
248 
JniCallNonvirtualTestSubclass()249     public JniCallNonvirtualTestSubclass() {
250         System.out.println("Subclass.<init>");
251     }
252 
staticMethod()253     public static void staticMethod() {
254         System.out.println("Subclass.staticMethod");
255     }
256 
nonstaticMethod()257     public void nonstaticMethod() {
258         System.out.println("Subclass.nonstaticMethod");
259         nonstaticMethodSubCalled = true;
260     }
261 }
262