Call into ART Service for profile snapshotting when it is enabled.
Test: adb root
adb shell setprop dalvik.vm.profilebootclasspath true
adb shell pm snapshot-profile android
adb shell pm snapshot-profile com.android.egg
adb shell pm snapshot-profile com.android.egg \
--code-path /system/app/EasterEgg/EasterEgg.apk
with dalvik.vm.useartservice=true
Bug: 251903639
Change-Id: Id49c381162e6f73d77e6bb80af54b9cbe5f7d739
This commit is contained in:
@@ -50,11 +50,15 @@ import com.android.internal.os.RoSystemProperties;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.art.ArtManagerLocal;
|
||||
import com.android.server.pm.DexOptHelper;
|
||||
import com.android.server.pm.Installer;
|
||||
import com.android.server.pm.Installer.InstallerException;
|
||||
import com.android.server.pm.Installer.LegacyDexoptDisabledException;
|
||||
import com.android.server.pm.PackageManagerLocal;
|
||||
import com.android.server.pm.PackageManagerService;
|
||||
import com.android.server.pm.PackageManagerServiceCompilerMapping;
|
||||
import com.android.server.pm.PackageManagerServiceUtils;
|
||||
import com.android.server.pm.parsing.PackageInfoUtils;
|
||||
import com.android.server.pm.pkg.AndroidPackage;
|
||||
import com.android.server.pm.pkg.PackageState;
|
||||
@@ -210,20 +214,15 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
|
||||
Slog.d(TAG, "Requested snapshot for " + packageName + ":" + codePath);
|
||||
}
|
||||
|
||||
// TODO(b/251903639): Call into ART Service.
|
||||
try {
|
||||
if (bootImageProfile) {
|
||||
snapshotBootImageProfile(callback);
|
||||
} else {
|
||||
snapshotAppProfile(packageName, codePath, callback);
|
||||
}
|
||||
} catch (LegacyDexoptDisabledException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (bootImageProfile) {
|
||||
snapshotBootImageProfile(callback);
|
||||
} else {
|
||||
snapshotAppProfile(packageName, codePath, callback);
|
||||
}
|
||||
}
|
||||
|
||||
private void snapshotAppProfile(String packageName, String codePath,
|
||||
ISnapshotRuntimeProfileCallback callback) throws LegacyDexoptDisabledException {
|
||||
private void snapshotAppProfile(
|
||||
String packageName, String codePath, ISnapshotRuntimeProfileCallback callback) {
|
||||
PackageInfo info = null;
|
||||
try {
|
||||
// Note that we use the default user 0 to retrieve the package info.
|
||||
@@ -260,17 +259,45 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
|
||||
}
|
||||
|
||||
// All good, create the profile snapshot.
|
||||
int appId = UserHandle.getAppId(info.applicationInfo.uid);
|
||||
if (appId < 0) {
|
||||
postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
|
||||
Slog.wtf(TAG, "AppId is -1 for package: " + packageName);
|
||||
return;
|
||||
}
|
||||
if (DexOptHelper.useArtService()) {
|
||||
ParcelFileDescriptor fd;
|
||||
|
||||
createProfileSnapshot(packageName, ArtManager.getProfileName(splitName), codePath,
|
||||
appId, callback);
|
||||
// Destroy the snapshot, we no longer need it.
|
||||
destroyProfileSnapshot(packageName, ArtManager.getProfileName(splitName));
|
||||
try (PackageManagerLocal.FilteredSnapshot snapshot =
|
||||
PackageManagerServiceUtils.getPackageManagerLocal()
|
||||
.withFilteredSnapshot()) {
|
||||
fd = DexOptHelper.getArtManagerLocal().snapshotAppProfile(
|
||||
snapshot, packageName, splitName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// ArtManagerLocal.snapshotAppProfile couldn't find the package or split. Since
|
||||
// we've checked them above this can only happen due to race, i.e. the package got
|
||||
// removed. So let's report it as SNAPSHOT_FAILED_PACKAGE_NOT_FOUND even if it was
|
||||
// for the split.
|
||||
// TODO(mast): Reuse the same snapshot to avoid this race.
|
||||
postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_PACKAGE_NOT_FOUND);
|
||||
return;
|
||||
} catch (IllegalStateException | ArtManagerLocal.SnapshotProfileException e) {
|
||||
postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
postSuccess(packageName, fd, callback);
|
||||
} else {
|
||||
int appId = UserHandle.getAppId(info.applicationInfo.uid);
|
||||
if (appId < 0) {
|
||||
postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
|
||||
Slog.wtf(TAG, "AppId is -1 for package: " + packageName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
createProfileSnapshot(packageName, ArtManager.getProfileName(splitName), codePath,
|
||||
appId, callback);
|
||||
// Destroy the snapshot, we no longer need it.
|
||||
destroyProfileSnapshot(packageName, ArtManager.getProfileName(splitName));
|
||||
} catch (LegacyDexoptDisabledException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createProfileSnapshot(String packageName, String profileName, String classpath,
|
||||
@@ -340,23 +367,43 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void snapshotBootImageProfile(ISnapshotRuntimeProfileCallback callback)
|
||||
throws LegacyDexoptDisabledException {
|
||||
// Combine the profiles for boot classpath and system server classpath.
|
||||
// This avoids having yet another type of profiles and simplifies the processing.
|
||||
String classpath = String.join(":", Os.getenv("BOOTCLASSPATH"),
|
||||
Os.getenv("SYSTEMSERVERCLASSPATH"));
|
||||
private void snapshotBootImageProfile(ISnapshotRuntimeProfileCallback callback) {
|
||||
if (DexOptHelper.useArtService()) {
|
||||
ParcelFileDescriptor fd;
|
||||
|
||||
final String standaloneSystemServerJars = Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
|
||||
if (standaloneSystemServerJars != null) {
|
||||
classpath = String.join(":", classpath, standaloneSystemServerJars);
|
||||
try (PackageManagerLocal.FilteredSnapshot snapshot =
|
||||
PackageManagerServiceUtils.getPackageManagerLocal()
|
||||
.withFilteredSnapshot()) {
|
||||
fd = DexOptHelper.getArtManagerLocal().snapshotBootImageProfile(snapshot);
|
||||
} catch (IllegalStateException | ArtManagerLocal.SnapshotProfileException e) {
|
||||
postError(callback, BOOT_IMAGE_ANDROID_PACKAGE,
|
||||
ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
postSuccess(BOOT_IMAGE_ANDROID_PACKAGE, fd, callback);
|
||||
} else {
|
||||
// Combine the profiles for boot classpath and system server classpath.
|
||||
// This avoids having yet another type of profiles and simplifies the processing.
|
||||
String classpath = String.join(
|
||||
":", Os.getenv("BOOTCLASSPATH"), Os.getenv("SYSTEMSERVERCLASSPATH"));
|
||||
|
||||
final String standaloneSystemServerJars = Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
|
||||
if (standaloneSystemServerJars != null) {
|
||||
classpath = String.join(":", classpath, standaloneSystemServerJars);
|
||||
}
|
||||
|
||||
try {
|
||||
// Create the snapshot.
|
||||
createProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME,
|
||||
classpath,
|
||||
/*appId*/ -1, callback);
|
||||
// Destroy the snapshot, we no longer need it.
|
||||
destroyProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME);
|
||||
} catch (LegacyDexoptDisabledException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the snapshot.
|
||||
createProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME, classpath,
|
||||
/*appId*/ -1, callback);
|
||||
// Destroy the snapshot, we no longer need it.
|
||||
destroyProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user