From 346cf7843f18594fb3b1b1bf65c424f87255c972 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Mon, 24 Sep 2018 14:07:16 -0700 Subject: [PATCH] Update the reference profile from .dm files only during installs In order to speed up first boot time we only create the current profile and do not update the content of the reference profile. A system image should already be configured with the right profile keys and the profiles for the speed-profile prebuilds should already be copied (that's done in #performDexOptUpgrade). Test: manual (install apps and splits, take OTA) Bug: 114046578 (cherry picked from commit 5c9a0085a3366b4c7f00586dba9691fac9016f22) Merged-In: I99db76684430b929c52634c25b457e874648e205 Change-Id: I99db76684430b929c52634c25b457e874648e205 --- .../server/pm/PackageManagerService.java | 15 +++++++++++++-- .../server/pm/dex/ArtManagerService.java | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 271d205cb69b9..fae4db9a81ded 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17529,7 +17529,8 @@ public class PackageManagerService extends IPackageManager.Stub // Prepare the application profiles for the new code paths. // This needs to be done before invoking dexopt so that any install-time profile // can be used for optimizations. - mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier())); + mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()), + /* updateReferenceProfileContent= */ true); // Check whether we need to dexopt the app. // @@ -22606,8 +22607,18 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); // // We also have to cover non system users because we do not call the usual install package // methods for them. + // + // NOTE: in order to speed up first boot time we only create the current profile and do not + // update the content of the reference profile. A system image should already be configured + // with the right profile keys and the profiles for the speed-profile prebuilds should + // already be copied. That's done in #performDexOptUpgrade. + // + // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of + // manually copying them in #performDexOptUpgrade. When we do that we should have a more + // granular check here and only update the existing profiles. if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) { - mArtManagerService.prepareAppProfiles(pkg, userId); + mArtManagerService.prepareAppProfiles(pkg, userId, + /* updateReferenceProfileContent= */ false); } if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 0ba78226a38f4..833cc5bd91f2f 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -389,7 +389,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { * - create the current primary profile to save time at app startup time. * - copy the profiles from the associated dex metadata file to the reference profile. */ - public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user) { + public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user, + boolean updateReferenceProfileContent) { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); if (user < 0) { Slog.wtf(TAG, "Invalid user id: " + user); @@ -404,8 +405,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) { String codePath = codePathsProfileNames.keyAt(i); String profileName = codePathsProfileNames.valueAt(i); - File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); - String dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + String dexMetadataPath = null; + // Passing the dex metadata file to the prepare method will update the reference + // profile content. As such, we look for the dex metadata file only if we need to + // perform an update. + if (updateReferenceProfileContent) { + File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); + dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + } synchronized (mInstaller) { boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); @@ -423,9 +430,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}. */ - public void prepareAppProfiles(PackageParser.Package pkg, int[] user) { + public void prepareAppProfiles(PackageParser.Package pkg, int[] user, + boolean updateReferenceProfileContent) { for (int i = 0; i < user.length; i++) { - prepareAppProfiles(pkg, user[i]); + prepareAppProfiles(pkg, user[i], updateReferenceProfileContent); } }