Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 491c7dc5 authored by Lee Shombert's avatar Lee Shombert Committed by Automerger Merge Worker
Browse files

Merge "Take snapshots of SettingBase subclasses" into sc-dev am: 4de5e908

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15246960

Change-Id: I9730aca1fa9bce2f5eb7871548c98795459210cc
parents 0a31518c 4de5e908
Loading
Loading
Loading
Loading
+44 −0
Original line number Original line Diff line number Diff line
@@ -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.LegacyPermissionDataProvider;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.pm.pkg.PackageStateUnserialized;
import com.android.server.pm.pkg.PackageStateUnserialized;
import com.android.server.utils.SnapshotCache;


import java.io.File;
import java.io.File;
import java.util.ArrayList;
import java.util.ArrayList;
@@ -81,6 +82,7 @@ public class PackageSetting extends PackageSettingBase {
     * object equality to check whether shared user settings are the same.
     * object equality to check whether shared user settings are the same.
     */
     */
    SharedUserSetting sharedUser;
    SharedUserSetting sharedUser;

    /**
    /**
     * Temporary holding space for the shared user ID. While parsing package settings, the
     * 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
     * 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
    @NonNull
    private UUID mDomainSetId;
    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)
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public PackageSetting(String name, String realName, @NonNull File codePath,
    public PackageSetting(String name, String realName, @NonNull File codePath,
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
@@ -118,6 +133,7 @@ public class PackageSetting extends PackageSettingBase {
        this.sharedUserId = sharedUserId;
        this.sharedUserId = sharedUserId;
        mDomainSetId = domainSetId;
        mDomainSetId = domainSetId;
        copyMimeGroups(mimeGroups);
        copyMimeGroups(mimeGroups);
        mSnapshot = makeCache();
    }
    }


    /**
    /**
@@ -127,6 +143,7 @@ public class PackageSetting extends PackageSettingBase {
    PackageSetting(PackageSetting orig) {
    PackageSetting(PackageSetting orig) {
        super(orig, orig.realName);
        super(orig, orig.realName);
        doCopy(orig);
        doCopy(orig);
        mSnapshot = makeCache();
    }
    }


    /**
    /**
@@ -137,6 +154,33 @@ public class PackageSetting extends PackageSettingBase {
    PackageSetting(PackageSetting orig, String realPkgName) {
    PackageSetting(PackageSetting orig, String realPkgName) {
        super(orig, realPkgName);
        super(orig, realPkgName);
        doCopy(orig);
        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 **/
    /** @see #pkg **/
+9 −0
Original line number Original line Diff line number Diff line
@@ -169,6 +169,15 @@ public abstract class PackageSettingBase extends SettingBase {
        doCopy(base);
        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) {
    public void setInstallerPackageName(String packageName) {
        installSource = installSource.setInstallerPackage(packageName);
        installSource = installSource.setInstallerPackage(packageName);
        onChanged();
        onChanged();
+2 −1
Original line number Original line Diff line number Diff line
@@ -22,12 +22,13 @@ import android.content.pm.ApplicationInfo;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.Watcher;
import com.android.server.utils.Watcher;


@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@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.
    // 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
    // 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.
    // to the Android naming convention, and that touches quite a few files.
+45 −8
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream;


import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.utils.SnapshotCache;


import libcore.util.EmptyArray;
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.
    // that all apps within the sharedUser run in the same selinux context.
    int seInfoTargetSdkVersion;
    int seInfoTargetSdkVersion;


    final ArraySet<PackageSetting> packages = new ArraySet<>();
    final ArraySet<PackageSetting> packages;


    final PackageSignatures signatures = new PackageSignatures();
    final PackageSignatures signatures = new PackageSignatures();
    Boolean signaturesChanged;
    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) {
    SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) {
        super(_pkgFlags, _pkgPrivateFlags);
        super(_pkgFlags, _pkgPrivateFlags);
@@ -62,6 +76,31 @@ public final class SharedUserSetting extends SettingBase {
        uidPrivateFlags = _pkgPrivateFlags;
        uidPrivateFlags = _pkgPrivateFlags;
        name = _name;
        name = _name;
        seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
        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
    @Override
@@ -80,9 +119,6 @@ public final class SharedUserSetting extends SettingBase {
    void addProcesses(Map<String, ParsedProcess> newProcs) {
    void addProcesses(Map<String, ParsedProcess> newProcs) {
        if (newProcs != null) {
        if (newProcs != null) {
            final int numProcs = newProcs.size();
            final int numProcs = newProcs.size();
            if (processes == null) {
                processes = new ArrayMap<>(numProcs);
            }
            for (String key : newProcs.keySet()) {
            for (String key : newProcs.keySet()) {
                ParsedProcess newProc = newProcs.get(key);
                ParsedProcess newProc = newProcs.get(key);
                ParsedProcess proc = processes.get(newProc.getName());
                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.
     * Update tracked data about processes based on all known packages in the shared user ID.
     */
     */
    public void updateProcesses() {
    public void updateProcesses() {
        processes = null;
        processes.clear();
        for (int i = packages.size() - 1; i >= 0; i--) {
        for (int i = packages.size() - 1; i >= 0; i--) {
            final AndroidPackage pkg = packages.valueAt(i).pkg;
            final AndroidPackage pkg = packages.valueAt(i).pkg;
            if (pkg != null) {
            if (pkg != null) {
@@ -230,14 +266,15 @@ public final class SharedUserSetting extends SettingBase {
        this.signaturesChanged = sharedUser.signaturesChanged;
        this.signaturesChanged = sharedUser.signaturesChanged;
        if (sharedUser.processes != null) {
        if (sharedUser.processes != null) {
            final int numProcs = sharedUser.processes.size();
            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++) {
            for (int i = 0; i < numProcs; i++) {
                ParsedProcess proc =
                ParsedProcess proc =
                        new ParsedProcess(sharedUser.processes.valueAt(i));
                        new ParsedProcess(sharedUser.processes.valueAt(i));
                this.processes.put(proc.getName(), proc);
                this.processes.put(proc.getName(), proc);
            }
            }
        } else {
        } else {
            this.processes = null;
            this.processes.clear();
        }
        }
        onChanged();
        onChanged();
        return this;
        return this;
+1 −0
Original line number Original line Diff line number Diff line
@@ -198,6 +198,7 @@ public class PackageManagerSettingsTests {
                new WatchableTester(settingsUnderTest, "noSuspendingPackage");
                new WatchableTester(settingsUnderTest, "noSuspendingPackage");
        watcher.register();
        watcher.register();
        settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
        settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
        settingsUnderTest.readPackageRestrictionsLPr(0);
        watcher.verifyChangeReported("put package 1");
        watcher.verifyChangeReported("put package 1");
        // Collect a snapshot at the midway point (package 2 has not been added)
        // Collect a snapshot at the midway point (package 2 has not been added)
        final Settings snapshot = settingsUnderTest.snapshot();
        final Settings snapshot = settingsUnderTest.snapshot();