Loading core/java/android/app/ApplicationLoaders.java +8 −9 Original line number Diff line number Diff line Loading @@ -145,8 +145,7 @@ public class ApplicationLoaders { */ public void createAndCacheNonBootclasspathSystemClassLoaders(SharedLibraryInfo[] libs) { if (mSystemLibsCacheMap != null) { Log.wtf(TAG, "Already cached."); return; throw new IllegalStateException("Already cached."); } mSystemLibsCacheMap = new HashMap<String, CachedClassLoader>(); Loading @@ -159,7 +158,8 @@ public class ApplicationLoaders { /** * Caches a single non-bootclasspath class loader. * * All of this library's dependencies must have previously been cached. * All of this library's dependencies must have previously been cached. Otherwise, an exception * is thrown. */ private void createAndCacheNonBootclasspathSystemClassLoader(SharedLibraryInfo lib) { String path = lib.getPath(); Loading @@ -174,9 +174,8 @@ public class ApplicationLoaders { CachedClassLoader cached = mSystemLibsCacheMap.get(dependencyPath); if (cached == null) { Log.e(TAG, "Failed to find dependency " + dependencyPath throw new IllegalStateException("Failed to find dependency " + dependencyPath + " of cachedlibrary " + path); return; } sharedLibraries.add(cached.loader); Loading @@ -189,8 +188,8 @@ public class ApplicationLoaders { null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/); if (classLoader == null) { Log.e(TAG, "Failed to cache " + path); return; // bad configuration or break in classloading code throw new IllegalStateException("Failed to cache " + path); } CachedClassLoader cached = new CachedClassLoader(); Loading @@ -215,7 +214,7 @@ public class ApplicationLoaders { * * If there is an error or the cache is not available, this returns null. */ private ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent, public ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries) { if (mSystemLibsCacheMap == null) { return null; Loading core/tests/coretests/src/android/app/ApplicationLoadersTest.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import android.content.pm.SharedLibraryInfo; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; @RunWith(AndroidJUnit4.class) @SmallTest public class ApplicationLoadersTest { // a library installed onto the device with no dependencies private static final String LIB_A = "/system/framework/android.hidl.base-V1.0-java.jar"; // a library installed onto the device which only depends on A private static final String LIB_DEP_A = "/system/framework/android.hidl.manager-V1.0-java.jar"; private static SharedLibraryInfo createLib(String zip) { return new SharedLibraryInfo( zip, null /*packageName*/, null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/); } @Test public void testGetNonExistantLib() { ApplicationLoaders loaders = new ApplicationLoaders(); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( "/system/framework/nonexistantlib.jar", null, null, null)); } @Test public void testCacheExistantLib() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, null)); } @Test public void testNonNullParent() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); ClassLoader parent = ClassLoader.getSystemClassLoader(); assertNotEquals(null, parent); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, parent, null, null)); } @Test public void testNonNullClassLoaderNamespace() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, "other classloader", null)); } @Test public void testDifferentSharedLibraries() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); // any other existant lib ClassLoader dep = ClassLoader.getSystemClassLoader(); ArrayList<ClassLoader> sharedLibraries = new ArrayList<>(); sharedLibraries.add(dep); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, sharedLibraries)); } @Test public void testDependentLibs() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); SharedLibraryInfo libB = createLib(LIB_DEP_A); libB.addDependency(libA); loaders.createAndCacheNonBootclasspathSystemClassLoaders( new SharedLibraryInfo[]{libA, libB}); ClassLoader loadA = loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, null); assertNotEquals(null, loadA); ArrayList<ClassLoader> sharedLibraries = new ArrayList<>(); sharedLibraries.add(loadA); assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_DEP_A, null, null, sharedLibraries)); } @Test(expected = IllegalStateException.class) public void testDependentLibsWrongOrder() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); SharedLibraryInfo libB = createLib(LIB_DEP_A); libB.addDependency(libA); loaders.createAndCacheNonBootclasspathSystemClassLoaders( new SharedLibraryInfo[]{libB, libA}); } } Loading
core/java/android/app/ApplicationLoaders.java +8 −9 Original line number Diff line number Diff line Loading @@ -145,8 +145,7 @@ public class ApplicationLoaders { */ public void createAndCacheNonBootclasspathSystemClassLoaders(SharedLibraryInfo[] libs) { if (mSystemLibsCacheMap != null) { Log.wtf(TAG, "Already cached."); return; throw new IllegalStateException("Already cached."); } mSystemLibsCacheMap = new HashMap<String, CachedClassLoader>(); Loading @@ -159,7 +158,8 @@ public class ApplicationLoaders { /** * Caches a single non-bootclasspath class loader. * * All of this library's dependencies must have previously been cached. * All of this library's dependencies must have previously been cached. Otherwise, an exception * is thrown. */ private void createAndCacheNonBootclasspathSystemClassLoader(SharedLibraryInfo lib) { String path = lib.getPath(); Loading @@ -174,9 +174,8 @@ public class ApplicationLoaders { CachedClassLoader cached = mSystemLibsCacheMap.get(dependencyPath); if (cached == null) { Log.e(TAG, "Failed to find dependency " + dependencyPath throw new IllegalStateException("Failed to find dependency " + dependencyPath + " of cachedlibrary " + path); return; } sharedLibraries.add(cached.loader); Loading @@ -189,8 +188,8 @@ public class ApplicationLoaders { null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/); if (classLoader == null) { Log.e(TAG, "Failed to cache " + path); return; // bad configuration or break in classloading code throw new IllegalStateException("Failed to cache " + path); } CachedClassLoader cached = new CachedClassLoader(); Loading @@ -215,7 +214,7 @@ public class ApplicationLoaders { * * If there is an error or the cache is not available, this returns null. */ private ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent, public ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries) { if (mSystemLibsCacheMap == null) { return null; Loading
core/tests/coretests/src/android/app/ApplicationLoadersTest.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import android.content.pm.SharedLibraryInfo; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; @RunWith(AndroidJUnit4.class) @SmallTest public class ApplicationLoadersTest { // a library installed onto the device with no dependencies private static final String LIB_A = "/system/framework/android.hidl.base-V1.0-java.jar"; // a library installed onto the device which only depends on A private static final String LIB_DEP_A = "/system/framework/android.hidl.manager-V1.0-java.jar"; private static SharedLibraryInfo createLib(String zip) { return new SharedLibraryInfo( zip, null /*packageName*/, null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/); } @Test public void testGetNonExistantLib() { ApplicationLoaders loaders = new ApplicationLoaders(); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( "/system/framework/nonexistantlib.jar", null, null, null)); } @Test public void testCacheExistantLib() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, null)); } @Test public void testNonNullParent() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); ClassLoader parent = ClassLoader.getSystemClassLoader(); assertNotEquals(null, parent); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, parent, null, null)); } @Test public void testNonNullClassLoaderNamespace() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, "other classloader", null)); } @Test public void testDifferentSharedLibraries() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); // any other existant lib ClassLoader dep = ClassLoader.getSystemClassLoader(); ArrayList<ClassLoader> sharedLibraries = new ArrayList<>(); sharedLibraries.add(dep); loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA}); assertEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, sharedLibraries)); } @Test public void testDependentLibs() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); SharedLibraryInfo libB = createLib(LIB_DEP_A); libB.addDependency(libA); loaders.createAndCacheNonBootclasspathSystemClassLoaders( new SharedLibraryInfo[]{libA, libB}); ClassLoader loadA = loaders.getCachedNonBootclasspathSystemLib( LIB_A, null, null, null); assertNotEquals(null, loadA); ArrayList<ClassLoader> sharedLibraries = new ArrayList<>(); sharedLibraries.add(loadA); assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib( LIB_DEP_A, null, null, sharedLibraries)); } @Test(expected = IllegalStateException.class) public void testDependentLibsWrongOrder() { ApplicationLoaders loaders = new ApplicationLoaders(); SharedLibraryInfo libA = createLib(LIB_A); SharedLibraryInfo libB = createLib(LIB_DEP_A); libB.addDependency(libA); loaders.createAndCacheNonBootclasspathSystemClassLoaders( new SharedLibraryInfo[]{libB, libA}); } }