1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker package art; 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker import java.lang.ref.Reference; 20*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Constructor; 21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Proxy; 22*795d594fSAndroid Build Coastguard Worker import java.nio.ByteBuffer; 23*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList; 24*795d594fSAndroid Build Coastguard Worker import java.util.Arrays; 25*795d594fSAndroid Build Coastguard Worker import java.util.Base64; 26*795d594fSAndroid Build Coastguard Worker import java.util.Comparator; 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker public class Test912 { run()29*795d594fSAndroid Build Coastguard Worker public static void run() throws Exception { 30*795d594fSAndroid Build Coastguard Worker doTest(); 31*795d594fSAndroid Build Coastguard Worker } 32*795d594fSAndroid Build Coastguard Worker doTest()33*795d594fSAndroid Build Coastguard Worker public static void doTest() throws Exception { 34*795d594fSAndroid Build Coastguard Worker testClass("java.lang.Object"); 35*795d594fSAndroid Build Coastguard Worker testClass("java.lang.String"); 36*795d594fSAndroid Build Coastguard Worker testClass("java.lang.Math"); 37*795d594fSAndroid Build Coastguard Worker testClass("java.util.List"); 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker testClass(getProxyClass()); 40*795d594fSAndroid Build Coastguard Worker 41*795d594fSAndroid Build Coastguard Worker testClass(int.class); 42*795d594fSAndroid Build Coastguard Worker testClass(double[].class); 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker testClassType(int.class); 45*795d594fSAndroid Build Coastguard Worker testClassType(getProxyClass()); 46*795d594fSAndroid Build Coastguard Worker testClassType(Runnable.class); 47*795d594fSAndroid Build Coastguard Worker testClassType(String.class); 48*795d594fSAndroid Build Coastguard Worker testClassType(ArrayList.class); 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker testClassType(int[].class); 51*795d594fSAndroid Build Coastguard Worker testClassType(Runnable[].class); 52*795d594fSAndroid Build Coastguard Worker testClassType(String[].class); 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker testClassFields(Integer.class); 55*795d594fSAndroid Build Coastguard Worker testClassFields(int.class); 56*795d594fSAndroid Build Coastguard Worker testClassFields(String[].class); 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker testClassMethods(Integer.class); 59*795d594fSAndroid Build Coastguard Worker testClassMethods(int.class); 60*795d594fSAndroid Build Coastguard Worker testClassMethods(String[].class); 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker testClassStatus(int.class); 63*795d594fSAndroid Build Coastguard Worker testClassStatus(String[].class); 64*795d594fSAndroid Build Coastguard Worker testClassStatus(Object.class); 65*795d594fSAndroid Build Coastguard Worker testClassStatus(TestForNonInit.class); 66*795d594fSAndroid Build Coastguard Worker try { 67*795d594fSAndroid Build Coastguard Worker System.out.println(TestForInitFail.intValue); 68*795d594fSAndroid Build Coastguard Worker } catch (ExceptionInInitializerError e) { 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker testClassStatus(TestForInitFail.class); 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker testInterfaces(int.class); 73*795d594fSAndroid Build Coastguard Worker testInterfaces(String[].class); 74*795d594fSAndroid Build Coastguard Worker testInterfaces(Object.class); 75*795d594fSAndroid Build Coastguard Worker testInterfaces(InfA.class); 76*795d594fSAndroid Build Coastguard Worker testInterfaces(InfB.class); 77*795d594fSAndroid Build Coastguard Worker testInterfaces(InfC.class); 78*795d594fSAndroid Build Coastguard Worker testInterfaces(ClassA.class); 79*795d594fSAndroid Build Coastguard Worker testInterfaces(ClassB.class); 80*795d594fSAndroid Build Coastguard Worker testInterfaces(ClassC.class); 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker testClassLoader(String.class); 83*795d594fSAndroid Build Coastguard Worker testClassLoader(String[].class); 84*795d594fSAndroid Build Coastguard Worker testClassLoader(InfA.class); 85*795d594fSAndroid Build Coastguard Worker testClassLoader(getProxyClass()); 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker testClassLoaderClasses(); 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker System.out.println(); 90*795d594fSAndroid Build Coastguard Worker 91*795d594fSAndroid Build Coastguard Worker testClassVersion(); 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker System.out.println(); 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker // Use a dedicated thread to have a well-defined current thread. 96*795d594fSAndroid Build Coastguard Worker Thread classEventsThread = new Thread("ClassEvents") { 97*795d594fSAndroid Build Coastguard Worker @Override 98*795d594fSAndroid Build Coastguard Worker public void run() { 99*795d594fSAndroid Build Coastguard Worker try { 100*795d594fSAndroid Build Coastguard Worker testClassEvents(); 101*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 102*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(e); 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker } 105*795d594fSAndroid Build Coastguard Worker }; 106*795d594fSAndroid Build Coastguard Worker classEventsThread.start(); 107*795d594fSAndroid Build Coastguard Worker classEventsThread.join(); 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker // b/146170757 110*795d594fSAndroid Build Coastguard Worker TestRecursiveClassPrepareEvents(); 111*795d594fSAndroid Build Coastguard Worker } 112*795d594fSAndroid Build Coastguard Worker testClass(String className)113*795d594fSAndroid Build Coastguard Worker private static void testClass(String className) throws Exception { 114*795d594fSAndroid Build Coastguard Worker Class<?> base = Class.forName(className); 115*795d594fSAndroid Build Coastguard Worker testClass(base); 116*795d594fSAndroid Build Coastguard Worker } 117*795d594fSAndroid Build Coastguard Worker testClass(Class<?> base)118*795d594fSAndroid Build Coastguard Worker private static void testClass(Class<?> base) throws Exception { 119*795d594fSAndroid Build Coastguard Worker String[] result = getClassSignature(base); 120*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(result)); 121*795d594fSAndroid Build Coastguard Worker int mod = getClassModifiers(base); 122*795d594fSAndroid Build Coastguard Worker if (mod != base.getModifiers()) { 123*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected modifiers: " + base.getModifiers() + " vs " + mod); 124*795d594fSAndroid Build Coastguard Worker } 125*795d594fSAndroid Build Coastguard Worker System.out.println(Integer.toHexString(mod)); 126*795d594fSAndroid Build Coastguard Worker } 127*795d594fSAndroid Build Coastguard Worker testClassType(Class<?> c)128*795d594fSAndroid Build Coastguard Worker private static void testClassType(Class<?> c) throws Exception { 129*795d594fSAndroid Build Coastguard Worker boolean isInterface = isInterface(c); 130*795d594fSAndroid Build Coastguard Worker boolean isArray = isArrayClass(c); 131*795d594fSAndroid Build Coastguard Worker boolean isModifiable = isModifiableClass(c); 132*795d594fSAndroid Build Coastguard Worker System.out.println(c.getName() + " interface=" + isInterface + " array=" + isArray + 133*795d594fSAndroid Build Coastguard Worker " modifiable=" + isModifiable); 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker testClassFields(Class<?> c)136*795d594fSAndroid Build Coastguard Worker private static void testClassFields(Class<?> c) throws Exception { 137*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(getClassFields(c))); 138*795d594fSAndroid Build Coastguard Worker } 139*795d594fSAndroid Build Coastguard Worker testClassMethods(Class<?> c)140*795d594fSAndroid Build Coastguard Worker private static void testClassMethods(Class<?> c) throws Exception { 141*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(getClassMethods(c))); 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker testClassStatus(Class<?> c)144*795d594fSAndroid Build Coastguard Worker private static void testClassStatus(Class<?> c) { 145*795d594fSAndroid Build Coastguard Worker System.out.println(c + " " + Integer.toBinaryString(getClassStatus(c))); 146*795d594fSAndroid Build Coastguard Worker } 147*795d594fSAndroid Build Coastguard Worker testInterfaces(Class<?> c)148*795d594fSAndroid Build Coastguard Worker private static void testInterfaces(Class<?> c) { 149*795d594fSAndroid Build Coastguard Worker System.out.println(c + " " + Arrays.toString(getImplementedInterfaces(c))); 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker IsBootClassLoader(ClassLoader l)152*795d594fSAndroid Build Coastguard Worker private static boolean IsBootClassLoader(ClassLoader l) { 153*795d594fSAndroid Build Coastguard Worker // Hacky check for Android's fake boot classloader. 154*795d594fSAndroid Build Coastguard Worker return l.getClass().getName().equals("java.lang.BootClassLoader"); 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker testClassLoader(Class<?> c)157*795d594fSAndroid Build Coastguard Worker private static void testClassLoader(Class<?> c) { 158*795d594fSAndroid Build Coastguard Worker Object cl = getClassLoader(c); 159*795d594fSAndroid Build Coastguard Worker System.out.println(c + " " + (cl != null ? cl.getClass().getName() : "null")); 160*795d594fSAndroid Build Coastguard Worker if (cl == null) { 161*795d594fSAndroid Build Coastguard Worker if (c.getClassLoader() != null && !IsBootClassLoader(c.getClassLoader())) { 162*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Expected " + c.getClassLoader() + ", but got null."); 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker } else { 165*795d594fSAndroid Build Coastguard Worker if (!(cl instanceof ClassLoader)) { 166*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected \"classloader\": " + cl + " (" + cl.getClass() + 167*795d594fSAndroid Build Coastguard Worker ")"); 168*795d594fSAndroid Build Coastguard Worker } 169*795d594fSAndroid Build Coastguard Worker if (cl != c.getClassLoader()) { 170*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected classloader: " + c.getClassLoader() + " vs " + cl); 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker } 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker testClassLoaderClasses()175*795d594fSAndroid Build Coastguard Worker private static void testClassLoaderClasses() throws Exception { 176*795d594fSAndroid Build Coastguard Worker System.out.println(); 177*795d594fSAndroid Build Coastguard Worker System.out.println("boot <- (B) <- (A,C)"); 178*795d594fSAndroid Build Coastguard Worker ClassLoader cl1 = DexData.create2(DexData.create1()); 179*795d594fSAndroid Build Coastguard Worker Class.forName("B", false, cl1); 180*795d594fSAndroid Build Coastguard Worker Class.forName("A", false, cl1); 181*795d594fSAndroid Build Coastguard Worker printClassLoaderClasses(cl1); 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker System.out.println(); 184*795d594fSAndroid Build Coastguard Worker System.out.println("boot <- (B) <- (A, List)"); 185*795d594fSAndroid Build Coastguard Worker ClassLoader cl2 = DexData.create2(DexData.create1()); 186*795d594fSAndroid Build Coastguard Worker Class.forName("A", false, cl2); 187*795d594fSAndroid Build Coastguard Worker Class.forName("java.util.List", false, cl2); 188*795d594fSAndroid Build Coastguard Worker Class.forName("B", false, cl2.getParent()); 189*795d594fSAndroid Build Coastguard Worker printClassLoaderClasses(cl2); 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker System.out.println(); 192*795d594fSAndroid Build Coastguard Worker System.out.println("boot <- 1+2 (A,B)"); 193*795d594fSAndroid Build Coastguard Worker ClassLoader cl3 = DexData.create12(); 194*795d594fSAndroid Build Coastguard Worker Class.forName("B", false, cl3); 195*795d594fSAndroid Build Coastguard Worker Class.forName("A", false, cl3); 196*795d594fSAndroid Build Coastguard Worker printClassLoaderClasses(cl3); 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker // Check that the boot classloader dumps something non-empty. 199*795d594fSAndroid Build Coastguard Worker ClassLoader boot = ClassLoader.getSystemClassLoader().getParent(); 200*795d594fSAndroid Build Coastguard Worker while (boot.getParent() != null) { 201*795d594fSAndroid Build Coastguard Worker boot = boot.getParent(); 202*795d594fSAndroid Build Coastguard Worker } 203*795d594fSAndroid Build Coastguard Worker 204*795d594fSAndroid Build Coastguard Worker Class<?>[] bootClasses = getClassLoaderClasses(boot); 205*795d594fSAndroid Build Coastguard Worker if (bootClasses.length == 0) { 206*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("No classes initiated by boot classloader."); 207*795d594fSAndroid Build Coastguard Worker } 208*795d594fSAndroid Build Coastguard Worker // Check that at least java.util.List is loaded. 209*795d594fSAndroid Build Coastguard Worker boolean foundList = false; 210*795d594fSAndroid Build Coastguard Worker for (Class<?> c : bootClasses) { 211*795d594fSAndroid Build Coastguard Worker if (c == java.util.List.class) { 212*795d594fSAndroid Build Coastguard Worker foundList = true; 213*795d594fSAndroid Build Coastguard Worker break; 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker } 216*795d594fSAndroid Build Coastguard Worker if (!foundList) { 217*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(bootClasses)); 218*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Could not find class java.util.List."); 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker /** 223*795d594fSAndroid Build Coastguard Worker * base64 encoded class/dex file for 224*795d594fSAndroid Build Coastguard Worker * class Transform { 225*795d594fSAndroid Build Coastguard Worker * public void sayHi() { 226*795d594fSAndroid Build Coastguard Worker * System.out.println("Goodbye"); 227*795d594fSAndroid Build Coastguard Worker * } 228*795d594fSAndroid Build Coastguard Worker * } 229*795d594fSAndroid Build Coastguard Worker */ 230*795d594fSAndroid Build Coastguard Worker private static final byte[] DEX_BYTES = Base64.getDecoder().decode( 231*795d594fSAndroid Build Coastguard Worker "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" + 232*795d594fSAndroid Build Coastguard Worker "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" + 233*795d594fSAndroid Build Coastguard Worker "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" + 234*795d594fSAndroid Build Coastguard Worker "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" + 235*795d594fSAndroid Build Coastguard Worker "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" + 236*795d594fSAndroid Build Coastguard Worker "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" + 237*795d594fSAndroid Build Coastguard Worker "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" + 238*795d594fSAndroid Build Coastguard Worker "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" + 239*795d594fSAndroid Build Coastguard Worker "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" + 240*795d594fSAndroid Build Coastguard Worker "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" + 241*795d594fSAndroid Build Coastguard Worker "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" + 242*795d594fSAndroid Build Coastguard Worker "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" + 243*795d594fSAndroid Build Coastguard Worker "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA="); testClassVersion()244*795d594fSAndroid Build Coastguard Worker private static void testClassVersion() throws Exception { 245*795d594fSAndroid Build Coastguard Worker Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader"); 246*795d594fSAndroid Build Coastguard Worker Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class); 247*795d594fSAndroid Build Coastguard Worker Class target = ((ClassLoader)ctor.newInstance( 248*795d594fSAndroid Build Coastguard Worker ByteBuffer.wrap(DEX_BYTES), Test912.class.getClassLoader())).loadClass("Transform"); 249*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(getClassVersion(target))); 250*795d594fSAndroid Build Coastguard Worker } 251*795d594fSAndroid Build Coastguard Worker testClassEvents()252*795d594fSAndroid Build Coastguard Worker private static void testClassEvents() throws Exception { 253*795d594fSAndroid Build Coastguard Worker ClassLoader cl = Main.class.getClassLoader(); 254*795d594fSAndroid Build Coastguard Worker while (cl.getParent() != null) { 255*795d594fSAndroid Build Coastguard Worker cl = cl.getParent(); 256*795d594fSAndroid Build Coastguard Worker } 257*795d594fSAndroid Build Coastguard Worker final ClassLoader boot = cl; 258*795d594fSAndroid Build Coastguard Worker 259*795d594fSAndroid Build Coastguard Worker // The JIT may deeply inline and load some classes. Preload these for test determinism. 260*795d594fSAndroid Build Coastguard Worker final String PRELOAD_FOR_JIT[] = { 261*795d594fSAndroid Build Coastguard Worker "java.nio.charset.CoderMalfunctionError", 262*795d594fSAndroid Build Coastguard Worker "java.util.NoSuchElementException", 263*795d594fSAndroid Build Coastguard Worker "java.io.FileNotFoundException", // b/63581208 264*795d594fSAndroid Build Coastguard Worker "java.util.zip.ZipException", // b/63581208 265*795d594fSAndroid Build Coastguard Worker "sun.invoke.util.Wrapper", // For "ClassEvents" thread in JIT/no-image config. 266*795d594fSAndroid Build Coastguard Worker }; 267*795d594fSAndroid Build Coastguard Worker for (String s : PRELOAD_FOR_JIT) { 268*795d594fSAndroid Build Coastguard Worker Class.forName(s); 269*795d594fSAndroid Build Coastguard Worker } 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker Runnable r = new Runnable() { 272*795d594fSAndroid Build Coastguard Worker @Override 273*795d594fSAndroid Build Coastguard Worker public void run() { 274*795d594fSAndroid Build Coastguard Worker try { 275*795d594fSAndroid Build Coastguard Worker ClassLoader cl6 = DexData.create12(); 276*795d594fSAndroid Build Coastguard Worker System.out.println("C, true"); 277*795d594fSAndroid Build Coastguard Worker Class.forName("C", true, cl6); 278*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 279*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 280*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(e); 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker } 283*795d594fSAndroid Build Coastguard Worker }; 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker Thread noopThread = new Thread(); 286*795d594fSAndroid Build Coastguard Worker noopThread.start(); 287*795d594fSAndroid Build Coastguard Worker noopThread.join(); 288*795d594fSAndroid Build Coastguard Worker 289*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(true, Thread.currentThread()); 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker ClassLoader cl1 = DexData.create12(); 292*795d594fSAndroid Build Coastguard Worker System.out.println("B, false"); 293*795d594fSAndroid Build Coastguard Worker Class.forName("B", false, cl1); 294*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 295*795d594fSAndroid Build Coastguard Worker 296*795d594fSAndroid Build Coastguard Worker ClassLoader cl2 = DexData.create12(); 297*795d594fSAndroid Build Coastguard Worker System.out.println("B, true"); 298*795d594fSAndroid Build Coastguard Worker Class.forName("B", true, cl2); 299*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker ClassLoader cl3 = DexData.create12(); 302*795d594fSAndroid Build Coastguard Worker System.out.println("C, false"); 303*795d594fSAndroid Build Coastguard Worker Class.forName("C", false, cl3); 304*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 305*795d594fSAndroid Build Coastguard Worker System.out.println("A, false"); 306*795d594fSAndroid Build Coastguard Worker Class.forName("A", false, cl3); 307*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 308*795d594fSAndroid Build Coastguard Worker 309*795d594fSAndroid Build Coastguard Worker ClassLoader cl4 = DexData.create12(); 310*795d594fSAndroid Build Coastguard Worker System.out.println("C, true"); 311*795d594fSAndroid Build Coastguard Worker Class.forName("C", true, cl4); 312*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 313*795d594fSAndroid Build Coastguard Worker System.out.println("A, true"); 314*795d594fSAndroid Build Coastguard Worker Class.forName("A", true, cl4); 315*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 316*795d594fSAndroid Build Coastguard Worker 317*795d594fSAndroid Build Coastguard Worker ClassLoader cl5 = DexData.create12(); 318*795d594fSAndroid Build Coastguard Worker System.out.println("A, true"); 319*795d594fSAndroid Build Coastguard Worker Class.forName("A", true, cl5); 320*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 321*795d594fSAndroid Build Coastguard Worker System.out.println("C, true"); 322*795d594fSAndroid Build Coastguard Worker Class.forName("C", true, cl5); 323*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(false, null); 326*795d594fSAndroid Build Coastguard Worker 327*795d594fSAndroid Build Coastguard Worker Thread t = new Thread(r, "TestRunner"); 328*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(true, t); 329*795d594fSAndroid Build Coastguard Worker t.start(); 330*795d594fSAndroid Build Coastguard Worker t.join(); 331*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(false, null); 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(true, Thread.currentThread()); 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker // Check creation of arrays and proxies. 336*795d594fSAndroid Build Coastguard Worker Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Comparable.class, I0.class }); 337*795d594fSAndroid Build Coastguard Worker Class.forName("[Lart.Test912;"); 338*795d594fSAndroid Build Coastguard Worker printClassLoadMessages(); 339*795d594fSAndroid Build Coastguard Worker 340*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(false, null); 341*795d594fSAndroid Build Coastguard Worker 342*795d594fSAndroid Build Coastguard Worker testClassLoadPrepareEquality(); 343*795d594fSAndroid Build Coastguard Worker } 344*795d594fSAndroid Build Coastguard Worker testClassLoadPrepareEquality()345*795d594fSAndroid Build Coastguard Worker private static void testClassLoadPrepareEquality() throws Exception { 346*795d594fSAndroid Build Coastguard Worker setEqualityEventStorageClass(ClassF.class); 347*795d594fSAndroid Build Coastguard Worker 348*795d594fSAndroid Build Coastguard Worker enableClassLoadPrepareEqualityEvents(true); 349*795d594fSAndroid Build Coastguard Worker 350*795d594fSAndroid Build Coastguard Worker Class.forName("art.Test912$ClassE"); 351*795d594fSAndroid Build Coastguard Worker 352*795d594fSAndroid Build Coastguard Worker enableClassLoadPrepareEqualityEvents(false); 353*795d594fSAndroid Build Coastguard Worker } 354*795d594fSAndroid Build Coastguard Worker printClassLoaderClasses(ClassLoader cl)355*795d594fSAndroid Build Coastguard Worker private static void printClassLoaderClasses(ClassLoader cl) { 356*795d594fSAndroid Build Coastguard Worker for (;;) { 357*795d594fSAndroid Build Coastguard Worker if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) { 358*795d594fSAndroid Build Coastguard Worker break; 359*795d594fSAndroid Build Coastguard Worker } 360*795d594fSAndroid Build Coastguard Worker 361*795d594fSAndroid Build Coastguard Worker Class<?> classes[] = getClassLoaderClasses(cl); 362*795d594fSAndroid Build Coastguard Worker Arrays.sort(classes, new ClassNameComparator()); 363*795d594fSAndroid Build Coastguard Worker System.out.println(Arrays.toString(classes)); 364*795d594fSAndroid Build Coastguard Worker 365*795d594fSAndroid Build Coastguard Worker cl = cl.getParent(); 366*795d594fSAndroid Build Coastguard Worker } 367*795d594fSAndroid Build Coastguard Worker } 368*795d594fSAndroid Build Coastguard Worker printClassLoadMessages()369*795d594fSAndroid Build Coastguard Worker private static void printClassLoadMessages() { 370*795d594fSAndroid Build Coastguard Worker for (String s : getClassLoadMessages()) { 371*795d594fSAndroid Build Coastguard Worker System.out.println(s); 372*795d594fSAndroid Build Coastguard Worker } 373*795d594fSAndroid Build Coastguard Worker } 374*795d594fSAndroid Build Coastguard Worker isModifiableClass(Class<?> c)375*795d594fSAndroid Build Coastguard Worker private static native boolean isModifiableClass(Class<?> c); getClassSignature(Class<?> c)376*795d594fSAndroid Build Coastguard Worker private static native String[] getClassSignature(Class<?> c); 377*795d594fSAndroid Build Coastguard Worker isInterface(Class<?> c)378*795d594fSAndroid Build Coastguard Worker private static native boolean isInterface(Class<?> c); isArrayClass(Class<?> c)379*795d594fSAndroid Build Coastguard Worker private static native boolean isArrayClass(Class<?> c); 380*795d594fSAndroid Build Coastguard Worker getClassModifiers(Class<?> c)381*795d594fSAndroid Build Coastguard Worker private static native int getClassModifiers(Class<?> c); 382*795d594fSAndroid Build Coastguard Worker getClassFields(Class<?> c)383*795d594fSAndroid Build Coastguard Worker private static native Object[] getClassFields(Class<?> c); getClassMethods(Class<?> c)384*795d594fSAndroid Build Coastguard Worker private static native Object[] getClassMethods(Class<?> c); getImplementedInterfaces(Class<?> c)385*795d594fSAndroid Build Coastguard Worker private static native Class<?>[] getImplementedInterfaces(Class<?> c); 386*795d594fSAndroid Build Coastguard Worker getClassStatus(Class<?> c)387*795d594fSAndroid Build Coastguard Worker private static native int getClassStatus(Class<?> c); 388*795d594fSAndroid Build Coastguard Worker getClassLoader(Class<?> c)389*795d594fSAndroid Build Coastguard Worker private static native Object getClassLoader(Class<?> c); 390*795d594fSAndroid Build Coastguard Worker getClassLoaderClasses(ClassLoader cl)391*795d594fSAndroid Build Coastguard Worker private static native Class<?>[] getClassLoaderClasses(ClassLoader cl); 392*795d594fSAndroid Build Coastguard Worker getClassVersion(Class<?> c)393*795d594fSAndroid Build Coastguard Worker private static native int[] getClassVersion(Class<?> c); 394*795d594fSAndroid Build Coastguard Worker enableClassLoadPreparePrintEvents(boolean b, Thread filter)395*795d594fSAndroid Build Coastguard Worker private static native void enableClassLoadPreparePrintEvents(boolean b, Thread filter); getClassLoadMessages()396*795d594fSAndroid Build Coastguard Worker private static native String[] getClassLoadMessages(); 397*795d594fSAndroid Build Coastguard Worker setEqualityEventStorageClass(Class<?> c)398*795d594fSAndroid Build Coastguard Worker private static native void setEqualityEventStorageClass(Class<?> c); enableClassLoadPrepareEqualityEvents(boolean b)399*795d594fSAndroid Build Coastguard Worker private static native void enableClassLoadPrepareEqualityEvents(boolean b); 400*795d594fSAndroid Build Coastguard Worker runRecursiveClassPrepareEvents(Runnable forceLoad)401*795d594fSAndroid Build Coastguard Worker private static native void runRecursiveClassPrepareEvents(Runnable forceLoad); 402*795d594fSAndroid Build Coastguard Worker TestRecursiveClassPrepareEvents()403*795d594fSAndroid Build Coastguard Worker private static void TestRecursiveClassPrepareEvents() { 404*795d594fSAndroid Build Coastguard Worker final int[] called = new int[] { 0 }; 405*795d594fSAndroid Build Coastguard Worker runRecursiveClassPrepareEvents(() -> { 406*795d594fSAndroid Build Coastguard Worker if (called[0] == 2) { 407*795d594fSAndroid Build Coastguard Worker return; 408*795d594fSAndroid Build Coastguard Worker } else { 409*795d594fSAndroid Build Coastguard Worker called[0]++; 410*795d594fSAndroid Build Coastguard Worker } 411*795d594fSAndroid Build Coastguard Worker try { 412*795d594fSAndroid Build Coastguard Worker System.out.println("class-prepare event START!"); 413*795d594fSAndroid Build Coastguard Worker // Load a new class in a new class-loader. 414*795d594fSAndroid Build Coastguard Worker Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader"); 415*795d594fSAndroid Build Coastguard Worker Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class); 416*795d594fSAndroid Build Coastguard Worker Class<?> target = ((ClassLoader)ctor.newInstance( 417*795d594fSAndroid Build Coastguard Worker ByteBuffer.wrap(DEX_BYTES), Test912.class.getClassLoader())).loadClass("Transform"); 418*795d594fSAndroid Build Coastguard Worker target.newInstance(); 419*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { } 420*795d594fSAndroid Build Coastguard Worker System.out.println("class-prepare event END!"); 421*795d594fSAndroid Build Coastguard Worker }); 422*795d594fSAndroid Build Coastguard Worker if (called[0] != 2) { 423*795d594fSAndroid Build Coastguard Worker System.out.println("Failed to cause recursive Class prepare."); 424*795d594fSAndroid Build Coastguard Worker } 425*795d594fSAndroid Build Coastguard Worker } 426*795d594fSAndroid Build Coastguard Worker 427*795d594fSAndroid Build Coastguard Worker private static class TestForNonInit { 428*795d594fSAndroid Build Coastguard Worker public static double doubleValue = Math.random(); // So it can't be compile-time initialized. 429*795d594fSAndroid Build Coastguard Worker } 430*795d594fSAndroid Build Coastguard Worker 431*795d594fSAndroid Build Coastguard Worker @SuppressWarnings("RandomCast") 432*795d594fSAndroid Build Coastguard Worker private static class TestForInitFail { 433*795d594fSAndroid Build Coastguard Worker public static int intValue = ((int)Math.random())/0; // So it throws when initializing. 434*795d594fSAndroid Build Coastguard Worker } 435*795d594fSAndroid Build Coastguard Worker 436*795d594fSAndroid Build Coastguard Worker public static interface InfA { 437*795d594fSAndroid Build Coastguard Worker } 438*795d594fSAndroid Build Coastguard Worker public static interface InfB extends InfA { 439*795d594fSAndroid Build Coastguard Worker } 440*795d594fSAndroid Build Coastguard Worker public static interface InfC extends InfB { 441*795d594fSAndroid Build Coastguard Worker } 442*795d594fSAndroid Build Coastguard Worker 443*795d594fSAndroid Build Coastguard Worker public abstract static class ClassA implements InfA { 444*795d594fSAndroid Build Coastguard Worker } 445*795d594fSAndroid Build Coastguard Worker public abstract static class ClassB extends ClassA implements InfB { 446*795d594fSAndroid Build Coastguard Worker } 447*795d594fSAndroid Build Coastguard Worker public abstract static class ClassC implements InfA, InfC { 448*795d594fSAndroid Build Coastguard Worker } 449*795d594fSAndroid Build Coastguard Worker 450*795d594fSAndroid Build Coastguard Worker public static class ClassE { foo()451*795d594fSAndroid Build Coastguard Worker public void foo() { 452*795d594fSAndroid Build Coastguard Worker } bar()453*795d594fSAndroid Build Coastguard Worker public void bar() { 454*795d594fSAndroid Build Coastguard Worker } 455*795d594fSAndroid Build Coastguard Worker } 456*795d594fSAndroid Build Coastguard Worker 457*795d594fSAndroid Build Coastguard Worker public static class ClassF { 458*795d594fSAndroid Build Coastguard Worker public static Object STATIC = null; 459*795d594fSAndroid Build Coastguard Worker public static Reference<Object> WEAK = null; 460*795d594fSAndroid Build Coastguard Worker } 461*795d594fSAndroid Build Coastguard Worker 462*795d594fSAndroid Build Coastguard Worker private static class ClassNameComparator implements Comparator<Class<?>> { compare(Class<?> c1, Class<?> c2)463*795d594fSAndroid Build Coastguard Worker public int compare(Class<?> c1, Class<?> c2) { 464*795d594fSAndroid Build Coastguard Worker return c1.getName().compareTo(c2.getName()); 465*795d594fSAndroid Build Coastguard Worker } 466*795d594fSAndroid Build Coastguard Worker } 467*795d594fSAndroid Build Coastguard Worker 468*795d594fSAndroid Build Coastguard Worker // See run-test 910 for an explanation. 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker private static Class<?> proxyClass = null; 471*795d594fSAndroid Build Coastguard Worker getProxyClass()472*795d594fSAndroid Build Coastguard Worker private static Class<?> getProxyClass() throws Exception { 473*795d594fSAndroid Build Coastguard Worker if (proxyClass != null) { 474*795d594fSAndroid Build Coastguard Worker return proxyClass; 475*795d594fSAndroid Build Coastguard Worker } 476*795d594fSAndroid Build Coastguard Worker 477*795d594fSAndroid Build Coastguard Worker for (int i = 1; i <= 21; i++) { 478*795d594fSAndroid Build Coastguard Worker proxyClass = createProxyClass(i); 479*795d594fSAndroid Build Coastguard Worker String name = proxyClass.getName(); 480*795d594fSAndroid Build Coastguard Worker if (name.equals("$Proxy20")) { 481*795d594fSAndroid Build Coastguard Worker return proxyClass; 482*795d594fSAndroid Build Coastguard Worker } 483*795d594fSAndroid Build Coastguard Worker } 484*795d594fSAndroid Build Coastguard Worker return proxyClass; 485*795d594fSAndroid Build Coastguard Worker } 486*795d594fSAndroid Build Coastguard Worker createProxyClass(int i)487*795d594fSAndroid Build Coastguard Worker private static Class<?> createProxyClass(int i) throws Exception { 488*795d594fSAndroid Build Coastguard Worker int count = Integer.bitCount(i); 489*795d594fSAndroid Build Coastguard Worker Class<?>[] input = new Class<?>[count + 1]; 490*795d594fSAndroid Build Coastguard Worker input[0] = Runnable.class; 491*795d594fSAndroid Build Coastguard Worker int inputIndex = 1; 492*795d594fSAndroid Build Coastguard Worker int bitIndex = 0; 493*795d594fSAndroid Build Coastguard Worker while (i != 0) { 494*795d594fSAndroid Build Coastguard Worker if ((i & 1) != 0) { 495*795d594fSAndroid Build Coastguard Worker input[inputIndex++] = Class.forName("art.Test912$I" + bitIndex); 496*795d594fSAndroid Build Coastguard Worker } 497*795d594fSAndroid Build Coastguard Worker i >>>= 1; 498*795d594fSAndroid Build Coastguard Worker bitIndex++; 499*795d594fSAndroid Build Coastguard Worker } 500*795d594fSAndroid Build Coastguard Worker return Proxy.getProxyClass(Test912.class.getClassLoader(), input); 501*795d594fSAndroid Build Coastguard Worker } 502*795d594fSAndroid Build Coastguard Worker 503*795d594fSAndroid Build Coastguard Worker // Need this for the proxy naming. 504*795d594fSAndroid Build Coastguard Worker public static interface I0 { 505*795d594fSAndroid Build Coastguard Worker } 506*795d594fSAndroid Build Coastguard Worker public static interface I1 { 507*795d594fSAndroid Build Coastguard Worker } 508*795d594fSAndroid Build Coastguard Worker public static interface I2 { 509*795d594fSAndroid Build Coastguard Worker } 510*795d594fSAndroid Build Coastguard Worker public static interface I3 { 511*795d594fSAndroid Build Coastguard Worker } 512*795d594fSAndroid Build Coastguard Worker public static interface I4 { 513*795d594fSAndroid Build Coastguard Worker } 514*795d594fSAndroid Build Coastguard Worker } 515