Merge "Prepare to move dexopt calls to Binder."

am: d7b144a5e9

Change-Id: I49cce8519d5b09a646609fffc6e62ecbe1a086ef
This commit is contained in:
Jeff Sharkey
2016-12-09 16:53:46 +00:00
committed by android-build-merger
5 changed files with 124 additions and 98 deletions

View File

@@ -134,13 +134,6 @@ public class InstallerConnection {
return resRaw; 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, public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter, int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter,
String volumeUuid, String sharedLibraries) throws InstallerException { String volumeUuid, String sharedLibraries) throws InstallerException {

View File

@@ -31,6 +31,7 @@ import android.os.SystemClock;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.Trace; import android.os.Trace;
import android.os.ZygoteProcess; import android.os.ZygoteProcess;
import android.os.storage.StorageManager;
import android.security.keystore.AndroidKeyStoreProvider; import android.security.keystore.AndroidKeyStoreProvider;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
@@ -522,10 +523,15 @@ public class ZygoteInit {
} }
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 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 { try {
installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet, installer.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
sharedLibraries); uuid, sharedLibraries);
} catch (InstallerException e) { } catch (InstallerException e) {
// Ignore (but log), we need this on the classpath for fallback mode. // Ignore (but log), we need this on the classpath for fallback mode.
Log.w(TAG, "Failed compiling classpath element for system server: " Log.w(TAG, "Failed compiling classpath element for system server: "

View File

@@ -34,7 +34,7 @@ import dalvik.system.VMRuntime;
import java.util.Arrays; import java.util.Arrays;
public final class Installer extends SystemService { public class Installer extends SystemService {
private static final String TAG = "Installer"; private static final String TAG = "Installer";
/* *************************************************************************** /* ***************************************************************************
@@ -58,25 +58,33 @@ public final class Installer extends SystemService {
public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
public static final int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9; 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 InstallerConnection mInstaller;
private final IInstalld mInstalld; private final IInstalld mInstalld;
private volatile Object mWarnIfHeld; private volatile Object mWarnIfHeld;
public Installer(Context context) { public Installer(Context context) {
super(context); this(context, false);
mInstaller = new InstallerConnection();
// TODO: reconnect if installd restarts
mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd"));
} }
// Package-private installer that accepts a custom InstallerConnection. Used for /**
// OtaDexoptService. * @param isolated indicates if this object should <em>not</em> connect to
Installer(Context context, InstallerConnection connection) { * 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); super(context);
mInstaller = connection; mIsolated = isolated;
// TODO: reconnect if installd restarts if (isolated) {
mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd")); mInstaller = null;
mInstalld = null;
} else {
mInstaller = new InstallerConnection();
mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd"));
}
} }
/** /**
@@ -84,26 +92,41 @@ public final class Installer extends SystemService {
* the given object. * the given object.
*/ */
public void setWarnIfHeld(Object warnIfHeld) { public void setWarnIfHeld(Object warnIfHeld) {
mInstaller.setWarnIfHeld(warnIfHeld); if (mInstaller != null) {
mInstaller.setWarnIfHeld(warnIfHeld);
}
mWarnIfHeld = warnIfHeld; mWarnIfHeld = warnIfHeld;
} }
@Override @Override
public void onStart() { public void onStart() {
Slog.i(TAG, "Waiting for installd to be ready."); if (mInstaller != null) {
mInstaller.waitForConnection(); 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)) { if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x" Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
+ Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable()); + 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, public void createAppData(String uuid, String packageName, int userId, int flags, int appId,
String seInfo, int targetSdkVersion) throws InstallerException { String seInfo, int targetSdkVersion) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo, mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo,
targetSdkVersion); targetSdkVersion);
@@ -114,7 +137,7 @@ public final class Installer extends SystemService {
public void restoreconAppData(String uuid, String packageName, int userId, int flags, int appId, public void restoreconAppData(String uuid, String packageName, int userId, int flags, int appId,
String seInfo) throws InstallerException { String seInfo) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.restoreconAppData(uuid, packageName, userId, flags, appId, seInfo); mInstalld.restoreconAppData(uuid, packageName, userId, flags, appId, seInfo);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -124,7 +147,7 @@ public final class Installer extends SystemService {
public void migrateAppData(String uuid, String packageName, int userId, int flags) public void migrateAppData(String uuid, String packageName, int userId, int flags)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.migrateAppData(uuid, packageName, userId, flags); mInstalld.migrateAppData(uuid, packageName, userId, flags);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -134,7 +157,7 @@ public final class Installer extends SystemService {
public void clearAppData(String uuid, String packageName, int userId, int flags, public void clearAppData(String uuid, String packageName, int userId, int flags,
long ceDataInode) throws InstallerException { long ceDataInode) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode); mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -144,7 +167,7 @@ public final class Installer extends SystemService {
public void destroyAppData(String uuid, String packageName, int userId, int flags, public void destroyAppData(String uuid, String packageName, int userId, int flags,
long ceDataInode) throws InstallerException { long ceDataInode) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.destroyAppData(uuid, packageName, userId, flags, ceDataInode); mInstalld.destroyAppData(uuid, packageName, userId, flags, ceDataInode);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -155,7 +178,7 @@ public final class Installer extends SystemService {
public void moveCompleteApp(String fromUuid, String toUuid, String packageName, public void moveCompleteApp(String fromUuid, String toUuid, String packageName,
String dataAppName, int appId, String seInfo, int targetSdkVersion) String dataAppName, int appId, String seInfo, int targetSdkVersion)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.moveCompleteApp(fromUuid, toUuid, packageName, dataAppName, appId, seInfo, mInstalld.moveCompleteApp(fromUuid, toUuid, packageName, dataAppName, appId, seInfo,
targetSdkVersion); targetSdkVersion);
@@ -166,6 +189,7 @@ public final class Installer extends SystemService {
public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode, public void getAppSize(String uuid, String pkgname, int userid, int flags, long ceDataInode,
String codePath, PackageStats stats) throws InstallerException { String codePath, PackageStats stats) throws InstallerException {
if (!checkBeforeRemote()) return;
final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags, final String[] res = mInstaller.execute("get_app_size", uuid, pkgname, userid, flags,
ceDataInode, codePath); ceDataInode, codePath);
try { try {
@@ -179,7 +203,7 @@ public final class Installer extends SystemService {
public long getAppDataInode(String uuid, String packageName, int userId, int flags) public long getAppDataInode(String uuid, String packageName, int userId, int flags)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return -1;
try { try {
return mInstalld.getAppDataInode(uuid, packageName, userId, flags); return mInstalld.getAppDataInode(uuid, packageName, userId, flags);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -187,25 +211,18 @@ public final class Installer extends SystemService {
} }
} }
public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded, public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet,
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,
int dexoptNeeded, @Nullable String outputPath, int dexFlags, int dexoptNeeded, @Nullable String outputPath, int dexFlags,
String compilerFilter, String volumeUuid, String sharedLibraries) String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries)
throws InstallerException { throws InstallerException {
assertValidInstructionSet(instructionSet); assertValidInstructionSet(instructionSet);
if (!checkBeforeRemote()) return;
mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries); outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries);
} }
public boolean mergeProfiles(int uid, String packageName) throws InstallerException { public boolean mergeProfiles(int uid, String packageName) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return false;
try { try {
return mInstalld.mergeProfiles(uid, packageName); return mInstalld.mergeProfiles(uid, packageName);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -215,7 +232,7 @@ public final class Installer extends SystemService {
public boolean dumpProfiles(int uid, String packageName, String codePaths) public boolean dumpProfiles(int uid, String packageName, String codePaths)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return false;
try { try {
return mInstalld.dumpProfiles(uid, packageName, codePaths); return mInstalld.dumpProfiles(uid, packageName, codePaths);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -225,7 +242,7 @@ public final class Installer extends SystemService {
public void idmap(String targetApkPath, String overlayApkPath, int uid) public void idmap(String targetApkPath, String overlayApkPath, int uid)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.idmap(targetApkPath, overlayApkPath, uid); mInstalld.idmap(targetApkPath, overlayApkPath, uid);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -235,7 +252,7 @@ public final class Installer extends SystemService {
public void rmdex(String codePath, String instructionSet) throws InstallerException { public void rmdex(String codePath, String instructionSet) throws InstallerException {
assertValidInstructionSet(instructionSet); assertValidInstructionSet(instructionSet);
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.rmdex(codePath, instructionSet); mInstalld.rmdex(codePath, instructionSet);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -244,7 +261,7 @@ public final class Installer extends SystemService {
} }
public void rmPackageDir(String packageDir) throws InstallerException { public void rmPackageDir(String packageDir) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.rmPackageDir(packageDir); mInstalld.rmPackageDir(packageDir);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -253,7 +270,7 @@ public final class Installer extends SystemService {
} }
public void clearAppProfiles(String packageName) throws InstallerException { public void clearAppProfiles(String packageName) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.clearAppProfiles(packageName); mInstalld.clearAppProfiles(packageName);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -262,7 +279,7 @@ public final class Installer extends SystemService {
} }
public void destroyAppProfiles(String packageName) throws InstallerException { public void destroyAppProfiles(String packageName) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.destroyAppProfiles(packageName); mInstalld.destroyAppProfiles(packageName);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -272,7 +289,7 @@ public final class Installer extends SystemService {
public void createUserData(String uuid, int userId, int userSerial, int flags) public void createUserData(String uuid, int userId, int userSerial, int flags)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.createUserData(uuid, userId, userSerial, flags); mInstalld.createUserData(uuid, userId, userSerial, flags);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -281,7 +298,7 @@ public final class Installer extends SystemService {
} }
public void destroyUserData(String uuid, int userId, int flags) throws InstallerException { public void destroyUserData(String uuid, int userId, int flags) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.destroyUserData(uuid, userId, flags); mInstalld.destroyUserData(uuid, userId, flags);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -291,7 +308,7 @@ public final class Installer extends SystemService {
public void markBootComplete(String instructionSet) throws InstallerException { public void markBootComplete(String instructionSet) throws InstallerException {
assertValidInstructionSet(instructionSet); assertValidInstructionSet(instructionSet);
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.markBootComplete(instructionSet); mInstalld.markBootComplete(instructionSet);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -300,7 +317,7 @@ public final class Installer extends SystemService {
} }
public void freeCache(String uuid, long freeStorageSize) throws InstallerException { public void freeCache(String uuid, long freeStorageSize) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.freeCache(uuid, freeStorageSize); mInstalld.freeCache(uuid, freeStorageSize);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -315,7 +332,7 @@ public final class Installer extends SystemService {
*/ */
public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32, public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32,
int userId) throws InstallerException { int userId) throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId); mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -325,7 +342,7 @@ public final class Installer extends SystemService {
public void createOatDir(String oatDir, String dexInstructionSet) public void createOatDir(String oatDir, String dexInstructionSet)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.createOatDir(oatDir, dexInstructionSet); mInstalld.createOatDir(oatDir, dexInstructionSet);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -335,7 +352,7 @@ public final class Installer extends SystemService {
public void linkFile(String relativePath, String fromBase, String toBase) public void linkFile(String relativePath, String fromBase, String toBase)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.linkFile(relativePath, fromBase, toBase); mInstalld.linkFile(relativePath, fromBase, toBase);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -345,7 +362,7 @@ public final class Installer extends SystemService {
public void moveAb(String apkPath, String instructionSet, String outputPath) public void moveAb(String apkPath, String instructionSet, String outputPath)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.moveAb(apkPath, instructionSet, outputPath); mInstalld.moveAb(apkPath, instructionSet, outputPath);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
@@ -355,7 +372,7 @@ public final class Installer extends SystemService {
public void deleteOdex(String apkPath, String instructionSet, String outputPath) public void deleteOdex(String apkPath, String instructionSet, String outputPath)
throws InstallerException { throws InstallerException {
checkLock(); if (!checkBeforeRemote()) return;
try { try {
mInstalld.deleteOdex(apkPath, instructionSet, outputPath); mInstalld.deleteOdex(apkPath, instructionSet, outputPath);
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {

View File

@@ -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.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.content.pm.IOtaDexopt; import android.content.pm.IOtaDexopt;
import android.content.pm.PackageParser; import android.content.pm.PackageParser;
@@ -29,15 +30,17 @@ import android.os.RemoteException;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.util.Slog; import android.util.Slog;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.InstallerConnection;
import com.android.internal.os.InstallerConnection.InstallerException; import com.android.internal.os.InstallerConnection.InstallerException;
import java.io.File; import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -276,9 +279,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
*/ */
private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg, private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg,
int compilationReason) { int compilationReason) {
// Use our custom connection that just collects the commands. // Intercept and collect dexopt requests
RecordingInstallerConnection collectingConnection = new RecordingInstallerConnection(); final List<String> commands = new ArrayList<String>();
Installer collectingInstaller = new Installer(mContext, collectingConnection); 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. // Use the package manager install and install lock here for the OTA dex optimizer.
PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer(
@@ -295,7 +316,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
getCompilerFilterForReason(compilationReason), getCompilerFilterForReason(compilationReason),
null /* CompilerStats.PackageStats */); null /* CompilerStats.PackageStats */);
return collectingConnection.commands; return commands;
} }
@Override @Override
@@ -414,39 +435,27 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
} }
private static class RecordingInstallerConnection extends InstallerConnection { /**
public List<String> commands = new ArrayList<String>(1); * Cook up argument list in the format that {@code installd} expects.
*/
@Override private static String buildCommand(Object... args) {
public void setWarnIfHeld(Object warnIfHeld) { final StringBuilder builder = new StringBuilder();
throw new IllegalStateException("Should not reach here"); for (Object arg : args) {
} String escaped;
if (arg == null) {
@Override escaped = "";
public synchronized String transact(String cmd) { } else {
commands.add(cmd); escaped = String.valueOf(arg);
return "0"; }
} if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) {
throw new IllegalArgumentException(
@Override "Invalid argument while executing " + Arrays.toString(args));
public boolean mergeProfiles(int uid, String pkgName) throws InstallerException { }
throw new IllegalStateException("Should not reach here"); if (TextUtils.isEmpty(escaped)) {
} escaped = "!";
}
@Override builder.append(' ').append(escaped);
public boolean dumpProfiles(String gid, String packageName, String codePaths)
throws InstallerException {
throw new IllegalStateException("Should not reach here");
}
@Override
public void disconnect() {
throw new IllegalStateException("Should not reach here");
}
@Override
public void waitForConnection() {
throw new IllegalStateException("Should not reach here");
} }
return builder.toString();
} }
} }

View File

@@ -2228,8 +2228,9 @@ public class PackageManagerService extends IPackageManager.Stub {
getCompilerFilterForReason(REASON_SHARED_APK), getCompilerFilterForReason(REASON_SHARED_APK),
false /* newProfile */); false /* newProfile */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, mInstaller.dexopt(lib, Process.SYSTEM_UID, "*",
dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, dexCodeInstructionSet, dexoptNeeded, null,
DEXOPT_PUBLIC,
getCompilerFilterForReason(REASON_SHARED_APK), getCompilerFilterForReason(REASON_SHARED_APK),
StorageManager.UUID_PRIVATE_INTERNAL, StorageManager.UUID_PRIVATE_INTERNAL,
SKIP_SHARED_LIBRARY_CHECK); SKIP_SHARED_LIBRARY_CHECK);