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