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

Commit 39ef1f3f authored by Winson's avatar Winson
Browse files

Add DomainVerificationSettings write/read to Settings

Introduces the concept of a domainSetId which represents an immutable
set of domains declared by the package. This is currently updated
whenever the package updates, hooked into the process for updating
a PackageSetting object.

Exempt-From-Owner-Approval: Already approved by owners on main branch

Bug: 163565712

Test: atest PackageManagerSettingsTests

Change-Id: I7c2c541cfdad7ddca7739424ee9e034fe616988b
parent dd04535e
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -1822,6 +1822,13 @@ public class PackageManagerService extends IPackageManager.Stub
    private class DomainVerificationConnection implements
            DomainVerificationService.Connection {
        @Override
        public void scheduleWriteSettings() {
            synchronized (mLock) {
                PackageManagerService.this.scheduleWriteSettingsLocked();
            }
        }
    }
    /**
@@ -5885,7 +5892,8 @@ public class PackageManagerService extends IPackageManager.Stub
                (i, pm) -> new Settings(Environment.getDataDirectory(),
                        RuntimePermissionsPersistence.createInstance(),
                        i.getPermissionManagerServiceInternal(),
                        i.getIntentFilterVerificationManager(), lock),
                        i.getIntentFilterVerificationManager(),
                        domainVerificationService, lock),
                (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
                (i, pm) -> SystemConfig.getInstance(),
@@ -13296,7 +13304,7 @@ public class PackageManagerService extends IPackageManager.Stub
        final int userId = user == null ? 0 : user.getIdentifier();
        // Modify state for the given package setting
        commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
        commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags,
                (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
        if (pkgSetting.getInstantApp(userId)) {
            mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
@@ -13553,6 +13561,9 @@ public class PackageManagerService extends IPackageManager.Stub
            usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
            parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
        }
        final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId();
        // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
        //  to avoid adding something that's unsupported due to lack of state, since it's called
        //  with null.
@@ -13576,7 +13587,8 @@ public class PackageManagerService extends IPackageManager.Stub
                    parsedPackage.getVersionCode(), pkgFlags, pkgPrivateFlags, user,
                    true /*allowInstall*/, instantApp, virtualPreload,
                    UserManagerService.getInstance(), usesStaticLibraries,
                    parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups());
                    parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
                    newDomainSetId);
        } else {
            // make a deep copy to avoid modifying any existing system state.
            pkgSetting = new PackageSetting(pkgSetting);
@@ -13595,7 +13607,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
                    UserManagerService.getInstance(),
                    usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
                    parsedPackage.getMimeGroups());
                    parsedPackage.getMimeGroups(), newDomainSetId);
        }
        if (createNewPackage && originalPkgSetting != null) {
            // This is the initial transition from the original package, so,
@@ -14440,8 +14452,8 @@ public class PackageManagerService extends IPackageManager.Stub
     * Adds a scanned package to the system. When this method is finished, the package will
     * be available for query, resolution, etc...
     */
    private void commitPackageSettings(AndroidPackage pkg,
            @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
    private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg,
            @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting,
            final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
        final String pkgName = pkg.getPackageName();
        if (mCustomResolverComponentName != null &&
@@ -20950,6 +20962,7 @@ public class PackageManagerService extends IPackageManager.Stub
                synchronized (mLock) {
                    mIntentFilterVerificationManager.clearIntentFilterVerificationsLocked(
                            deletedPs.name, UserHandle.USER_ALL, true);
                    mDomainVerificationManager.clearPackage(deletedPs.name);
                    clearDefaultBrowserIfNeeded(packageName);
                    mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
                    mAppsFilter.removePackage(getPackageSetting(packageName));
@@ -22084,6 +22097,7 @@ public class PackageManagerService extends IPackageManager.Stub
                mSettings.applyDefaultPreferredAppsLPw(userId);
                mIntentFilterVerificationManager.clearIntentFilterVerificationsLocked(userId,
                        mPackages);
                mDomainVerificationManager.clearUser(userId);
                primeDomainVerificationsLPw(userId);
                final int numPackages = mPackages.size();
                for (int i = 0; i < numPackages; i++) {
+19 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * Settings data for a particular package we know about.
@@ -99,18 +100,23 @@ public class PackageSetting extends PackageSettingBase {
    @NonNull
    private PackageStateUnserialized pkgState = new PackageStateUnserialized();

    @NonNull
    private UUID mDomainSetId;

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public PackageSetting(String name, String realName, @NonNull File codePath,
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
            String secondaryCpuAbiString, String cpuAbiOverrideString,
            long pVersionCode, int pkgFlags, int privateFlags,
            int sharedUserId, String[] usesStaticLibraries,
            long[] usesStaticLibrariesVersions, Map<String, ArraySet<String>> mimeGroups) {
            long[] usesStaticLibrariesVersions, Map<String, ArraySet<String>> mimeGroups,
            @NonNull UUID domainSetId) {
        super(name, realName, codePath, legacyNativeLibraryPathString,
                primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
                pVersionCode, pkgFlags, privateFlags,
                usesStaticLibraries, usesStaticLibrariesVersions);
        this.sharedUserId = sharedUserId;
        mDomainSetId = domainSetId;
        copyMimeGroups(mimeGroups);
    }

@@ -168,6 +174,7 @@ public class PackageSetting extends PackageSettingBase {
        sharedUser = orig.sharedUser;
        sharedUserId = orig.sharedUserId;
        copyMimeGroups(orig.mimeGroups);
        mDomainSetId = orig.getDomainSetId();
    }

    private void copyMimeGroups(@Nullable Map<String, ArraySet<String>> newMimeGroups) {
@@ -374,6 +381,7 @@ public class PackageSetting extends PackageSettingBase {
        pkg = other.pkg;
        sharedUserId = other.sharedUserId;
        sharedUser = other.sharedUser;
        mDomainSetId = other.mDomainSetId;

        Set<String> mimeGroupNames = other.mimeGroups != null ? other.mimeGroups.keySet() : null;
        updateMimeGroups(mimeGroupNames);
@@ -385,4 +393,14 @@ public class PackageSetting extends PackageSettingBase {
    public PackageStateUnserialized getPkgState() {
        return pkgState;
    }

    @NonNull
    public UUID getDomainSetId() {
        return mDomainSetId;
    }

    public PackageSetting setDomainSetId(@NonNull UUID domainSetId) {
        mDomainSetId = domainSetId;
        return this;
    }
}
+48 −11
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@ import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.LocalServices;
import com.android.server.backup.PreferredActivityBackupHelper;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.domain.verify.DomainVerificationManagerInternal;
import com.android.server.pm.domain.verify.DomainVerificationPersistence;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationManager;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -154,6 +156,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

/**
 * Holds information about dynamic settings.
@@ -510,6 +513,8 @@ public final class Settings implements Watchable, Snappable {

    private final IntentFilterVerificationManager mIntentFilterVerificationManager;

    private final DomainVerificationManagerInternal mDomainVerificationManager;

    /**
     * The observer that watches for changes from array members
     */
@@ -537,6 +542,7 @@ public final class Settings implements Watchable, Snappable {
        mBackupStoppedPackagesFilename = null;
        mKernelMappingFilename = null;
        mIntentFilterVerificationManager = null;
        mDomainVerificationManager = null;
        mPackages.registerObserver(mObserver);
        mInstallerPackages.registerObserver(mObserver);
        mKernelMapping.registerObserver(mObserver);
@@ -558,7 +564,9 @@ public final class Settings implements Watchable, Snappable {

    Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence,
            LegacyPermissionDataProvider permissionDataProvider,
            IntentFilterVerificationManager intentFilterVerificationManager, Object lock)  {
            @NonNull IntentFilterVerificationManager intentFilterVerificationManager,
            @NonNull DomainVerificationManagerInternal domainVerificationManager,
            @NonNull Object lock)  {
        mLock = lock;
        mAppIds = new WatchedArrayList<>();
        mOtherAppIds = new WatchedSparseArray<>();
@@ -586,6 +594,7 @@ public final class Settings implements Watchable, Snappable {
        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");

        mIntentFilterVerificationManager = intentFilterVerificationManager;
        mDomainVerificationManager = domainVerificationManager;

        mPackages.registerObserver(mObserver);
        mInstallerPackages.registerObserver(mObserver);
@@ -629,6 +638,7 @@ public final class Settings implements Watchable, Snappable {
        mKernelMappingFilename = null;

        mIntentFilterVerificationManager = r.mIntentFilterVerificationManager;
        mDomainVerificationManager = r.mDomainVerificationManager;

        mInstallerPackages.addAll(r.mInstallerPackages);
        mKernelMapping.putAll(r.mKernelMapping);
@@ -766,7 +776,8 @@ public final class Settings implements Watchable, Snappable {
                p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
                p.secondaryCpuAbiString, p.cpuAbiOverrideString,
                p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
                p.usesStaticLibraries, p.usesStaticLibrariesVersions, p.mimeGroups);
                p.usesStaticLibraries, p.usesStaticLibrariesVersions, p.mimeGroups,
                mDomainVerificationManager.generateNewId());
        if (ret != null) {
            ret.getPkgState().setUpdatedSystemApp(false);
        }
@@ -786,7 +797,8 @@ public final class Settings implements Watchable, Snappable {
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
            String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int
            pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries,
            long[] usesStaticLibraryNames, Map<String, ArraySet<String>> mimeGroups) {
            long[] usesStaticLibraryNames, Map<String, ArraySet<String>> mimeGroups,
            @NonNull UUID domainSetId) {
        PackageSetting p = mPackages.get(name);
        if (p != null) {
            if (p.appId == uid) {
@@ -799,7 +811,7 @@ public final class Settings implements Watchable, Snappable {
        p = new PackageSetting(name, realName, codePath, legacyNativeLibraryPathString,
                primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, vc, pkgFlags,
                pkgPrivateFlags, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames,
                mimeGroups);
                mimeGroups, domainSetId);
        p.appId = uid;
        if (registerExistingAppIdLPw(uid, p, name)) {
            mPackages.put(name, p);
@@ -863,7 +875,7 @@ public final class Settings implements Watchable, Snappable {
            UserHandle installUser, boolean allowInstall, boolean instantApp,
            boolean virtualPreload, UserManagerService userManager,
            String[] usesStaticLibraries, long[] usesStaticLibrariesVersions,
            Set<String> mimeGroupNames) {
            Set<String> mimeGroupNames, @NonNull UUID domainSetId) {
        final PackageSetting pkgSetting;
        if (originalPkg != null) {
            if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
@@ -883,12 +895,13 @@ public final class Settings implements Watchable, Snappable {
            pkgSetting.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
            // Update new package state.
            pkgSetting.setTimeStamp(codePath.lastModified());
            pkgSetting.setDomainSetId(domainSetId);
        } else {
            pkgSetting = new PackageSetting(pkgName, realPkgName, codePath,
                    legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
                    null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags,
                    0 /*sharedUserId*/, usesStaticLibraries,
                    usesStaticLibrariesVersions, createMimeGroups(mimeGroupNames));
                    usesStaticLibrariesVersions, createMimeGroups(mimeGroupNames), domainSetId);
            pkgSetting.setTimeStamp(codePath.lastModified());
            pkgSetting.sharedUser = sharedUser;
            // If this is not a system app, it starts out stopped.
@@ -983,7 +996,7 @@ public final class Settings implements Watchable, Snappable {
            @Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi, int pkgFlags,
            int pkgPrivateFlags, @NonNull UserManagerService userManager,
            @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions,
            @Nullable Set<String> mimeGroupNames)
            @Nullable Set<String> mimeGroupNames, @NonNull UUID domainSetId)
                    throws PackageManagerException {
        final String pkgName = pkgSetting.name;
        if (pkgSetting.sharedUser != sharedUser) {
@@ -1059,6 +1072,7 @@ public final class Settings implements Watchable, Snappable {
            pkgSetting.usesStaticLibrariesVersions = null;
        }
        pkgSetting.updateMimeGroups(mimeGroupNames);
        pkgSetting.setDomainSetId(domainSetId);
    }

    /**
@@ -2342,6 +2356,8 @@ public final class Settings implements Watchable, Snappable {

            mIntentFilterVerificationManager.writeRestoredIntentFilterVerifications(serializer);

            mDomainVerificationManager.writeSettings(serializer);

            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);

            serializer.endTag(null, "packages");
@@ -2717,6 +2733,8 @@ public final class Settings implements Watchable, Snappable {
        serializer.attributeFloat(null, "loadingProgress",
                pkg.getIncrementalStates().getProgress());

        serializer.attribute(null, "domainSetId", pkg.getDomainSetId().toString());

        writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);

        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
@@ -2904,6 +2922,8 @@ public final class Settings implements Watchable, Snappable {
                    ver.sdkVersion = parser.getAttributeInt(null, ATTR_SDK_VERSION);
                    ver.databaseVersion = parser.getAttributeInt(null, ATTR_DATABASE_VERSION);
                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
                } else if (tagName.equals(DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
                    mDomainVerificationManager.readSettings(parser);
                }else {
                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
                            + parser.getName());
@@ -3385,9 +3405,15 @@ public final class Settings implements Watchable, Snappable {
        if (codePathStr.contains("/priv-app/")) {
            pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
        }

        // When reading a disabled setting, use a disabled domainSetId, which makes it easier to
        // debug invalid entries. The actual logic for migrating to a new ID is done in other
        // methods that use DomainVerificationManagerInternal#generateNewId
        UUID domainSetId = DomainVerificationManagerInternal.DISABLED_ID;
        PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
                legacyNativeLibraryPathStr, primaryCpuAbiStr, secondaryCpuAbiStr, cpuAbiOverrideStr,
                versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserId*/, null, null, null);
                versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserId*/, null, null, null,
                domainSetId);
        long timeStamp = parser.getAttributeLongHex(null, "ft", 0);
        if (timeStamp == 0) {
            timeStamp = parser.getAttributeLong(null, "ts", 0);
@@ -3460,6 +3486,7 @@ public final class Settings implements Watchable, Snappable {
        boolean isStartable = false;
        boolean isLoading = false;
        float loadingProgress = 0;
        UUID domainSetId;
        try {
            name = parser.getAttributeValue(null, ATTR_NAME);
            realName = parser.getAttributeValue(null, "realName");
@@ -3496,6 +3523,15 @@ public final class Settings implements Watchable, Snappable {
            categoryHint = parser.getAttributeInt(null, "categoryHint",
                    ApplicationInfo.CATEGORY_UNDEFINED);

            String domainSetIdString = parser.getAttributeValue(null, "domainSetId");

            if (TextUtils.isEmpty(domainSetIdString)) {
                // If empty, assume restoring from previous platform version and generate an ID
                domainSetId = mDomainVerificationManager.generateNewId();
            } else {
                domainSetId = UUID.fromString(domainSetIdString);
            }

            systemStr = parser.getAttributeValue(null, "publicFlags");
            if (systemStr != null) {
                try {
@@ -3567,7 +3603,7 @@ public final class Settings implements Watchable, Snappable {
                        legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString,
                        cpuAbiOverrideString, userId, versionCode, pkgFlags, pkgPrivateFlags,
                        null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/,
                        null /*mimeGroups*/);
                        null /*mimeGroups*/, domainSetId);
                if (PackageManagerService.DEBUG_SETTINGS)
                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
                            + userId + " pkg=" + packageSetting);
@@ -3588,7 +3624,7 @@ public final class Settings implements Watchable, Snappable {
                            versionCode, pkgFlags, pkgPrivateFlags, sharedUserId,
                            null /*usesStaticLibraries*/,
                            null /*usesStaticLibraryVersions*/,
                            null /*mimeGroups*/);
                            null /*mimeGroups*/, domainSetId);
                    packageSetting.setTimeStamp(timeStamp);
                    packageSetting.firstInstallTime = firstInstallTime;
                    packageSetting.lastUpdateTime = lastUpdateTime;
@@ -3974,6 +4010,7 @@ public final class Settings implements Watchable, Snappable {
        removeCrossProfileIntentFiltersLPw(userId);

        mRuntimePermissionsPersistence.onUserRemovedLPw(userId);
        mDomainVerificationManager.clearUser(userId);

        writePackageListLPr();

+66 −1
Original line number Diff line number Diff line
@@ -16,10 +16,75 @@

package com.android.server.pm.domain.verify;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.pm.domain.verify.DomainVerificationManager;
import android.content.pm.domain.verify.DomainVerificationSet;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;

import com.android.server.pm.domain.verify.models.DomainVerificationPkgState;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.UUID;

public interface DomainVerificationManagerInternal extends DomainVerificationManager {

    // TODO(b/159952358): Skeleton checked in to prepare for future internal methods
    UUID DISABLED_ID = new UUID(0, 0);

    /**
     * Generate a new domain set ID to be used for attaching new packages.
     */
    @NonNull
    UUID generateNewId();

    /**
     * Serializes the entire internal state. This is equivalent to a full backup of the existing
     * verification state.
     */
    void writeSettings(@NonNull TypedXmlSerializer serializer) throws IOException;

    /**
     * Read back a list of {@link DomainVerificationPkgState}s previously written by {@link
     * #writeSettings(TypedXmlSerializer)}. Assumes that the
     * {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS}
     * tag has already been entered.
     * <p>
     * This is expected to only be used to re-attach states for packages already known to be on the
     * device. If restoring from a backup, use {@link #restoreSettings(TypedXmlPullParser)}.
     */
    void readSettings(@NonNull TypedXmlPullParser parser)
            throws IOException, XmlPullParserException;

    /**
     * Remove all state for the given package.
     */
    void clearPackage(@NonNull String packageName);

    /**
     * Delete all the state for a user. This can be because the user has been removed from the
     * device, or simply that the state for a user should be deleted.
     */
    void clearUser(@UserIdInt int userId);

    /**
     * Restore a list of {@link DomainVerificationPkgState}s previously written by {@link
     * #writeSettings(TypedXmlSerializer)}. Assumes that the
     * {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS}
     * tag has already been entered.
     * <p>
     * This is <b>only</b> for restore, and will override package states, ignoring if their {@link
     * DomainVerificationSet#getIdentifier()}s match. It's expected that any restored domains marked
     * as success verify against the server correctly, although the verification agent may decide to
     * re-verify them when it gets the chance.
     */
    /*
     * TODO(b/170746586): Figure out how to verify that package signatures match at snapshot time
     *  and restore time.
     */
    void restoreSettings(@NonNull TypedXmlPullParser parser)
            throws IOException, XmlPullParserException;

}
+95 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading