diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 0dbe971ed3f57..948f203119056 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -538,7 +538,7 @@ public class ZygoteInit { .asInterface(ServiceManager.getService("installd")); final String instructionSet = VMRuntime.getRuntime().vmInstructionSet(); - String sharedLibraries = ""; + String classPathForElement = ""; for (String classPathElement : classPathElements) { // System server is fully AOTed and never profiled // for profile guided compilation. @@ -570,10 +570,12 @@ public class ZygoteInit { final String compilerFilter = systemServerFilter; final String uuid = StorageManager.UUID_PRIVATE_INTERNAL; final String seInfo = null; + final String classLoaderContext = + getSystemServerClassLoaderContext(classPathForElement); try { installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, - uuid, sharedLibraries, seInfo, false /* downgrade */); + uuid, classLoaderContext, seInfo, false /* downgrade */); } catch (RemoteException | ServiceSpecificException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " @@ -581,13 +583,35 @@ public class ZygoteInit { } } - if (!sharedLibraries.isEmpty()) { - sharedLibraries += ":"; - } - sharedLibraries += classPathElement; + classPathForElement = encodeSystemServerClassPath( + classPathForElement, classPathElement); } } + /** + * Encodes the system server class loader context in a format that is accepted by dexopt. + * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}. + * + * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no + * dependency here on the server so we hard code the logic again. + */ + private static String getSystemServerClassLoaderContext(String classPath) { + return classPath == null ? "PCL[]" : "PCL[" + classPath + "]"; + } + + /** + * Encodes the class path in a format accepted by dexopt. + * @param classPath the old class path (may be empty). + * @param newElement the new class path elements + * @return the class path encoding resulted from appending {@code newElement} to + * {@code classPath}. + */ + private static String encodeSystemServerClassPath(String classPath, String newElement) { + return (classPath == null || classPath.isEmpty()) + ? newElement + : classPath + ":" + newElement; + } + /** * Prepare the arguments and forks for the system server process. *