diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 91af0eca8707e..4a7b2f6883aef 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -15336,7 +15336,9 @@ public class PackageManagerService extends IPackageManager.Stub // This needs to be done before invoking dexopt so that any install-time profile // can be used for optimizations. mArtManagerService.prepareAppProfiles( - pkg, resolveUserIds(reconciledPkg.installForUser.getIdentifier())); + pkg, + resolveUserIds(reconciledPkg.installForUser.getIdentifier()), + /* updateReferenceProfileContent= */ true); // Check whether we need to dexopt the app. // @@ -21184,8 +21186,18 @@ public class PackageManagerService extends IPackageManager.Stub // // 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 21daa39e05e04..910ea738acd8e 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); } }