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