Take snapshots of SettingBase subclasses
Bug: 192478088 Snapshot SharedUserSetting and PackageSetting. Test: atest * CtsContentTestCases:IntentFilterTest * CtsDynamicMimeHostTestCases * CtsRoleTestCases * FrameworksServicesTests:UserSystemPackageInstallerTest * FrameworksServicesTests:PackageManagerSettingsTests * FrameworksServicesTests:PackageManagerServiceTest * FrameworksServicesTests:AppsFilterTest * FrameworksServicesTests:PackageInstallerSessionTest * FrameworksServicesTests:ScanTests * UserLifecycleTests#startUser * UserLifecycleTests#stopUser * UserLifecycleTests#switchUser * FrameworksServicesTests:WatcherTest * android.appsecurity.cts.EphemeralTest * android.appsecurity.cts.InstantAppUserTest Change-Id: I5ccd77bd8a07aa833219c6bab797cdc153c1136f
This commit is contained in:
@@ -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;
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -118,6 +133,7 @@ public class PackageSetting extends PackageSettingBase {
|
||||
this.sharedUserId = sharedUserId;
|
||||
mDomainSetId = domainSetId;
|
||||
copyMimeGroups(mimeGroups);
|
||||
mSnapshot = makeCache();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,6 +143,7 @@ public class PackageSetting extends PackageSettingBase {
|
||||
PackageSetting(PackageSetting orig) {
|
||||
super(orig, orig.realName);
|
||||
doCopy(orig);
|
||||
mSnapshot = makeCache();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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 **/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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());
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user