blob: 6a73829da154b3f397142c5a336c91f3b919bcba [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
Dianne Hackbornf7be4802013-04-12 14:52:58 -070019import android.os.Trace;
Dianne Hackbornadd005c2013-07-17 18:43:12 -070020import android.util.ArrayMap;
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070021import com.android.internal.os.PathClassLoaderFactory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import dalvik.system.PathClassLoader;
23
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080024class ApplicationLoaders {
25 public static ApplicationLoaders getDefault() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026 return gApplicationLoaders;
27 }
28
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080029 public ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
30 String librarySearchPath, String libraryPermittedPath,
31 ClassLoader parent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032 /*
33 * This is the parent we use if they pass "null" in. In theory
34 * this should be the "system" class loader; in practice we
35 * don't use that and can happily (and more efficiently) use the
36 * bootstrap class loader.
37 */
38 ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();
39
40 synchronized (mLoaders) {
41 if (parent == null) {
42 parent = baseParent;
43 }
44
45 /*
46 * If we're one step up from the base class loader, find
47 * something in our cache. Otherwise, we create a whole
48 * new ClassLoader for the zip archive.
49 */
50 if (parent == baseParent) {
Kenny Root85387d72010-08-26 10:13:11 -070051 ClassLoader loader = mLoaders.get(zip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 if (loader != null) {
53 return loader;
54 }
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070055
Dianne Hackbornf7be4802013-04-12 14:52:58 -070056 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080057
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070058 PathClassLoader pathClassloader = PathClassLoaderFactory.createClassLoader(
59 zip,
60 librarySearchPath,
61 libraryPermittedPath,
62 parent,
63 targetSdkVersion,
64 isBundled);
Dimitry Ivanova55c7f12016-02-23 14:25:50 -080065
Dianne Hackbornf7be4802013-04-12 14:52:58 -070066 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
67
Andreas Gampe4c8e5422016-05-18 11:58:47 -070068 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupVulkanLayerPath");
Dimitry Ivanov09979082016-04-19 11:11:01 -070069 setupVulkanLayerPath(pathClassloader, librarySearchPath);
Andreas Gampe4c8e5422016-05-18 11:58:47 -070070 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dimitry Ivanov09979082016-04-19 11:11:01 -070071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 mLoaders.put(zip, pathClassloader);
73 return pathClassloader;
74 }
75
Dianne Hackbornf7be4802013-04-12 14:52:58 -070076 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
77 PathClassLoader pathClassloader = new PathClassLoader(zip, parent);
78 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
79 return pathClassloader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 }
81 }
82
Dimitry Ivanov09979082016-04-19 11:11:01 -070083 private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
84
Todd Kennedy39bfee52016-02-24 10:28:21 -080085 /**
86 * Adds a new path the classpath of the given loader.
87 * @throws IllegalStateException if the provided class loader is not a {@link PathClassLoader}.
88 */
89 void addPath(ClassLoader classLoader, String dexPath) {
90 if (!(classLoader instanceof PathClassLoader)) {
91 throw new IllegalStateException("class loader is not a PathClassLoader");
92 }
93 final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader;
94 baseDexClassLoader.addDexPath(dexPath);
95 }
96
Dianne Hackbornadd005c2013-07-17 18:43:12 -070097 private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
Dimitry Ivanovb1ef62b2016-04-20 14:09:32 -070099 private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100}