Merge "Prepare to move dexopt calls to Binder." am: d7b144a5e9
am: 35cbe8ffb0
Change-Id: Ice3c37568ae7185dfe028d3019abf5204aa93963
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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: "
|
||||||
|
|||||||
@@ -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,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_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) {
|
||||||
|
mInstaller = null;
|
||||||
|
mInstalld = null;
|
||||||
|
} else {
|
||||||
|
mInstaller = new InstallerConnection();
|
||||||
mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd"));
|
mInstalld = IInstalld.Stub.asInterface(ServiceManager.getService("installd"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yell loudly if someone tries making future calls while holding a lock on
|
* Yell loudly if someone tries making future calls while holding a lock on
|
||||||
* the given object.
|
* the given object.
|
||||||
*/
|
*/
|
||||||
public void setWarnIfHeld(Object warnIfHeld) {
|
public void setWarnIfHeld(Object warnIfHeld) {
|
||||||
|
if (mInstaller != null) {
|
||||||
mInstaller.setWarnIfHeld(warnIfHeld);
|
mInstaller.setWarnIfHeld(warnIfHeld);
|
||||||
|
}
|
||||||
mWarnIfHeld = warnIfHeld;
|
mWarnIfHeld = warnIfHeld;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
|
if (mInstaller != null) {
|
||||||
Slog.i(TAG, "Waiting for installd to be ready.");
|
Slog.i(TAG, "Waiting for installd to be ready.");
|
||||||
mInstaller.waitForConnection();
|
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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
escaped = "";
|
||||||
|
} else {
|
||||||
|
escaped = String.valueOf(arg);
|
||||||
}
|
}
|
||||||
|
if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) {
|
||||||
@Override
|
throw new IllegalArgumentException(
|
||||||
public synchronized String transact(String cmd) {
|
"Invalid argument while executing " + Arrays.toString(args));
|
||||||
commands.add(cmd);
|
|
||||||
return "0";
|
|
||||||
}
|
}
|
||||||
|
if (TextUtils.isEmpty(escaped)) {
|
||||||
@Override
|
escaped = "!";
|
||||||
public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
|
|
||||||
throw new IllegalStateException("Should not reach here");
|
|
||||||
}
|
}
|
||||||
|
builder.append(' ').append(escaped);
|
||||||
@Override
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2240,8 +2240,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);
|
||||||
|
|||||||
Reference in New Issue
Block a user