diff options
3 files changed, 67 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index da6e26e17122..73ac05738f0f 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -53,7 +53,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { private final static boolean DEBUG_DEXOPT = true; // The synthetic library dependencies denoting "no checks." - private final static String[] NO_LIBRARIES = new String[] { "&" }; + private final static String[] NO_LIBRARIES = + new String[] { PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK }; // The amount of "available" (free - low threshold) space necessary at the start of an OTA to // not bulk-delete unused apps' odex files. @@ -325,7 +326,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { mPackageManagerService.getDexManager().dexoptSecondaryDex( new DexoptOptions(pkg.packageName, compilationReason, DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX | - DexoptOptions.DEXOPT_BOOT_COMPLETE)); + DexoptOptions.DEXOPT_BOOT_COMPLETE)); return commands; } diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java index ef2ee4a41555..e1310a2f1ab3 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java +++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java @@ -21,6 +21,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.os.ClassLoaderFactory; +import com.android.server.pm.PackageDexOptimizer; import java.io.File; import java.util.ArrayList; @@ -238,10 +239,15 @@ public final class DexoptUtils { /** * Encodes a single class loader dependency starting from {@param path} and * {@param classLoaderName}. + * When classpath is {@link PackageDexOptimizer#SKIP_SHARED_LIBRARY_CHECK}, the method returns + * the same. This special property is used only during OTA. * NOTE: Keep this in sync with the dexopt expectations! Right now that is either "PCL[path]" * for a PathClassLoader or "DLC[path]" for a DelegateLastClassLoader. */ - private static String encodeClassLoader(String classpath, String classLoaderName) { + /*package*/ static String encodeClassLoader(String classpath, String classLoaderName) { + if (classpath.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK)) { + return classpath; + } String classLoaderDexoptEncoding = classLoaderName; if (ClassLoaderFactory.isPathClassLoaderName(classLoaderName)) { classLoaderDexoptEncoding = "PCL"; @@ -255,10 +261,17 @@ public final class DexoptUtils { /** * Links to dependencies together in a format accepted by dexopt. + * For the special case when either of cl1 or cl2 equals + * {@link PackageDexOptimizer#SKIP_SHARED_LIBRARY_CHECK}, the method returns the same. This + * property is used only during OTA. * NOTE: Keep this in sync with the dexopt expectations! Right now that is a list of split * dependencies {@see encodeClassLoader} separated by ';'. */ - private static String encodeClassLoaderChain(String cl1, String cl2) { + /*package*/ static String encodeClassLoaderChain(String cl1, String cl2) { + if (cl1.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK) || + cl2.equals(PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK)) { + return PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK; + } if (cl1.isEmpty()) return cl2; if (cl2.isEmpty()) return cl1; return cl1 + ";" + cl2; diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java index c8c8eb1aa5c6..150f7f0c948c 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java @@ -16,10 +16,14 @@ package com.android.server.pm.dex; +import com.android.server.pm.PackageDexOptimizer; + +import static com.android.server.pm.PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.content.pm.ApplicationInfo; import android.support.test.filters.SmallTest; @@ -369,4 +373,49 @@ public class DexoptUtilsTest { } assertTrue(gotException); } + + @Test + public void testEncodeClassLoader() { + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader( + SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.PathClassLoader")); + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader( + SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.DexClassLoader")); + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoader( + SKIP_SHARED_LIBRARY_CHECK, "dalvik.system.DelegateLastClassLoader")); + assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz", + "dalvik.system.PathClassLoader")); + assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz", + "dalvik.system.DexClassLoader")); + assertEquals("DLC[xyz]", DexoptUtils.encodeClassLoader("xyz", + "dalvik.system.DelegateLastClassLoader")); + assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz", null)); + assertEquals("abc[xyz]", DexoptUtils.encodeClassLoader("xyz", "abc")); + + try { + DexoptUtils.encodeClassLoader(null, "abc"); + fail(); // Exception should be caught. + } catch (NullPointerException expected) {} + } + + @Test + public void testEncodeClassLoaderChain() { + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain( + SKIP_SHARED_LIBRARY_CHECK, "PCL[a]")); + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain("PCL[a]", + SKIP_SHARED_LIBRARY_CHECK)); + assertEquals("PCL[a];DLC[b]", DexoptUtils.encodeClassLoaderChain("PCL[a]", + "DLC[b]")); + assertEquals(SKIP_SHARED_LIBRARY_CHECK, DexoptUtils.encodeClassLoaderChain("PCL[a]", + SKIP_SHARED_LIBRARY_CHECK)); + + try { + DexoptUtils.encodeClassLoaderChain("a", null); + fail(); // exception is expected + } catch (NullPointerException expected) {} + + try { + DexoptUtils.encodeClassLoaderChain(null, "b"); + fail(); // exception is expected + } catch (NullPointerException expected) {} + } } |