diff options
| author | 2018-01-25 18:58:09 +0000 | |
|---|---|---|
| committer | 2018-01-25 18:58:09 +0000 | |
| commit | 2b6e24c7e52df47fd35ade619211fa293eca5ad7 (patch) | |
| tree | b715a23940c33306fd5eeb2951c47d23ace160b3 | |
| parent | 15050aaa994f6bba3aee0997b6a9ab09b04febe7 (diff) | |
| parent | 6ae39fc2e5b4692d092a042816939fd0a5f3e3b8 (diff) | |
Merge "[framework] Extend profile operations to take the profile name"
9 files changed, 135 insertions, 79 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 26f498087786..d24d4f341aea 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -28,6 +28,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.dex.ArtManager; import android.content.pm.split.SplitDependencyLoader; import android.content.res.AssetManager; import android.content.res.CompatibilityInfo; @@ -35,7 +36,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; import android.os.Bundle; -import android.os.Environment; import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; @@ -49,13 +49,15 @@ import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.Log; -import android.util.LogPrinter; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAdjustments; + import com.android.internal.util.ArrayUtils; + import dalvik.system.VMRuntime; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -749,13 +751,6 @@ public final class LoadedApk { } } - // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp). - private static File getPrimaryProfileFile(String packageName) { - File profileDir = Environment.getDataProfilesDePackageDirectory( - UserHandle.myUserId(), packageName); - return new File(profileDir, "primary.prof"); - } - private void setupJitProfileSupport() { if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) { return; @@ -783,10 +778,12 @@ public final class LoadedApk { return; } - final File profileFile = getPrimaryProfileFile(mPackageName); - - VMRuntime.registerAppInfo(profileFile.getPath(), - codePaths.toArray(new String[codePaths.size()])); + for (int i = codePaths.size() - 1; i >= 0; i--) { + String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1]; + String profileFile = ArtManager.getCurrentProfilePath( + mPackageName, UserHandle.myUserId(), splitName); + VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)}); + } // Register the app data directory with the reporter. It will // help deciding whether or not a dex file is the primary apk or a diff --git a/core/java/android/content/pm/dex/ArtManager.java b/core/java/android/content/pm/dex/ArtManager.java index aa9c46e6a52d..f979576e5315 100644 --- a/core/java/android/content/pm/dex/ArtManager.java +++ b/core/java/android/content/pm/dex/ArtManager.java @@ -19,6 +19,7 @@ package android.content.pm.dex; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -26,6 +27,8 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Slog; +import java.io.File; + /** * Class for retrieving various kinds of information related to the runtime artifacts of * packages that are currently installed on the device. @@ -163,4 +166,29 @@ public class ArtManager { public static String getProfileName(String splitName) { return splitName == null ? "primary.prof" : splitName + ".split.prof"; } + + /** + * Return the path to the current profile corresponding to given package and split. + * + * @hide + */ + public static String getCurrentProfilePath(String packageName, int userId, String splitName) { + File profileDir = Environment.getDataProfilesDePackageDirectory(userId, packageName); + return new File(profileDir, getProfileName(splitName)).getAbsolutePath(); + } + + /** + * Return the snapshot profile file for the given package and split. + * + * KEEP in sync with installd dexopt.cpp. + * TODO(calin): inject the snapshot profile name from PM to avoid the dependency. + * + * @hide + */ + public static File getProfileSnapshotFile(String packageName, String splitName) { + File profileDir = Environment.getDataRefProfilesDePackageDirectory(packageName); + String snapshotFile = getProfileName(splitName) + ".snapshot"; + return new File(profileDir, snapshotFile); + + } } diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 62731e84a401..158041dd91e7 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -302,9 +302,8 @@ public class Environment { } /** {@hide} */ - public static File getProfileSnapshotPath(String packageName, String codePath) { - return buildPath(buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName, - "primary.prof.snapshot")); + public static File getDataRefProfilesDePackageDirectory(String packageName) { + return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName); } /** {@hide} */ diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 56594705082a..39279b5055b1 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -583,7 +583,7 @@ public class ZygoteInit { installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, uuid, classLoaderContext, seInfo, false /* downgrade */, - targetSdkVersion); + targetSdkVersion, /*profileName*/ null); } catch (RemoteException | ServiceSpecificException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 4b6c40669cb8..3c40a9eba41d 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -289,43 +289,44 @@ public class Installer extends SystemService { 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, - @Nullable String seInfo, boolean downgrade, int targetSdkVersion) - throws InstallerException { + @Nullable String seInfo, boolean downgrade, int targetSdkVersion, + @Nullable String profileName) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; try { mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade, - targetSdkVersion); + targetSdkVersion, profileName); } catch (Exception e) { throw InstallerException.from(e); } } - public boolean mergeProfiles(int uid, String packageName) throws InstallerException { + public boolean mergeProfiles(int uid, String packageName, String profileName) + throws InstallerException { if (!checkBeforeRemote()) return false; try { - return mInstalld.mergeProfiles(uid, packageName); + return mInstalld.mergeProfiles(uid, packageName, profileName); } catch (Exception e) { throw InstallerException.from(e); } } - public boolean dumpProfiles(int uid, String packageName, String codePaths) + public boolean dumpProfiles(int uid, String packageName, String profileName, String codePath) throws InstallerException { if (!checkBeforeRemote()) return false; try { - return mInstalld.dumpProfiles(uid, packageName, codePaths); + return mInstalld.dumpProfiles(uid, packageName, profileName, codePath); } catch (Exception e) { throw InstallerException.from(e); } } - public boolean copySystemProfile(String systemProfile, int uid, String packageName) - throws InstallerException { + public boolean copySystemProfile(String systemProfile, int uid, String packageName, + String profileName) throws InstallerException { if (!checkBeforeRemote()) return false; try { - return mInstalld.copySystemProfile(systemProfile, uid, packageName); + return mInstalld.copySystemProfile(systemProfile, uid, packageName, profileName); } catch (Exception e) { throw InstallerException.from(e); } @@ -369,10 +370,10 @@ public class Installer extends SystemService { } } - public void clearAppProfiles(String packageName) throws InstallerException { + public void clearAppProfiles(String packageName, String profileName) throws InstallerException { if (!checkBeforeRemote()) return; try { - mInstalld.clearAppProfiles(packageName); + mInstalld.clearAppProfiles(packageName, profileName); } catch (Exception e) { throw InstallerException.from(e); } @@ -525,21 +526,21 @@ public class Installer extends SystemService { } } - public boolean createProfileSnapshot(int appId, String packageName, String codePath) + public boolean createProfileSnapshot(int appId, String packageName, String profileName) throws InstallerException { if (!checkBeforeRemote()) return false; try { - return mInstalld.createProfileSnapshot(appId, packageName, codePath); + return mInstalld.createProfileSnapshot(appId, packageName, profileName); } catch (Exception e) { throw InstallerException.from(e); } } - public void destroyProfileSnapshot(String packageName, String codePath) + public void destroyProfileSnapshot(String packageName, String profileName) throws InstallerException { if (!checkBeforeRemote()) return; try { - mInstalld.destroyProfileSnapshot(packageName, codePath); + mInstalld.destroyProfileSnapshot(packageName, profileName); } catch (Exception e) { throw InstallerException.from(e); } diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 03950119ea13..5bf38dc21305 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -261,12 +261,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub { String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade, - int targetSdkVersion) + int targetSdkVersion, @Nullable String profileName) throws InstallerException { final StringBuilder builder = new StringBuilder(); - // The version. Right now it's 4. - builder.append("4 "); + // The version. Right now it's 5. + builder.append("5 "); builder.append("dexopt"); @@ -283,6 +283,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { encodeParameter(builder, seInfo); encodeParameter(builder, downgrade); encodeParameter(builder, targetSdkVersion); + encodeParameter(builder, profileName); commands.add(builder.toString()); } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 324dc5fb8656..cde8cb740590 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageParser; +import android.content.pm.dex.ArtManager; import android.os.FileUtils; import android.os.PowerManager; import android.os.SystemClock; @@ -206,12 +207,14 @@ public class PackageDexOptimizer { } } + String profileName = ArtManager.getProfileName(i == 0 ? null : pkg.splitNames[i - 1]); + final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary() || packageUseInfo.isUsedByOtherApps(path); final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, options.getCompilerFilter(), isUsedByOtherApps); final boolean profileUpdated = options.isCheckForProfileUpdates() && - isProfileUpdated(pkg, sharedGid, compilerFilter); + isProfileUpdated(pkg, sharedGid, profileName, compilerFilter); // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct // flags. @@ -220,7 +223,7 @@ public class PackageDexOptimizer { for (String dexCodeIsa : dexCodeInstructionSets) { int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter, profileUpdated, classLoaderContexts[i], dexoptFlags, sharedGid, - packageStats, options.isDowngrade()); + packageStats, options.isDowngrade(), profileName); // The end result is: // - FAILED if any path failed, // - PERFORMED if at least one path needed compilation, @@ -244,7 +247,8 @@ public class PackageDexOptimizer { @GuardedBy("mInstallLock") private int dexOptPath(PackageParser.Package pkg, String path, String isa, String compilerFilter, boolean profileUpdated, String classLoaderContext, - int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade) { + int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade, + String profileName) { int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, classLoaderContext, profileUpdated, downgrade); if (Math.abs(dexoptNeeded) == DexFile.NO_DEXOPT_NEEDED) { @@ -270,7 +274,8 @@ public class PackageDexOptimizer { // primary dex files. mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo, - false /* downgrade*/, pkg.applicationInfo.targetSdkVersion); + false /* downgrade*/, pkg.applicationInfo.targetSdkVersion, + profileName); if (packageStats != null) { long endTime = System.currentTimeMillis(); @@ -391,7 +396,7 @@ public class PackageDexOptimizer { mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, /*oatDir*/ null, dexoptFlags, compilerFilter, info.volumeUuid, classLoaderContext, info.seInfoUser, - options.isDowngrade(), info.targetSdkVersion); + options.isDowngrade(), info.targetSdkVersion, /*profileName*/ null); } return DEX_OPT_PERFORMED; @@ -550,14 +555,15 @@ public class PackageDexOptimizer { * current profile and the reference profile will be merged and subsequent calls * may return a different result. */ - private boolean isProfileUpdated(PackageParser.Package pkg, int uid, String compilerFilter) { + private boolean isProfileUpdated(PackageParser.Package pkg, int uid, String profileName, + String compilerFilter) { // Check if we are allowed to merge and if the compiler filter is profile guided. if (!isProfileGuidedCompilerFilter(compilerFilter)) { return false; } // Merge profiles. It returns whether or not there was an updated in the profile info. try { - return mInstaller.mergeProfiles(uid, pkg.packageName); + return mInstaller.mergeProfiles(uid, pkg.packageName, profileName); } catch (InstallerException e) { Slog.w(TAG, "Failed to merge profiles", e); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 91a8317ff33d..837a118384be 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -193,6 +193,7 @@ import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VerifierInfo; import android.content.pm.VersionedPackage; +import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.IArtManager; import android.content.res.Resources; @@ -8916,7 +8917,8 @@ Slog.e("TODD", // PackageDexOptimizer to prevent this happening on first boot. The issue // is that we don't have a good way to say "do this only once". if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(), - pkg.applicationInfo.uid, pkg.packageName)) { + pkg.applicationInfo.uid, pkg.packageName, + ArtManager.getProfileName(null))) { Log.e(TAG, "Installer failed to copy system profile!"); } else { // Disabled as this causes speed-profile compilation during first boot @@ -8951,7 +8953,8 @@ Slog.e("TODD", // issue is that we don't have a good way to say "do this only // once". if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(), - pkg.applicationInfo.uid, pkg.packageName)) { + pkg.applicationInfo.uid, pkg.packageName, + ArtManager.getProfileName(null))) { Log.e(TAG, "Failed to copy system profile for stub package!"); } else { useProfileForDexopt = true; @@ -9376,14 +9379,7 @@ Slog.e("TODD", synchronized (mInstallLock) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); - final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); - try { - List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); - String codePaths = TextUtils.join(";", allCodePaths); - mInstaller.dumpProfiles(sharedGid, packageName, codePaths); - } catch (InstallerException e) { - Slog.w(TAG, "Failed to dump profiles", e); - } + mArtManagerService.dumpProfiles(pkg); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } @@ -9459,6 +9455,8 @@ Slog.e("TODD", for (int i = 0; i < childCount; i++) { clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); } + + clearAppProfilesLIF(pkg, UserHandle.USER_ALL); } private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { @@ -9531,18 +9529,10 @@ Slog.e("TODD", Slog.wtf(TAG, "Package was null!", new Throwable()); return; } - clearAppProfilesLeafLIF(pkg); + mArtManagerService.clearAppProfiles(pkg); final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; for (int i = 0; i < childCount; i++) { - clearAppProfilesLeafLIF(pkg.childPackages.get(i)); - } - } - - private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { - try { - mInstaller.clearAppProfiles(pkg.packageName); - } catch (InstallerException e) { - Slog.w(TAG, String.valueOf(e)); + mArtManagerService.clearAppProfiles(pkg.childPackages.get(i)); } } @@ -16202,7 +16192,6 @@ Slog.e("TODD", clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); - clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); try { final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, @@ -16341,7 +16330,6 @@ Slog.e("TODD", // Successfully disabled the old package. Now proceed with re-installation clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); - clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, @@ -20414,7 +20402,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); - clearAppProfilesLIF(pkg, UserHandle.USER_ALL); mDexManager.notifyPackageUpdated(pkg.packageName, pkg.baseCodePath, pkg.splitCodePaths); } 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 81786890a436..f15dc2d5f8d3 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -25,7 +25,6 @@ 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; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -111,11 +110,13 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { } boolean pathFound = info.applicationInfo.getBaseCodePath().equals(codePath); + String splitName = null; String[] splitCodePaths = info.applicationInfo.getSplitCodePaths(); if (!pathFound && (splitCodePaths != null)) { - for (String path : splitCodePaths) { - if (path.equals(codePath)) { + for (int i = splitCodePaths.length - 1; i >= 0; i--) { + if (splitCodePaths[i].equals(codePath)) { pathFound = true; + splitName = info.applicationInfo.splitNames[i]; break; } } @@ -126,18 +127,18 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { } // All good, create the profile snapshot. - createProfileSnapshot(packageName, codePath, callback, info); + createProfileSnapshot(packageName, splitName, callback, info); // Destroy the snapshot, we no longer need it. - destroyProfileSnapshot(packageName, codePath); + destroyProfileSnapshot(packageName, splitName); } - private void createProfileSnapshot(String packageName, String codePath, + private void createProfileSnapshot(String packageName, String splitName, ISnapshotRuntimeProfileCallback callback, PackageInfo info) { // Ask the installer to snapshot the profile. synchronized (mInstallLock) { try { if (!mInstaller.createProfileSnapshot(UserHandle.getAppId(info.applicationInfo.uid), - packageName, codePath)) { + packageName, ArtManager.getProfileName(splitName))) { postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR); return; } @@ -148,28 +149,30 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { } // Open the snapshot and invoke the callback. - File snapshotProfile = Environment.getProfileSnapshotPath(packageName, codePath); + File snapshotProfile = ArtManager.getProfileSnapshotFile(packageName, splitName); ParcelFileDescriptor fd; try { fd = ParcelFileDescriptor.open(snapshotProfile, ParcelFileDescriptor.MODE_READ_ONLY); postSuccess(packageName, fd, callback); } catch (FileNotFoundException e) { - Slog.w(TAG, "Could not open snapshot profile for " + packageName + ":" + codePath, e); + Slog.w(TAG, "Could not open snapshot profile for " + packageName + ":" + + snapshotProfile, e); postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR); } } - private void destroyProfileSnapshot(String packageName, String codePath) { + private void destroyProfileSnapshot(String packageName, String splitName) { if (DEBUG) { - Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + codePath); + Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + splitName); } synchronized (mInstallLock) { try { - mInstaller.destroyProfileSnapshot(packageName, codePath); + mInstaller.destroyProfileSnapshot(packageName, + ArtManager.getProfileName(splitName)); } catch (InstallerException e) { Slog.e(TAG, "Failed to destroy profile snapshot for " + - packageName + ":" + codePath, e); + packageName + ":" + splitName, e); } } } @@ -284,6 +287,40 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { } /** + * Clear the profiles for the given package. + */ + public void clearAppProfiles(PackageParser.Package pkg) { + try { + ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg); + for (int i = packageProfileNames.size() - 1; i >= 0; i--) { + String profileName = packageProfileNames.valueAt(i); + mInstaller.clearAppProfiles(pkg.packageName, profileName); + } + } catch (InstallerException e) { + Slog.w(TAG, String.valueOf(e)); + } + } + + /** + * Dumps the profiles for the given package. + */ + public void dumpProfiles(PackageParser.Package pkg) { + final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); + try { + ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg); + for (int i = packageProfileNames.size() - 1; i >= 0; i--) { + String codePath = packageProfileNames.keyAt(i); + String profileName = packageProfileNames.valueAt(i); + synchronized (mInstallLock) { + mInstaller.dumpProfiles(sharedGid, pkg.packageName, profileName, codePath); + } + } + } catch (InstallerException e) { + Slog.w(TAG, "Failed to dump profiles", e); + } + } + + /** * Build the profiles names for all the package code paths (excluding resource only paths). * Return the map [code path -> profile name]. */ |