• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(args[0]);
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         testJniCriticalSectionAndGc();
42         testCallDefaultMethods();
43         String lambda = "λ";
44         testInvokeLambdaMethod(() -> { System.out.println("hi-lambda: " + lambda); });
45         String def = "δ";
46         testInvokeLambdaDefaultMethod(() -> { System.out.println("hi-default " + def + lambda); });
47     }
48 
testCallDefaultMethods()49     private static native void testCallDefaultMethods();
50 
testFindClassOnAttachedNativeThread()51     private static native void testFindClassOnAttachedNativeThread();
52 
53     private static boolean testFindFieldOnAttachedNativeThreadField;
54 
testReflectFieldGetFromAttachedNativeThreadNative()55     private static native void testReflectFieldGetFromAttachedNativeThreadNative();
56 
57     public static boolean testReflectFieldGetFromAttachedNativeThreadField;
58 
testFindFieldOnAttachedNativeThread()59     private static void testFindFieldOnAttachedNativeThread() {
60       testFindFieldOnAttachedNativeThreadNative();
61       if (!testFindFieldOnAttachedNativeThreadField) {
62             throw new AssertionError();
63         }
64     }
65 
testFindFieldOnAttachedNativeThreadNative()66     private static native void testFindFieldOnAttachedNativeThreadNative();
67 
testCallStaticVoidMethodOnSubClass()68     private static void testCallStaticVoidMethodOnSubClass() {
69         testCallStaticVoidMethodOnSubClassNative();
70         if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
71             throw new AssertionError();
72         }
73     }
74 
testCallStaticVoidMethodOnSubClassNative()75     private static native void testCallStaticVoidMethodOnSubClassNative();
76 
77     private static class testCallStaticVoidMethodOnSubClass_SuperClass {
78         private static boolean executed = false;
execute()79         private static void execute() {
80             executed = true;
81         }
82     }
83 
84     private static class testCallStaticVoidMethodOnSubClass_SubClass
85         extends testCallStaticVoidMethodOnSubClass_SuperClass {
86     }
87 
testGetMirandaMethodNative()88     private static native Method testGetMirandaMethodNative();
89 
testGetMirandaMethod()90     private static void testGetMirandaMethod() {
91         Method m = testGetMirandaMethodNative();
92         if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) {
93             throw new AssertionError();
94         }
95     }
96 
testZeroLengthByteBuffers()97     private static native void testZeroLengthByteBuffers();
98 
99     private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface {
inAbstract()100         public boolean inAbstract() {
101             return true;
102         }
103     }
104 
105     private static interface testGetMirandaMethod_MirandaInterface {
inInterface()106         public boolean inInterface();
107     }
108 
109     // Test sign-extension for values < 32b
110 
byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10)111     static native byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
112         byte b8, byte b9, byte b10);
113 
testByteMethod()114     private static void testByteMethod() {
115       byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
116       for (int i = 0; i < returns.length; i++) {
117         byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
118             (byte)(-7), (byte)8, (byte)(-9), (byte)10);
119         if (returns[i] != result) {
120           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
121           throw new AssertionError();
122         }
123       }
124     }
125 
removeLocalObject(Object o)126     private static native void removeLocalObject(Object o);
127 
testRemoveLocalObject()128     private static void testRemoveLocalObject() {
129         removeLocalObject(new Object());
130     }
131 
shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10)132     private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
133         short s8, short s9, short s10);
134 
testShortMethod()135     private static void testShortMethod() {
136       short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
137       for (int i = 0; i < returns.length; i++) {
138         short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
139             (short)(-7), (short)8, (short)(-9), (short)10);
140         if (returns[i] != result) {
141           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
142           throw new AssertionError();
143         }
144       }
145     }
146 
147     // Test zero-extension for values < 32b
148 
booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10)149     private static native boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
150         boolean b8, boolean b9, boolean b10);
151 
testBooleanMethod()152     private static void testBooleanMethod() {
153       if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
154         throw new AssertionError();
155       }
156 
157       if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
158         throw new AssertionError();
159       }
160     }
161 
charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10)162     private static native char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
163         char c8, char c9, char c10);
164 
testCharMethod()165     private static void testCharMethod() {
166       char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
167           (char)34000 };
168       for (int i = 0; i < returns.length; i++) {
169         char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
170             (char)3456);
171         if (returns[i] != result) {
172           System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
173           throw new AssertionError();
174         }
175       }
176     }
177 
178     // http://b/16531674
testIsAssignableFromOnPrimitiveTypes()179     private static void testIsAssignableFromOnPrimitiveTypes() {
180       if (!nativeIsAssignableFrom(int.class, Integer.TYPE)) {
181         System.out.println("IsAssignableFrom(int.class, Integer.TYPE) returned false, expected true");
182         throw new AssertionError();
183       }
184 
185       if (!nativeIsAssignableFrom(Integer.TYPE, int.class)) {
186         System.out.println("IsAssignableFrom(Integer.TYPE, int.class) returned false, expected true");
187         throw new AssertionError();
188       }
189     }
190 
nativeIsAssignableFrom(Class<?> from, Class<?> to)191     private static native boolean nativeIsAssignableFrom(Class<?> from, Class<?> to);
192 
testShallowGetCallingClassLoader()193     private static void testShallowGetCallingClassLoader() {
194         nativeTestShallowGetCallingClassLoader();
195     }
196 
nativeTestShallowGetCallingClassLoader()197     private native static void nativeTestShallowGetCallingClassLoader();
198 
testShallowGetStackClass2()199     private static void testShallowGetStackClass2() {
200         nativeTestShallowGetStackClass2();
201     }
202 
nativeTestShallowGetStackClass2()203     private static native void nativeTestShallowGetStackClass2();
204 
testCallNonvirtual()205     private static native void testCallNonvirtual();
206 
testNewStringObject()207     private static native void testNewStringObject();
208 
209     private interface SimpleInterface {
a()210         void a();
211     }
212 
213     private static class DummyInvocationHandler implements InvocationHandler {
invoke(Object proxy, Method method, Object[] args)214         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
215             return null;
216         }
217     }
218 
testProxyGetMethodID()219     private static void testProxyGetMethodID() {
220         InvocationHandler handler = new DummyInvocationHandler();
221         SimpleInterface proxy =
222                 (SimpleInterface) Proxy.newProxyInstance(SimpleInterface.class.getClassLoader(),
223                         new Class[] {SimpleInterface.class}, handler);
224         if (testGetMethodID(SimpleInterface.class) == 0) {
225             throw new AssertionError();
226         }
227         if (testGetMethodID(proxy.getClass()) == 0) {
228             throw new AssertionError();
229         }
230     }
231 
testGetMethodID(Class<?> c)232     private static native long testGetMethodID(Class<?> c);
233 
234     // Exercise GC and JNI critical sections in parallel.
testJniCriticalSectionAndGc()235     private static void testJniCriticalSectionAndGc() {
236         Thread runGcThread = new Thread(new Runnable() {
237             @Override
238             public void run() {
239                 for (int i = 0; i < 10; ++i) {
240                     Runtime.getRuntime().gc();
241                 }
242             }
243         });
244         Thread jniCriticalThread = new Thread(new Runnable() {
245             @Override
246             public void run() {
247                 final int arraySize = 32;
248                 byte[] array0 = new byte[arraySize];
249                 byte[] array1 = new byte[arraySize];
250                 enterJniCriticalSection(arraySize, array0, array1);
251             }
252         });
253         jniCriticalThread.start();
254         runGcThread.start();
255         try {
256             jniCriticalThread.join();
257             runGcThread.join();
258         } catch (InterruptedException ignored) {}
259     }
260 
enterJniCriticalSection(int arraySize, byte[] array0, byte[] array)261     private static native void enterJniCriticalSection(int arraySize, byte[] array0, byte[] array);
262 
testInvokeLambdaMethod(LambdaInterface iface)263     private static native void testInvokeLambdaMethod(LambdaInterface iface);
264 
testInvokeLambdaDefaultMethod(LambdaInterface iface)265     private static native void testInvokeLambdaDefaultMethod(LambdaInterface iface);
266 }
267 
268 @FunctionalInterface
269 interface LambdaInterface {
sayHi()270   public void sayHi();
sayHiTwice()271   public default void sayHiTwice() {
272     sayHi();
273     sayHi();
274   }
275 }
276 
277 class JniCallNonvirtualTest {
278     public boolean nonstaticMethodSuperCalled = false;
279     public boolean nonstaticMethodSubCalled = false;
280 
testCallNonvirtual()281     private static native void testCallNonvirtual();
282 
JniCallNonvirtualTest()283     public JniCallNonvirtualTest() {
284         System.out.println("Super.<init>");
285     }
286 
staticMethod()287     public static void staticMethod() {
288         System.out.println("Super.staticMethod");
289     }
290 
nonstaticMethod()291     public void nonstaticMethod() {
292         System.out.println("Super.nonstaticMethod");
293         nonstaticMethodSuperCalled = true;
294     }
295 }
296 
297 class JniCallNonvirtualTestSubclass extends JniCallNonvirtualTest {
298 
JniCallNonvirtualTestSubclass()299     public JniCallNonvirtualTestSubclass() {
300         System.out.println("Subclass.<init>");
301     }
302 
staticMethod()303     public static void staticMethod() {
304         System.out.println("Subclass.staticMethod");
305     }
306 
nonstaticMethod()307     public void nonstaticMethod() {
308         System.out.println("Subclass.nonstaticMethod");
309         nonstaticMethodSubCalled = true;
310     }
311 }
312