Loading core/java/android/content/pm/dex/ArtManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -153,4 +153,14 @@ public class ArtManager { return true; } } /** * Return the profile name for the given split. If {@code splitName} is null the * method returns the profile name for the base apk. * * @hide */ public static String getProfileName(String splitName) { return splitName == null ? "primary.prof" : splitName + ".split.prof"; } } services/core/java/com/android/server/pm/Installer.java +13 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.pm; import android.annotation.AppIdInt; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageStats; import android.os.Build; Loading Loading @@ -538,6 +540,17 @@ public class Installer extends SystemService { } } public boolean prepareAppProfile(String pkg, @UserIdInt int userId, @AppIdInt int appId, String profileName, String codePath, String dexMetadataPath) throws InstallerException { if (!checkBeforeRemote()) return false; try { return mInstalld.prepareAppProfile(pkg, userId, appId, profileName, codePath, dexMetadataPath); } catch (Exception e) { throw InstallerException.from(e); } } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading services/core/java/com/android/server/pm/PackageManagerService.java +8 −1 Original line number Diff line number Diff line Loading @@ -2430,6 +2430,7 @@ public class PackageManagerService extends IPackageManager.Stub installer, mInstallLock); mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock, dexManagerListener); mArtManagerService = new ArtManagerService(this, installer, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -3086,7 +3087,6 @@ Slog.e("TODD", } mInstallerService = new PackageInstallerService(context, this); mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); if (instantAppResolverComponent != null) { Loading Loading @@ -17019,6 +17019,11 @@ Slog.e("TODD", } } // 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, args.user.getIdentifier()); // Check whether we need to dexopt the app. // // NOTE: it is IMPORTANT to call dexopt: Loading Loading @@ -22033,6 +22038,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); } } // Prepare the application profiles. mArtManagerService.prepareAppProfiles(pkg, userId); if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { // TODO: mark this structure as dirty so we persist it! services/core/java/com/android/server/pm/dex/ArtManagerService.java +54 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,13 @@ package com.android.server.pm.dex; import android.Manifest; import android.annotation.UserIdInt; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.os.Binder; import android.os.Environment; import android.os.Handler; Loading @@ -29,10 +33,12 @@ import android.content.pm.IPackageManager; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; Loading Loading @@ -230,4 +236,52 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { // Should not happen. } } /** * Prepare the application profiles. * For all code paths: * - 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) { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); try { ArrayMap<String, String> codePathsProfileNames = getPackageProfileNames(pkg); 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(); synchronized (mInstaller) { boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); if (!result) { Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName + ":" + codePath); } } } } catch (InstallerException e) { Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName, e); } } /** * Build the profiles names for all the package code paths (excluding resource only paths). * Return the map [code path -> profile name]. */ private ArrayMap<String, String> getPackageProfileNames(PackageParser.Package pkg) { ArrayMap<String, String> result = new ArrayMap<>(); if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { result.put(pkg.baseCodePath, ArtManager.getProfileName(null)); } if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (int i = 0; i < pkg.splitCodePaths.length; i++) { if ((pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) { result.put(pkg.splitCodePaths[i], ArtManager.getProfileName(pkg.splitNames[i])); } } } return result; } } Loading
core/java/android/content/pm/dex/ArtManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -153,4 +153,14 @@ public class ArtManager { return true; } } /** * Return the profile name for the given split. If {@code splitName} is null the * method returns the profile name for the base apk. * * @hide */ public static String getProfileName(String splitName) { return splitName == null ? "primary.prof" : splitName + ".split.prof"; } }
services/core/java/com/android/server/pm/Installer.java +13 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.pm; import android.annotation.AppIdInt; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageStats; import android.os.Build; Loading Loading @@ -538,6 +540,17 @@ public class Installer extends SystemService { } } public boolean prepareAppProfile(String pkg, @UserIdInt int userId, @AppIdInt int appId, String profileName, String codePath, String dexMetadataPath) throws InstallerException { if (!checkBeforeRemote()) return false; try { return mInstalld.prepareAppProfile(pkg, userId, appId, profileName, codePath, dexMetadataPath); } catch (Exception e) { throw InstallerException.from(e); } } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading
services/core/java/com/android/server/pm/PackageManagerService.java +8 −1 Original line number Diff line number Diff line Loading @@ -2430,6 +2430,7 @@ public class PackageManagerService extends IPackageManager.Stub installer, mInstallLock); mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock, dexManagerListener); mArtManagerService = new ArtManagerService(this, installer, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -3086,7 +3087,6 @@ Slog.e("TODD", } mInstallerService = new PackageInstallerService(context, this); mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); if (instantAppResolverComponent != null) { Loading Loading @@ -17019,6 +17019,11 @@ Slog.e("TODD", } } // 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, args.user.getIdentifier()); // Check whether we need to dexopt the app. // // NOTE: it is IMPORTANT to call dexopt: Loading Loading @@ -22033,6 +22038,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); } } // Prepare the application profiles. mArtManagerService.prepareAppProfiles(pkg, userId); if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { // TODO: mark this structure as dirty so we persist it!
services/core/java/com/android/server/pm/dex/ArtManagerService.java +54 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,13 @@ package com.android.server.pm.dex; import android.Manifest; import android.annotation.UserIdInt; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.os.Binder; import android.os.Environment; import android.os.Handler; Loading @@ -29,10 +33,12 @@ import android.content.pm.IPackageManager; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; Loading Loading @@ -230,4 +236,52 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { // Should not happen. } } /** * Prepare the application profiles. * For all code paths: * - 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) { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); try { ArrayMap<String, String> codePathsProfileNames = getPackageProfileNames(pkg); 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(); synchronized (mInstaller) { boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); if (!result) { Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName + ":" + codePath); } } } } catch (InstallerException e) { Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName, e); } } /** * Build the profiles names for all the package code paths (excluding resource only paths). * Return the map [code path -> profile name]. */ private ArrayMap<String, String> getPackageProfileNames(PackageParser.Package pkg) { ArrayMap<String, String> result = new ArrayMap<>(); if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { result.put(pkg.baseCodePath, ArtManager.getProfileName(null)); } if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (int i = 0; i < pkg.splitCodePaths.length; i++) { if ((pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) { result.put(pkg.splitCodePaths[i], ArtManager.getProfileName(pkg.splitNames[i])); } } } return result; } }