Loading core/java/com/android/internal/os/InstallerConnection.java +0 −7 Original line number Diff line number Diff line Loading @@ -134,13 +134,6 @@ public class InstallerConnection { return resRaw; } public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /*outputPath*/, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { Loading core/java/com/android/internal/os/ZygoteInit.java +9 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.ZygoteProcess; import android.os.storage.StorageManager; import android.security.keystore.AndroidKeyStoreProvider; import android.system.ErrnoException; import android.system.Os; Loading Loading @@ -522,10 +523,15 @@ public class ZygoteInit { } if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { final String packageName = "*"; final String outputPath = null; final int dexFlags = 0; final String compilerFilter = "speed"; final String uuid = StorageManager.UUID_PRIVATE_INTERNAL; try { installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet, dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/, sharedLibraries); installer.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, uuid, sharedLibraries); } catch (InstallerException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " Loading services/core/java/com/android/server/pm/Installer.java +65 −48 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ import dalvik.system.VMRuntime; import java.util.Arrays; public final class Installer extends SystemService { public class Installer extends SystemService { private static final String TAG = "Installer"; /* *************************************************************************** Loading @@ -58,52 +58,75 @@ public final class Installer extends SystemService { public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; public static final int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9; private final boolean mIsolated; // TODO: reconnect if installd restarts private final InstallerConnection mInstaller; private final IInstalld mInstalld; private volatile Object mWarnIfHeld; public Installer(Context context) { super(context); mInstaller = new InstallerConnection(); // TODO: reconnect if installd restarts mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd")); this(context, false); } // Package-private installer that accepts a custom InstallerConnection. Used for // OtaDexoptService. Installer(Context context, InstallerConnection connection) { /** * @param isolated indicates if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored * unless you extend this class and intercept them. */ public Installer(Context context, boolean isolated) { super(context); mInstaller = connection; // TODO: reconnect if installd restarts mIsolated = isolated; if (isolated) { mInstaller = null; mInstalld = null; } else { mInstaller = new InstallerConnection(); mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd")); } } /** * Yell loudly if someone tries making future calls while holding a lock on * the given object. */ public void setWarnIfHeld(Object warnIfHeld) { if (mInstaller != null) { mInstaller.setWarnIfHeld(warnIfHeld); } mWarnIfHeld = warnIfHeld; } @Override public void onStart() { if (mInstaller != null) { Slog.i(TAG, "Waiting for installd to be ready."); mInstaller.waitForConnection(); } } private void checkLock() { /** * Do several pre-flight checks before making a remote call. * * @return if the remote call should continue. */ private boolean checkBeforeRemote() { 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 (mIsolated) { Slog.i(TAG, "Ignoring request because this installer is isolated"); return false; } else { return true; } } public void createAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo, int targetSdkVersion) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo, targetSdkVersion); Loading @@ -114,7 +137,7 @@ public final class Installer extends SystemService { public void restoreconAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.restoreconAppData(uuid, packageName, userId, flags, appId, seInfo); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -124,7 +147,7 @@ public final class Installer extends SystemService { public void migrateAppData(String uuid, String packageName, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.migrateAppData(uuid, packageName, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -134,7 +157,7 @@ public final class Installer extends SystemService { public void clearAppData(String uuid, String packageName, int userId, int flags, long ceDataInode) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -144,7 +167,7 @@ public final class Installer extends SystemService { public void destroyAppData(String uuid, String packageName, int userId, int flags, long ceDataInode) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyAppData(uuid, packageName, userId, flags, ceDataInode); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -155,7 +178,7 @@ public final class Installer extends SystemService { public void moveCompleteApp(String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seInfo, int targetSdkVersion) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.moveCompleteApp(fromUuid, toUuid, packageName, dataAppName, appId, seInfo, targetSdkVersion); Loading @@ -166,6 +189,7 @@ public final class Installer extends SystemService { public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode, String codePath, PackageStats stats) throws InstallerException { if (!checkBeforeRemote()) return; final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags, ceDataInode, codePath); try { Loading @@ -179,7 +203,7 @@ public final class Installer extends SystemService { public long getAppDataInode(String uuid, String packageName, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return -1; try { return mInstalld.getAppDataInode(uuid, packageName, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -187,25 +211,18 @@ public final class Installer extends SystemService { } } public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { assertValidInstructionSet(instructionSet); mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public boolean mergeProfiles(int uid, String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return false; try { return mInstalld.mergeProfiles(uid, packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -215,7 +232,7 @@ public final class Installer extends SystemService { public boolean dumpProfiles(int uid, String packageName, String codePaths) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return false; try { return mInstalld.dumpProfiles(uid, packageName, codePaths); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -225,7 +242,7 @@ public final class Installer extends SystemService { public void idmap(String targetApkPath, String overlayApkPath, int uid) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.idmap(targetApkPath, overlayApkPath, uid); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -235,7 +252,7 @@ public final class Installer extends SystemService { public void rmdex(String codePath, String instructionSet) throws InstallerException { assertValidInstructionSet(instructionSet); checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.rmdex(codePath, instructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -244,7 +261,7 @@ public final class Installer extends SystemService { } public void rmPackageDir(String packageDir) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.rmPackageDir(packageDir); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -253,7 +270,7 @@ public final class Installer extends SystemService { } public void clearAppProfiles(String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.clearAppProfiles(packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -262,7 +279,7 @@ public final class Installer extends SystemService { } public void destroyAppProfiles(String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyAppProfiles(packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -272,7 +289,7 @@ public final class Installer extends SystemService { public void createUserData(String uuid, int userId, int userSerial, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createUserData(uuid, userId, userSerial, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -281,7 +298,7 @@ public final class Installer extends SystemService { } public void destroyUserData(String uuid, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyUserData(uuid, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -291,7 +308,7 @@ public final class Installer extends SystemService { public void markBootComplete(String instructionSet) throws InstallerException { assertValidInstructionSet(instructionSet); checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.markBootComplete(instructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -300,7 +317,7 @@ public final class Installer extends SystemService { } public void freeCache(String uuid, long freeStorageSize) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.freeCache(uuid, freeStorageSize); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -315,7 +332,7 @@ public final class Installer extends SystemService { */ public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32, int userId) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -325,7 +342,7 @@ public final class Installer extends SystemService { public void createOatDir(String oatDir, String dexInstructionSet) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createOatDir(oatDir, dexInstructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -335,7 +352,7 @@ public final class Installer extends SystemService { public void linkFile(String relativePath, String fromBase, String toBase) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.linkFile(relativePath, fromBase, toBase); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -345,7 +362,7 @@ public final class Installer extends SystemService { public void moveAb(String apkPath, String instructionSet, String outputPath) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.moveAb(apkPath, instructionSet, outputPath); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -355,7 +372,7 @@ public final class Installer extends SystemService { public void deleteOdex(String apkPath, String instructionSet, String outputPath) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.deleteOdex(apkPath, instructionSet, outputPath); } catch (RemoteException | ServiceSpecificException e) { Loading services/core/java/com/android/server/pm/OtaDexoptService.java +47 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; import android.annotation.Nullable; import android.content.Context; import android.content.pm.IOtaDexopt; import android.content.pm.PackageParser; Loading @@ -29,15 +30,17 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.InstallerConnection; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; Loading Loading @@ -276,9 +279,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub { */ private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg, int compilationReason) { // Use our custom connection that just collects the commands. RecordingInstallerConnection collectingConnection = new RecordingInstallerConnection(); Installer collectingInstaller = new Installer(mContext, collectingConnection); // Intercept and collect dexopt requests final List<String> commands = new ArrayList<String>(); final Installer collectingInstaller = new Installer(mContext, true) { @Override public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries) throws InstallerException { commands.add(buildCommand("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries)); } }; // Use the package manager install and install lock here for the OTA dex optimizer. PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( Loading @@ -295,7 +316,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */); return collectingConnection.commands; return commands; } @Override Loading Loading @@ -414,39 +435,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub { } private static class RecordingInstallerConnection extends InstallerConnection { public List<String> commands = new ArrayList<String>(1); @Override public void setWarnIfHeld(Object warnIfHeld) { throw new IllegalStateException("Should not reach here"); } @Override public synchronized String transact(String cmd) { commands.add(cmd); return "0"; } @Override public boolean mergeProfiles(int uid, String pkgName) throws InstallerException { throw new IllegalStateException("Should not reach here"); /** * Cook up argument list in the format that {@code installd} expects. */ private static String buildCommand(Object... args) { final StringBuilder builder = new StringBuilder(); for (Object arg : args) { String escaped; if (arg == null) { escaped = ""; } else { escaped = String.valueOf(arg); } @Override public boolean dumpProfiles(String gid, String packageName, String codePaths) throws InstallerException { throw new IllegalStateException("Should not reach here"); if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) { throw new IllegalArgumentException( "Invalid argument while executing " + Arrays.toString(args)); } @Override public void disconnect() { throw new IllegalStateException("Should not reach here"); if (TextUtils.isEmpty(escaped)) { escaped = "!"; } @Override public void waitForConnection() { throw new IllegalStateException("Should not reach here"); builder.append(' ').append(escaped); } return builder.toString(); } } services/core/java/com/android/server/pm/PackageManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -2228,8 +2228,9 @@ public class PackageManagerService extends IPackageManager.Stub { getCompilerFilterForReason(REASON_SHARED_APK), false /* newProfile */); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, mInstaller.dexopt(lib, Process.SYSTEM_UID, "*", dexCodeInstructionSet, dexoptNeeded, null, DEXOPT_PUBLIC, getCompilerFilterForReason(REASON_SHARED_APK), StorageManager.UUID_PRIVATE_INTERNAL, SKIP_SHARED_LIBRARY_CHECK); Loading Loading
core/java/com/android/internal/os/InstallerConnection.java +0 −7 Original line number Diff line number Diff line Loading @@ -134,13 +134,6 @@ public class InstallerConnection { return resRaw; } public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /*outputPath*/, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { Loading
core/java/com/android/internal/os/ZygoteInit.java +9 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.ZygoteProcess; import android.os.storage.StorageManager; import android.security.keystore.AndroidKeyStoreProvider; import android.system.ErrnoException; import android.system.Os; Loading Loading @@ -522,10 +523,15 @@ public class ZygoteInit { } if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { final String packageName = "*"; final String outputPath = null; final int dexFlags = 0; final String compilerFilter = "speed"; final String uuid = StorageManager.UUID_PRIVATE_INTERNAL; try { installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet, dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/, sharedLibraries); installer.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, uuid, sharedLibraries); } catch (InstallerException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " Loading
services/core/java/com/android/server/pm/Installer.java +65 −48 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ import dalvik.system.VMRuntime; import java.util.Arrays; public final class Installer extends SystemService { public class Installer extends SystemService { private static final String TAG = "Installer"; /* *************************************************************************** Loading @@ -58,52 +58,75 @@ public final class Installer extends SystemService { public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; public static final int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9; private final boolean mIsolated; // TODO: reconnect if installd restarts private final InstallerConnection mInstaller; private final IInstalld mInstalld; private volatile Object mWarnIfHeld; public Installer(Context context) { super(context); mInstaller = new InstallerConnection(); // TODO: reconnect if installd restarts mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd")); this(context, false); } // Package-private installer that accepts a custom InstallerConnection. Used for // OtaDexoptService. Installer(Context context, InstallerConnection connection) { /** * @param isolated indicates if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored * unless you extend this class and intercept them. */ public Installer(Context context, boolean isolated) { super(context); mInstaller = connection; // TODO: reconnect if installd restarts mIsolated = isolated; if (isolated) { mInstaller = null; mInstalld = null; } else { mInstaller = new InstallerConnection(); mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd")); } } /** * Yell loudly if someone tries making future calls while holding a lock on * the given object. */ public void setWarnIfHeld(Object warnIfHeld) { if (mInstaller != null) { mInstaller.setWarnIfHeld(warnIfHeld); } mWarnIfHeld = warnIfHeld; } @Override public void onStart() { if (mInstaller != null) { Slog.i(TAG, "Waiting for installd to be ready."); mInstaller.waitForConnection(); } } private void checkLock() { /** * Do several pre-flight checks before making a remote call. * * @return if the remote call should continue. */ private boolean checkBeforeRemote() { 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 (mIsolated) { Slog.i(TAG, "Ignoring request because this installer is isolated"); return false; } else { return true; } } public void createAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo, int targetSdkVersion) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo, targetSdkVersion); Loading @@ -114,7 +137,7 @@ public final class Installer extends SystemService { public void restoreconAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.restoreconAppData(uuid, packageName, userId, flags, appId, seInfo); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -124,7 +147,7 @@ public final class Installer extends SystemService { public void migrateAppData(String uuid, String packageName, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.migrateAppData(uuid, packageName, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -134,7 +157,7 @@ public final class Installer extends SystemService { public void clearAppData(String uuid, String packageName, int userId, int flags, long ceDataInode) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -144,7 +167,7 @@ public final class Installer extends SystemService { public void destroyAppData(String uuid, String packageName, int userId, int flags, long ceDataInode) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyAppData(uuid, packageName, userId, flags, ceDataInode); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -155,7 +178,7 @@ public final class Installer extends SystemService { public void moveCompleteApp(String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seInfo, int targetSdkVersion) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.moveCompleteApp(fromUuid, toUuid, packageName, dataAppName, appId, seInfo, targetSdkVersion); Loading @@ -166,6 +189,7 @@ public final class Installer extends SystemService { public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode, String codePath, PackageStats stats) throws InstallerException { if (!checkBeforeRemote()) return; final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags, ceDataInode, codePath); try { Loading @@ -179,7 +203,7 @@ public final class Installer extends SystemService { public long getAppDataInode(String uuid, String packageName, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return -1; try { return mInstalld.getAppDataInode(uuid, packageName, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -187,25 +211,18 @@ public final class Installer extends SystemService { } } public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) throws InstallerException { assertValidInstructionSet(instructionSet); mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public void dexopt(String apkPath, int uid, String pkgName, String instructionSet, public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries) String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries); } public boolean mergeProfiles(int uid, String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return false; try { return mInstalld.mergeProfiles(uid, packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -215,7 +232,7 @@ public final class Installer extends SystemService { public boolean dumpProfiles(int uid, String packageName, String codePaths) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return false; try { return mInstalld.dumpProfiles(uid, packageName, codePaths); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -225,7 +242,7 @@ public final class Installer extends SystemService { public void idmap(String targetApkPath, String overlayApkPath, int uid) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.idmap(targetApkPath, overlayApkPath, uid); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -235,7 +252,7 @@ public final class Installer extends SystemService { public void rmdex(String codePath, String instructionSet) throws InstallerException { assertValidInstructionSet(instructionSet); checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.rmdex(codePath, instructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -244,7 +261,7 @@ public final class Installer extends SystemService { } public void rmPackageDir(String packageDir) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.rmPackageDir(packageDir); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -253,7 +270,7 @@ public final class Installer extends SystemService { } public void clearAppProfiles(String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.clearAppProfiles(packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -262,7 +279,7 @@ public final class Installer extends SystemService { } public void destroyAppProfiles(String packageName) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyAppProfiles(packageName); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -272,7 +289,7 @@ public final class Installer extends SystemService { public void createUserData(String uuid, int userId, int userSerial, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createUserData(uuid, userId, userSerial, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -281,7 +298,7 @@ public final class Installer extends SystemService { } public void destroyUserData(String uuid, int userId, int flags) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.destroyUserData(uuid, userId, flags); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -291,7 +308,7 @@ public final class Installer extends SystemService { public void markBootComplete(String instructionSet) throws InstallerException { assertValidInstructionSet(instructionSet); checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.markBootComplete(instructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -300,7 +317,7 @@ public final class Installer extends SystemService { } public void freeCache(String uuid, long freeStorageSize) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.freeCache(uuid, freeStorageSize); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -315,7 +332,7 @@ public final class Installer extends SystemService { */ public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32, int userId) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -325,7 +342,7 @@ public final class Installer extends SystemService { public void createOatDir(String oatDir, String dexInstructionSet) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.createOatDir(oatDir, dexInstructionSet); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -335,7 +352,7 @@ public final class Installer extends SystemService { public void linkFile(String relativePath, String fromBase, String toBase) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.linkFile(relativePath, fromBase, toBase); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -345,7 +362,7 @@ public final class Installer extends SystemService { public void moveAb(String apkPath, String instructionSet, String outputPath) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.moveAb(apkPath, instructionSet, outputPath); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -355,7 +372,7 @@ public final class Installer extends SystemService { public void deleteOdex(String apkPath, String instructionSet, String outputPath) throws InstallerException { checkLock(); if (!checkBeforeRemote()) return; try { mInstalld.deleteOdex(apkPath, instructionSet, outputPath); } catch (RemoteException | ServiceSpecificException e) { Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +47 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; import android.annotation.Nullable; import android.content.Context; import android.content.pm.IOtaDexopt; import android.content.pm.PackageParser; Loading @@ -29,15 +30,17 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.InstallerConnection; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; Loading Loading @@ -276,9 +279,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub { */ private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg, int compilationReason) { // Use our custom connection that just collects the commands. RecordingInstallerConnection collectingConnection = new RecordingInstallerConnection(); Installer collectingInstaller = new Installer(mContext, collectingConnection); // Intercept and collect dexopt requests final List<String> commands = new ArrayList<String>(); final Installer collectingInstaller = new Installer(mContext, true) { @Override public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries) throws InstallerException { commands.add(buildCommand("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries)); } }; // Use the package manager install and install lock here for the OTA dex optimizer. PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( Loading @@ -295,7 +316,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */); return collectingConnection.commands; return commands; } @Override Loading Loading @@ -414,39 +435,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub { } private static class RecordingInstallerConnection extends InstallerConnection { public List<String> commands = new ArrayList<String>(1); @Override public void setWarnIfHeld(Object warnIfHeld) { throw new IllegalStateException("Should not reach here"); } @Override public synchronized String transact(String cmd) { commands.add(cmd); return "0"; } @Override public boolean mergeProfiles(int uid, String pkgName) throws InstallerException { throw new IllegalStateException("Should not reach here"); /** * Cook up argument list in the format that {@code installd} expects. */ private static String buildCommand(Object... args) { final StringBuilder builder = new StringBuilder(); for (Object arg : args) { String escaped; if (arg == null) { escaped = ""; } else { escaped = String.valueOf(arg); } @Override public boolean dumpProfiles(String gid, String packageName, String codePaths) throws InstallerException { throw new IllegalStateException("Should not reach here"); if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) { throw new IllegalArgumentException( "Invalid argument while executing " + Arrays.toString(args)); } @Override public void disconnect() { throw new IllegalStateException("Should not reach here"); if (TextUtils.isEmpty(escaped)) { escaped = "!"; } @Override public void waitForConnection() { throw new IllegalStateException("Should not reach here"); builder.append(' ').append(escaped); } return builder.toString(); } }
services/core/java/com/android/server/pm/PackageManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -2228,8 +2228,9 @@ public class PackageManagerService extends IPackageManager.Stub { getCompilerFilterForReason(REASON_SHARED_APK), false /* newProfile */); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, mInstaller.dexopt(lib, Process.SYSTEM_UID, "*", dexCodeInstructionSet, dexoptNeeded, null, DEXOPT_PUBLIC, getCompilerFilterForReason(REASON_SHARED_APK), StorageManager.UUID_PRIVATE_INTERNAL, SKIP_SHARED_LIBRARY_CHECK); Loading