blob: ef2db4a0d795829a384546cde5b8ebc046d0bcb2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
17package android.app;
18
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +010019import android.os.Build;
Dianne Hackbornf7be4802013-04-12 14:52:58 -070020import android.os.Trace;
Dianne Hackbornadd005c2013-07-17 18:43:12 -070021import android.util.ArrayMap;
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070022import com.android.internal.os.PathClassLoaderFactory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import dalvik.system.PathClassLoader;
24
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +010025/** @hide */
26public class ApplicationLoaders {
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080027 public static ApplicationLoaders getDefault() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028 return gApplicationLoaders;
29 }
30
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +010031 ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080032 String librarySearchPath, String libraryPermittedPath,
33 ClassLoader parent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034 /*
35 * This is the parent we use if they pass "null" in. In theory
36 * this should be the "system" class loader; in practice we
37 * don't use that and can happily (and more efficiently) use the
38 * bootstrap class loader.
39 */
40 ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();
41
42 synchronized (mLoaders) {
43 if (parent == null) {
44 parent = baseParent;
45 }
46
47 /*
48 * If we're one step up from the base class loader, find
49 * something in our cache. Otherwise, we create a whole
50 * new ClassLoader for the zip archive.
51 */
52 if (parent == baseParent) {
Kenny Root85387d72010-08-26 10:13:11 -070053 ClassLoader loader = mLoaders.get(zip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 if (loader != null) {
55 return loader;
56 }
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070057
Dianne Hackbornf7be4802013-04-12 14:52:58 -070058 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080059
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070060 PathClassLoader pathClassloader = PathClassLoaderFactory.createClassLoader(
61 zip,
62 librarySearchPath,
63 libraryPermittedPath,
64 parent,
65 targetSdkVersion,
66 isBundled);
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080067
Dianne Hackbornf7be4802013-04-12 14:52:58 -070068 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
69
Andreas Gampe4c8e5422016-05-18 11:58:47 -070070 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupVulkanLayerPath");
Dimitry Ivanov09979082016-04-19 11:11:01 -070071 setupVulkanLayerPath(pathClassloader, librarySearchPath);
Andreas Gampe4c8e5422016-05-18 11:58:47 -070072 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dimitry Ivanov09979082016-04-19 11:11:01 -070073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 mLoaders.put(zip, pathClassloader);
75 return pathClassloader;
76 }
77
Dianne Hackbornf7be4802013-04-12 14:52:58 -070078 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
79 PathClassLoader pathClassloader = new PathClassLoader(zip, parent);
80 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
81 return pathClassloader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 }
83 }
84
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +010085 /**
86 * Creates a classloader for the WebView APK and places it in the cache of loaders maintained
87 * by this class. This is used in the WebView zygote, where its presence in the cache speeds up
88 * startup and enables memory sharing.
89 */
90 public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) {
91 // The correct paths are calculated by WebViewZygote in the system server and passed to
92 // us here. We hardcode the other parameters: WebView always targets the current SDK,
93 // does not need to use non-public system libraries, and uses the base classloader as its
94 // parent to permit usage of the cache.
95 return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null);
96 }
97
Dimitry Ivanov09979082016-04-19 11:11:01 -070098 private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
99
Todd Kennedy39bfee52016-02-24 10:28:21 -0800100 /**
101 * Adds a new path the classpath of the given loader.
102 * @throws IllegalStateException if the provided class loader is not a {@link PathClassLoader}.
103 */
104 void addPath(ClassLoader classLoader, String dexPath) {
105 if (!(classLoader instanceof PathClassLoader)) {
106 throw new IllegalStateException("class loader is not a PathClassLoader");
107 }
108 final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader;
109 baseDexClassLoader.addDexPath(dexPath);
110 }
111
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700112 private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -0700114 private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115}