Loading services/core/java/com/android/server/pm/PackageSetting.java +44 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.pkg.PackageStateUnserialized; import com.android.server.utils.SnapshotCache; import java.io.File; import java.util.ArrayList; Loading Loading @@ -81,6 +82,7 @@ public class PackageSetting extends PackageSettingBase { * object equality to check whether shared user settings are the same. */ SharedUserSetting sharedUser; /** * Temporary holding space for the shared user ID. While parsing package settings, the * shared users tag may come after the packages. In this case, we must delay linking the Loading @@ -103,6 +105,19 @@ public class PackageSetting extends PackageSettingBase { @NonNull private UUID mDomainSetId; /** * Snapshot support. */ private final SnapshotCache<PackageSetting> mSnapshot; private SnapshotCache<PackageSetting> makeCache() { return new SnapshotCache<PackageSetting>(this, this) { @Override public PackageSetting createSnapshot() { return new PackageSetting(mSource, true); }}; } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public PackageSetting(String name, String realName, @NonNull File codePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, Loading @@ -118,6 +133,7 @@ public class PackageSetting extends PackageSettingBase { this.sharedUserId = sharedUserId; mDomainSetId = domainSetId; copyMimeGroups(mimeGroups); mSnapshot = makeCache(); } /** Loading @@ -127,6 +143,7 @@ public class PackageSetting extends PackageSettingBase { PackageSetting(PackageSetting orig) { super(orig, orig.realName); doCopy(orig); mSnapshot = makeCache(); } /** Loading @@ -137,6 +154,33 @@ public class PackageSetting extends PackageSettingBase { PackageSetting(PackageSetting orig, String realPkgName) { super(orig, realPkgName); doCopy(orig); mSnapshot = makeCache(); } /** * Create a snapshot. The copy constructor is already in use and cannot be modified * for this purpose. */ PackageSetting(PackageSetting orig, boolean snapshot) { super(orig, snapshot); // The existing doCopy() method cannot be used in here because sharedUser must be // a snapshot, and not a reference. Also, the pkgState must be copied. However, // this code should otherwise be kept in sync with doCopy(). appId = orig.appId; pkg = orig.pkg; sharedUser = orig.sharedUser == null ? null : orig.sharedUser.snapshot(); sharedUserId = orig.sharedUserId; copyMimeGroups(orig.mimeGroups); pkgState = orig.pkgState; mDomainSetId = orig.getDomainSetId(); mSnapshot = new SnapshotCache.Sealed(); } /** * Return the package snapshot. */ public PackageSetting snapshot() { return mSnapshot.snapshot(); } /** @see #pkg **/ Loading services/core/java/com/android/server/pm/PackageSettingBase.java +9 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,15 @@ public abstract class PackageSettingBase extends SettingBase { doCopy(base); } // A copy constructor used to create snapshots. The boolean is present only to // match up with the constructor in PackageSetting. PackageSettingBase(PackageSettingBase orig, boolean snapshot) { super(orig); name = orig.name; realName = orig.realName; doCopy(orig); } public void setInstallerPackageName(String packageName) { installSource = installSource.setInstallerPackage(packageName); onChanged(); Loading services/core/java/com/android/server/pm/SettingBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -22,12 +22,13 @@ import android.content.pm.ApplicationInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.utils.Snappable; import com.android.server.utils.Watchable; import com.android.server.utils.WatchableImpl; import com.android.server.utils.Watcher; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public abstract class SettingBase implements Watchable { public abstract class SettingBase implements Watchable, Snappable { // TODO: make this variable protected, or even private with a getter and setter. // Simply making it protected or private requires that the name be changed to conformm // to the Android naming convention, and that touches quite a few files. Loading services/core/java/com/android/server/pm/SharedUserSetting.java +45 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.ArrayUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.utils.SnapshotCache; import libcore.util.EmptyArray; Loading @@ -49,12 +50,25 @@ public final class SharedUserSetting extends SettingBase { // that all apps within the sharedUser run in the same selinux context. int seInfoTargetSdkVersion; final ArraySet<PackageSetting> packages = new ArraySet<>(); final ArraySet<PackageSetting> packages; final PackageSignatures signatures = new PackageSignatures(); Boolean signaturesChanged; ArrayMap<String, ParsedProcess> processes; final ArrayMap<String, ParsedProcess> processes; /** * Snapshot support. */ private final SnapshotCache<SharedUserSetting> mSnapshot; private SnapshotCache<SharedUserSetting> makeCache() { return new SnapshotCache<SharedUserSetting>(this, this) { @Override public SharedUserSetting createSnapshot() { return new SharedUserSetting(mSource); }}; } SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) { super(_pkgFlags, _pkgPrivateFlags); Loading @@ -62,6 +76,31 @@ public final class SharedUserSetting extends SettingBase { uidPrivateFlags = _pkgPrivateFlags; name = _name; seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; packages = new ArraySet<>(); processes = new ArrayMap<>(); mSnapshot = makeCache(); } // The copy constructor is used to create a snapshot private SharedUserSetting(SharedUserSetting orig) { super(orig); name = orig.name; uidFlags = orig.uidFlags; uidPrivateFlags = orig.uidPrivateFlags; packages = new ArraySet(orig.packages); // A PackageParser.SigningDetails seems to consist solely of final attributes, so // it is safe to copy the reference. signatures.mSigningDetails = orig.signatures.mSigningDetails; signaturesChanged = orig.signaturesChanged; processes = new ArrayMap(orig.processes); mSnapshot = new SnapshotCache.Sealed(); } /** * Return a read-only snapshot of this object. */ public SharedUserSetting snapshot() { return mSnapshot.snapshot(); } @Override Loading @@ -80,9 +119,6 @@ public final class SharedUserSetting extends SettingBase { void addProcesses(Map<String, ParsedProcess> newProcs) { if (newProcs != null) { final int numProcs = newProcs.size(); if (processes == null) { processes = new ArrayMap<>(numProcs); } for (String key : newProcs.keySet()) { ParsedProcess newProc = newProcs.get(key); ParsedProcess proc = processes.get(newProc.getName()); Loading Loading @@ -191,7 +227,7 @@ public final class SharedUserSetting extends SettingBase { * Update tracked data about processes based on all known packages in the shared user ID. */ public void updateProcesses() { processes = null; processes.clear(); for (int i = packages.size() - 1; i >= 0; i--) { final AndroidPackage pkg = packages.valueAt(i).pkg; if (pkg != null) { Loading Loading @@ -230,14 +266,15 @@ public final class SharedUserSetting extends SettingBase { this.signaturesChanged = sharedUser.signaturesChanged; if (sharedUser.processes != null) { final int numProcs = sharedUser.processes.size(); this.processes = new ArrayMap<>(numProcs); this.processes.clear(); this.processes.ensureCapacity(numProcs); for (int i = 0; i < numProcs; i++) { ParsedProcess proc = new ParsedProcess(sharedUser.processes.valueAt(i)); this.processes.put(proc.getName(), proc); } } else { this.processes = null; this.processes.clear(); } onChanged(); return this; Loading services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +1 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ public class PackageManagerSettingsTests { new WatchableTester(settingsUnderTest, "noSuspendingPackage"); watcher.register(); settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1)); settingsUnderTest.readPackageRestrictionsLPr(0); watcher.verifyChangeReported("put package 1"); // Collect a snapshot at the midway point (package 2 has not been added) final Settings snapshot = settingsUnderTest.snapshot(); Loading Loading
services/core/java/com/android/server/pm/PackageSetting.java +44 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.pkg.PackageStateUnserialized; import com.android.server.utils.SnapshotCache; import java.io.File; import java.util.ArrayList; Loading Loading @@ -81,6 +82,7 @@ public class PackageSetting extends PackageSettingBase { * object equality to check whether shared user settings are the same. */ SharedUserSetting sharedUser; /** * Temporary holding space for the shared user ID. While parsing package settings, the * shared users tag may come after the packages. In this case, we must delay linking the Loading @@ -103,6 +105,19 @@ public class PackageSetting extends PackageSettingBase { @NonNull private UUID mDomainSetId; /** * Snapshot support. */ private final SnapshotCache<PackageSetting> mSnapshot; private SnapshotCache<PackageSetting> makeCache() { return new SnapshotCache<PackageSetting>(this, this) { @Override public PackageSetting createSnapshot() { return new PackageSetting(mSource, true); }}; } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public PackageSetting(String name, String realName, @NonNull File codePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, Loading @@ -118,6 +133,7 @@ public class PackageSetting extends PackageSettingBase { this.sharedUserId = sharedUserId; mDomainSetId = domainSetId; copyMimeGroups(mimeGroups); mSnapshot = makeCache(); } /** Loading @@ -127,6 +143,7 @@ public class PackageSetting extends PackageSettingBase { PackageSetting(PackageSetting orig) { super(orig, orig.realName); doCopy(orig); mSnapshot = makeCache(); } /** Loading @@ -137,6 +154,33 @@ public class PackageSetting extends PackageSettingBase { PackageSetting(PackageSetting orig, String realPkgName) { super(orig, realPkgName); doCopy(orig); mSnapshot = makeCache(); } /** * Create a snapshot. The copy constructor is already in use and cannot be modified * for this purpose. */ PackageSetting(PackageSetting orig, boolean snapshot) { super(orig, snapshot); // The existing doCopy() method cannot be used in here because sharedUser must be // a snapshot, and not a reference. Also, the pkgState must be copied. However, // this code should otherwise be kept in sync with doCopy(). appId = orig.appId; pkg = orig.pkg; sharedUser = orig.sharedUser == null ? null : orig.sharedUser.snapshot(); sharedUserId = orig.sharedUserId; copyMimeGroups(orig.mimeGroups); pkgState = orig.pkgState; mDomainSetId = orig.getDomainSetId(); mSnapshot = new SnapshotCache.Sealed(); } /** * Return the package snapshot. */ public PackageSetting snapshot() { return mSnapshot.snapshot(); } /** @see #pkg **/ Loading
services/core/java/com/android/server/pm/PackageSettingBase.java +9 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,15 @@ public abstract class PackageSettingBase extends SettingBase { doCopy(base); } // A copy constructor used to create snapshots. The boolean is present only to // match up with the constructor in PackageSetting. PackageSettingBase(PackageSettingBase orig, boolean snapshot) { super(orig); name = orig.name; realName = orig.realName; doCopy(orig); } public void setInstallerPackageName(String packageName) { installSource = installSource.setInstallerPackage(packageName); onChanged(); Loading
services/core/java/com/android/server/pm/SettingBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -22,12 +22,13 @@ import android.content.pm.ApplicationInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.utils.Snappable; import com.android.server.utils.Watchable; import com.android.server.utils.WatchableImpl; import com.android.server.utils.Watcher; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public abstract class SettingBase implements Watchable { public abstract class SettingBase implements Watchable, Snappable { // TODO: make this variable protected, or even private with a getter and setter. // Simply making it protected or private requires that the name be changed to conformm // to the Android naming convention, and that touches quite a few files. Loading
services/core/java/com/android/server/pm/SharedUserSetting.java +45 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.ArrayUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.utils.SnapshotCache; import libcore.util.EmptyArray; Loading @@ -49,12 +50,25 @@ public final class SharedUserSetting extends SettingBase { // that all apps within the sharedUser run in the same selinux context. int seInfoTargetSdkVersion; final ArraySet<PackageSetting> packages = new ArraySet<>(); final ArraySet<PackageSetting> packages; final PackageSignatures signatures = new PackageSignatures(); Boolean signaturesChanged; ArrayMap<String, ParsedProcess> processes; final ArrayMap<String, ParsedProcess> processes; /** * Snapshot support. */ private final SnapshotCache<SharedUserSetting> mSnapshot; private SnapshotCache<SharedUserSetting> makeCache() { return new SnapshotCache<SharedUserSetting>(this, this) { @Override public SharedUserSetting createSnapshot() { return new SharedUserSetting(mSource); }}; } SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) { super(_pkgFlags, _pkgPrivateFlags); Loading @@ -62,6 +76,31 @@ public final class SharedUserSetting extends SettingBase { uidPrivateFlags = _pkgPrivateFlags; name = _name; seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; packages = new ArraySet<>(); processes = new ArrayMap<>(); mSnapshot = makeCache(); } // The copy constructor is used to create a snapshot private SharedUserSetting(SharedUserSetting orig) { super(orig); name = orig.name; uidFlags = orig.uidFlags; uidPrivateFlags = orig.uidPrivateFlags; packages = new ArraySet(orig.packages); // A PackageParser.SigningDetails seems to consist solely of final attributes, so // it is safe to copy the reference. signatures.mSigningDetails = orig.signatures.mSigningDetails; signaturesChanged = orig.signaturesChanged; processes = new ArrayMap(orig.processes); mSnapshot = new SnapshotCache.Sealed(); } /** * Return a read-only snapshot of this object. */ public SharedUserSetting snapshot() { return mSnapshot.snapshot(); } @Override Loading @@ -80,9 +119,6 @@ public final class SharedUserSetting extends SettingBase { void addProcesses(Map<String, ParsedProcess> newProcs) { if (newProcs != null) { final int numProcs = newProcs.size(); if (processes == null) { processes = new ArrayMap<>(numProcs); } for (String key : newProcs.keySet()) { ParsedProcess newProc = newProcs.get(key); ParsedProcess proc = processes.get(newProc.getName()); Loading Loading @@ -191,7 +227,7 @@ public final class SharedUserSetting extends SettingBase { * Update tracked data about processes based on all known packages in the shared user ID. */ public void updateProcesses() { processes = null; processes.clear(); for (int i = packages.size() - 1; i >= 0; i--) { final AndroidPackage pkg = packages.valueAt(i).pkg; if (pkg != null) { Loading Loading @@ -230,14 +266,15 @@ public final class SharedUserSetting extends SettingBase { this.signaturesChanged = sharedUser.signaturesChanged; if (sharedUser.processes != null) { final int numProcs = sharedUser.processes.size(); this.processes = new ArrayMap<>(numProcs); this.processes.clear(); this.processes.ensureCapacity(numProcs); for (int i = 0; i < numProcs; i++) { ParsedProcess proc = new ParsedProcess(sharedUser.processes.valueAt(i)); this.processes.put(proc.getName(), proc); } } else { this.processes = null; this.processes.clear(); } onChanged(); return this; Loading
services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +1 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ public class PackageManagerSettingsTests { new WatchableTester(settingsUnderTest, "noSuspendingPackage"); watcher.register(); settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1)); settingsUnderTest.readPackageRestrictionsLPr(0); watcher.verifyChangeReported("put package 1"); // Collect a snapshot at the midway point (package 2 has not been added) final Settings snapshot = settingsUnderTest.snapshot(); Loading