Loading core/java/com/android/internal/os/InstallerConnection.java +53 −32 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.os; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.SystemClock; import android.text.TextUtils; import android.util.Slog; import com.android.internal.util.Preconditions; Loading @@ -29,6 +30,7 @@ import libcore.io.Streams; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; /** * Represents a connection to {@code installd}. Allows multiple connect and Loading Loading @@ -61,6 +63,11 @@ public class InstallerConnection { } public synchronized String transact(String cmd) { if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) { Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x" + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable()); } if (!connect()) { Slog.e(TAG, "connection failed"); return "-1"; Loading Loading @@ -96,44 +103,50 @@ public class InstallerConnection { } } public int execute(String cmd) { if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) { Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x" + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable()); public void execute(String cmd, Object... args) throws InstallerException { final String resRaw = executeForResult(cmd, args); int res = -1; try { res = Integer.parseInt(resRaw); } catch (NumberFormatException ignored) { } if (res != 0) { throw new InstallerException( "Failed to execute " + cmd + " " + Arrays.toString(args) + ": " + res); } } String res = transact(cmd); try { return Integer.parseInt(res); } catch (NumberFormatException ex) { return -1; public String executeForResult(String cmd, Object... args) throws InstallerException { final StringBuilder builder = new StringBuilder(cmd); for (Object arg : args) { String escaped; if (arg == null) { escaped = ""; } else { escaped = String.valueOf(arg); } if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) { throw new InstallerException( "Invalid argument while executing " + cmd + " " + Arrays.toString(args)); } if (TextUtils.isEmpty(escaped)) { escaped = "!"; } builder.append(' ').append(escaped); } return transact(builder.toString()); } public int dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags) { return dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /*outputPath*/, dexFlags); public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags) throws InstallerException { dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /* outputPath */, dexFlags); } public int dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags) { StringBuilder builder = new StringBuilder("dexopt"); builder.append(' '); builder.append(apkPath); builder.append(' '); builder.append(uid); builder.append(' '); builder.append(pkgName); builder.append(' '); builder.append(instructionSet); builder.append(' '); builder.append(dexoptNeeded); builder.append(' '); builder.append(outputPath != null ? outputPath : "!"); builder.append(' '); builder.append(dexFlags); return execute(builder.toString()); public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags) throws InstallerException { execute("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags); } private boolean connect() { Loading Loading @@ -227,11 +240,19 @@ public class InstallerConnection { public void waitForConnection() { for (;;) { if (execute("ping") >= 0) { try { execute("ping"); return; } catch (InstallerException ignored) { } Slog.w(TAG, "installd not ready"); SystemClock.sleep(1000); } } public static class InstallerException extends Exception { public InstallerException(String detailMessage) { super(detailMessage); } } } core/java/com/android/internal/os/ZygoteInit.java +4 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import android.util.EventLog; import android.util.Log; import android.webkit.WebViewFactory; import com.android.internal.os.InstallerConnection.InstallerException; import dalvik.system.DexFile; import dalvik.system.PathClassLoader; import dalvik.system.VMRuntime; Loading Loading @@ -502,8 +504,8 @@ public class ZygoteInit { dexoptNeeded, 0 /*dexFlags*/); } } } catch (IOException ioe) { throw new RuntimeException("Error starting system_server", ioe); } catch (IOException | InstallerException e) { throw new RuntimeException("Error starting system_server", e); } finally { installer.disconnect(); } Loading services/core/java/com/android/server/am/ActivityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.os.IResultReceiver; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.TransferPipe; import com.android.internal.os.Zygote; import com.android.internal.os.InstallerConnection.InstallerException; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FastXmlSerializer; Loading Loading @@ -6590,8 +6591,10 @@ public final class ActivityManagerService extends ActivityManagerNative Process.establishZygoteConnectionForAbi(abi); final String instructionSet = VMRuntime.getInstructionSet(abi); if (!completedIsas.contains(instructionSet)) { if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); try { mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); } catch (InstallerException e) { Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e); } completedIsas.add(instructionSet); } Loading services/core/java/com/android/server/pm/Installer.java +88 −369 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/pm/PackageDexOptimizer.java +15 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.util.ArraySet; import android.util.Log; import android.util.Slog; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.IOException; import java.util.ArrayList; Loading Loading @@ -166,12 +168,13 @@ final class PackageDexOptimizer { | (vmSafeMode ? DEXOPT_SAFEMODE : 0) | (debuggable ? DEXOPT_DEBUGGABLE : 0) | DEXOPT_BOOTCOMPLETE; final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags); // Dex2oat might fail due to compiler / verifier errors. if (ret == 0) { try { mPackageManagerService.mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags); performedDexOpt = true; } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); } } } Loading Loading @@ -210,8 +213,13 @@ final class PackageDexOptimizer { File codePath = new File(pkg.codePath); if (codePath.isDirectory()) { File oatDir = getOatDir(codePath); try { mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(), dexInstructionSet); } catch (InstallerException e) { Slog.w(TAG, "Failed to create oat dir", e); return null; } return oatDir.getAbsolutePath(); } return null; Loading Loading
core/java/com/android/internal/os/InstallerConnection.java +53 −32 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.os; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.SystemClock; import android.text.TextUtils; import android.util.Slog; import com.android.internal.util.Preconditions; Loading @@ -29,6 +30,7 @@ import libcore.io.Streams; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; /** * Represents a connection to {@code installd}. Allows multiple connect and Loading Loading @@ -61,6 +63,11 @@ public class InstallerConnection { } public synchronized String transact(String cmd) { if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) { Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x" + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable()); } if (!connect()) { Slog.e(TAG, "connection failed"); return "-1"; Loading Loading @@ -96,44 +103,50 @@ public class InstallerConnection { } } public int execute(String cmd) { if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) { Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x" + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable()); public void execute(String cmd, Object... args) throws InstallerException { final String resRaw = executeForResult(cmd, args); int res = -1; try { res = Integer.parseInt(resRaw); } catch (NumberFormatException ignored) { } if (res != 0) { throw new InstallerException( "Failed to execute " + cmd + " " + Arrays.toString(args) + ": " + res); } } String res = transact(cmd); try { return Integer.parseInt(res); } catch (NumberFormatException ex) { return -1; public String executeForResult(String cmd, Object... args) throws InstallerException { final StringBuilder builder = new StringBuilder(cmd); for (Object arg : args) { String escaped; if (arg == null) { escaped = ""; } else { escaped = String.valueOf(arg); } if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) { throw new InstallerException( "Invalid argument while executing " + cmd + " " + Arrays.toString(args)); } if (TextUtils.isEmpty(escaped)) { escaped = "!"; } builder.append(' ').append(escaped); } return transact(builder.toString()); } public int dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags) { return dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /*outputPath*/, dexFlags); public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags) throws InstallerException { dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /* outputPath */, dexFlags); } public int dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags) { StringBuilder builder = new StringBuilder("dexopt"); builder.append(' '); builder.append(apkPath); builder.append(' '); builder.append(uid); builder.append(' '); builder.append(pkgName); builder.append(' '); builder.append(instructionSet); builder.append(' '); builder.append(dexoptNeeded); builder.append(' '); builder.append(outputPath != null ? outputPath : "!"); builder.append(' '); builder.append(dexFlags); return execute(builder.toString()); public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags) throws InstallerException { execute("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags); } private boolean connect() { Loading Loading @@ -227,11 +240,19 @@ public class InstallerConnection { public void waitForConnection() { for (;;) { if (execute("ping") >= 0) { try { execute("ping"); return; } catch (InstallerException ignored) { } Slog.w(TAG, "installd not ready"); SystemClock.sleep(1000); } } public static class InstallerException extends Exception { public InstallerException(String detailMessage) { super(detailMessage); } } }
core/java/com/android/internal/os/ZygoteInit.java +4 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import android.util.EventLog; import android.util.Log; import android.webkit.WebViewFactory; import com.android.internal.os.InstallerConnection.InstallerException; import dalvik.system.DexFile; import dalvik.system.PathClassLoader; import dalvik.system.VMRuntime; Loading Loading @@ -502,8 +504,8 @@ public class ZygoteInit { dexoptNeeded, 0 /*dexFlags*/); } } } catch (IOException ioe) { throw new RuntimeException("Error starting system_server", ioe); } catch (IOException | InstallerException e) { throw new RuntimeException("Error starting system_server", e); } finally { installer.disconnect(); } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.os.IResultReceiver; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.TransferPipe; import com.android.internal.os.Zygote; import com.android.internal.os.InstallerConnection.InstallerException; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FastXmlSerializer; Loading Loading @@ -6590,8 +6591,10 @@ public final class ActivityManagerService extends ActivityManagerNative Process.establishZygoteConnectionForAbi(abi); final String instructionSet = VMRuntime.getInstructionSet(abi); if (!completedIsas.contains(instructionSet)) { if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); try { mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); } catch (InstallerException e) { Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e); } completedIsas.add(instructionSet); } Loading
services/core/java/com/android/server/pm/Installer.java +88 −369 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/pm/PackageDexOptimizer.java +15 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.util.ArraySet; import android.util.Log; import android.util.Slog; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.IOException; import java.util.ArrayList; Loading Loading @@ -166,12 +168,13 @@ final class PackageDexOptimizer { | (vmSafeMode ? DEXOPT_SAFEMODE : 0) | (debuggable ? DEXOPT_DEBUGGABLE : 0) | DEXOPT_BOOTCOMPLETE; final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags); // Dex2oat might fail due to compiler / verifier errors. if (ret == 0) { try { mPackageManagerService.mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags); performedDexOpt = true; } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); } } } Loading Loading @@ -210,8 +213,13 @@ final class PackageDexOptimizer { File codePath = new File(pkg.codePath); if (codePath.isDirectory()) { File oatDir = getOatDir(codePath); try { mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(), dexInstructionSet); } catch (InstallerException e) { Slog.w(TAG, "Failed to create oat dir", e); return null; } return oatDir.getAbsolutePath(); } return null; Loading