xref: /aosp_15_r20/art/test/692-vdex-secondary-loader/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 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 import dalvik.system.PathClassLoader;
18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
19*795d594fSAndroid Build Coastguard Worker import java.io.File;
20*795d594fSAndroid Build Coastguard Worker import java.nio.ByteBuffer;
21*795d594fSAndroid Build Coastguard Worker import java.util.Base64;
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker public class Main {
check(boolean expected, boolean actual, String message)24*795d594fSAndroid Build Coastguard Worker   private static void check(boolean expected, boolean actual, String message) {
25*795d594fSAndroid Build Coastguard Worker     if (expected != actual) {
26*795d594fSAndroid Build Coastguard Worker       System.err.println(
27*795d594fSAndroid Build Coastguard Worker           "ERROR: " + message + " (expected=" + expected + ", actual=" + actual + ")");
28*795d594fSAndroid Build Coastguard Worker       throw new Error("");
29*795d594fSAndroid Build Coastguard Worker     }
30*795d594fSAndroid Build Coastguard Worker   }
31*795d594fSAndroid Build Coastguard Worker 
singleLoader()32*795d594fSAndroid Build Coastguard Worker   private static ClassLoader singleLoader() {
33*795d594fSAndroid Build Coastguard Worker     return new PathClassLoader(DEX_EXTRA, /*parent*/null);
34*795d594fSAndroid Build Coastguard Worker   }
35*795d594fSAndroid Build Coastguard Worker 
test(ClassLoader loader, boolean expectedHasVdexFile, boolean expectedBackedByOat, boolean invokeMethod)36*795d594fSAndroid Build Coastguard Worker   private static void test(ClassLoader loader,
37*795d594fSAndroid Build Coastguard Worker                            boolean expectedHasVdexFile,
38*795d594fSAndroid Build Coastguard Worker                            boolean expectedBackedByOat,
39*795d594fSAndroid Build Coastguard Worker                            boolean invokeMethod) throws Exception {
40*795d594fSAndroid Build Coastguard Worker     // If ART created a vdex file, it must have verified all the classes.
41*795d594fSAndroid Build Coastguard Worker     // That happens if and only if we expect a vdex at the end of the test but
42*795d594fSAndroid Build Coastguard Worker     // do not expect it to have been loaded.
43*795d594fSAndroid Build Coastguard Worker     boolean expectedClassesVerified = expectedHasVdexFile && !expectedBackedByOat;
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker     waitForVerifier();
46*795d594fSAndroid Build Coastguard Worker     check(expectedClassesVerified, areClassesVerified(loader), "areClassesVerified");
47*795d594fSAndroid Build Coastguard Worker     check(expectedHasVdexFile, hasVdexFile(loader), "hasVdexFile");
48*795d594fSAndroid Build Coastguard Worker     check(expectedBackedByOat, isBackedByOatFile(loader), "isBackedByOatFile");
49*795d594fSAndroid Build Coastguard Worker     check(expectedBackedByOat, areClassesPreverified(loader), "areClassesPreverified");
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker     if (invokeMethod) {
52*795d594fSAndroid Build Coastguard Worker       loader.loadClass("art.ClassB").getDeclaredMethod("printHello").invoke(null);
53*795d594fSAndroid Build Coastguard Worker     }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker     if (expectedBackedByOat) {
56*795d594fSAndroid Build Coastguard Worker       String filter = getCompilerFilter(loader.loadClass("art.ClassB"));
57*795d594fSAndroid Build Coastguard Worker       if (!("verify".equals(filter))) {
58*795d594fSAndroid Build Coastguard Worker         throw new Error("Expected verify, got " + filter);
59*795d594fSAndroid Build Coastguard Worker       }
60*795d594fSAndroid Build Coastguard Worker     }
61*795d594fSAndroid Build Coastguard Worker   }
62*795d594fSAndroid Build Coastguard Worker 
main(String[] args)63*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Exception {
64*795d594fSAndroid Build Coastguard Worker     System.loadLibrary(args[0]);
65*795d594fSAndroid Build Coastguard Worker 
66*795d594fSAndroid Build Coastguard Worker     // Feature is disabled in debuggable mode because runtime threads are not
67*795d594fSAndroid Build Coastguard Worker     // allowed to load classes.
68*795d594fSAndroid Build Coastguard Worker     boolean featureEnabled = !isDebuggable();
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker     // SDK version not set. Background verification job should not have run
71*795d594fSAndroid Build Coastguard Worker     // and vdex should not have been created.
72*795d594fSAndroid Build Coastguard Worker     test(singleLoader(), /*hasVdex*/ false, /*backedByOat*/ false, /*invokeMethod*/ true);
73*795d594fSAndroid Build Coastguard Worker 
74*795d594fSAndroid Build Coastguard Worker     // Feature only enabled for target SDK version Q and later.
75*795d594fSAndroid Build Coastguard Worker     setTargetSdkVersion(/* Q */ 29);
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker     // SDK version directory is now set. Background verification job should have run,
78*795d594fSAndroid Build Coastguard Worker     // should have verified classes and written results to a vdex.
79*795d594fSAndroid Build Coastguard Worker     test(singleLoader(), /*hasVdex*/ featureEnabled, /*backedByOat*/ false, /*invokeMethod*/ true);
80*795d594fSAndroid Build Coastguard Worker     test(singleLoader(), /*hasVdex*/ featureEnabled, /*backedByOat*/ featureEnabled,
81*795d594fSAndroid Build Coastguard Worker         /*invokeMethod*/ true);
82*795d594fSAndroid Build Coastguard Worker   }
83*795d594fSAndroid Build Coastguard Worker 
isDebuggable()84*795d594fSAndroid Build Coastguard Worker   private static native boolean isDebuggable();
setTargetSdkVersion(int version)85*795d594fSAndroid Build Coastguard Worker   private static native int setTargetSdkVersion(int version);
waitForVerifier()86*795d594fSAndroid Build Coastguard Worker   private static native void waitForVerifier();
areClassesVerified(ClassLoader loader)87*795d594fSAndroid Build Coastguard Worker   private static native boolean areClassesVerified(ClassLoader loader);
hasVdexFile(ClassLoader loader)88*795d594fSAndroid Build Coastguard Worker   private static native boolean hasVdexFile(ClassLoader loader);
isBackedByOatFile(ClassLoader loader)89*795d594fSAndroid Build Coastguard Worker   private static native boolean isBackedByOatFile(ClassLoader loader);
areClassesPreverified(ClassLoader loader)90*795d594fSAndroid Build Coastguard Worker   private static native boolean areClassesPreverified(ClassLoader loader);
getCompilerFilter(Class cls)91*795d594fSAndroid Build Coastguard Worker   private static native String getCompilerFilter(Class cls);
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker   private static final String DEX_LOCATION = System.getenv("DEX_LOCATION");
94*795d594fSAndroid Build Coastguard Worker   private static final String DEX_EXTRA =
95*795d594fSAndroid Build Coastguard Worker       new File(DEX_LOCATION, "692-vdex-secondary-loader-ex.jar").getAbsolutePath();
96*795d594fSAndroid Build Coastguard Worker }
97