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

Commit 9202b39f authored by Winson's avatar Winson
Browse files

Implement domain verification backup and restore

Hooks up PreferredActivityBackupHelper to the domain verification XML,
replacing the old intent filter verification backup.

Also fixes a leftover bug where linkHandlingAllowed state was not
being deserialized properly.

Bug: 170746586
Bug: 182206123

Test: atest DomainVerificationPackageTest
Test: atest DomainVerificationPersistenceTest

Change-Id: I418c62866da4f82bf387a3b95d0139c2236ea62c
parent c5b6959f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -310,8 +310,8 @@ interface IPackageManager {
    void restorePreferredActivities(in byte[] backup, int userId);
    byte[] getDefaultAppsBackup(int userId);
    void restoreDefaultApps(in byte[] backup, int userId);
    byte[] getIntentFilterVerificationBackup(int userId);
    void restoreIntentFilterVerification(in byte[] backup, int userId);
    byte[] getDomainVerificationBackup(int userId);
    void restoreDomainVerification(in byte[] backup, int userId);

    /**
     * Report the set of 'Home' activity candidates, plus (if any) which of them
+50 −17
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@

package com.android.server.backup;

import android.annotation.StringDef;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.app.backup.BlobBackupHelper;
import android.content.pm.IPackageManager;
import android.os.UserHandle;
import android.content.pm.verify.domain.DomainVerificationManager;
import android.util.Slog;

public class PreferredActivityBackupHelper extends BlobBackupHelper {
@@ -27,7 +29,7 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper {
    private static final boolean DEBUG = false;

    // current schema of the backup state blob
    private static final int STATE_VERSION = 3;
    private static final int STATE_VERSION = 4;

    // key under which the preferred-activity state blob is committed to backup
    private static final String KEY_PREFERRED = "preferred-activity";
@@ -35,14 +37,41 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper {
    // key for default-browser [etc] state
    private static final String KEY_DEFAULT_APPS = "default-apps";

    // intent-filter verification state
    /**
     * Intent-filter verification state
     * @deprecated Replaced by {@link #KEY_DOMAIN_VERIFICATION}, retained to ensure the key is
     * never reused.
     */
    @Deprecated
    private static final String KEY_INTENT_VERIFICATION = "intent-verification";

    public PreferredActivityBackupHelper() {
        super(STATE_VERSION,
    /**
     * State for {@link DomainVerificationManager}.
     */
    private static final String KEY_DOMAIN_VERIFICATION = "domain-verification";

    private static final String[] KEYS = new String[] {
            KEY_PREFERRED,
            KEY_DEFAULT_APPS,
            KEY_INTENT_VERIFICATION,
            KEY_DOMAIN_VERIFICATION
    };

    @StringDef(value = {
            KEY_PREFERRED,
            KEY_DEFAULT_APPS,
                KEY_INTENT_VERIFICATION);
            KEY_INTENT_VERIFICATION,
            KEY_DOMAIN_VERIFICATION
    })
    private @interface Key {
    }

    @UserIdInt
    private final int mUserId;

    public PreferredActivityBackupHelper(@UserIdInt int userId) {
        super(STATE_VERSION, KEYS);
        mUserId = userId;
    }

    @Override
@@ -52,14 +81,16 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper {
            Slog.d(TAG, "Handling backup of " + key);
        }
        try {
            // TODO: http://b/22388012
            switch (key) {
                case KEY_PREFERRED:
                    return pm.getPreferredActivityBackup(UserHandle.USER_SYSTEM);
                    return pm.getPreferredActivityBackup(mUserId);
                case KEY_DEFAULT_APPS:
                    return pm.getDefaultAppsBackup(UserHandle.USER_SYSTEM);
                    return pm.getDefaultAppsBackup(mUserId);
                case KEY_INTENT_VERIFICATION:
                    return pm.getIntentFilterVerificationBackup(UserHandle.USER_SYSTEM);
                    // Deprecated
                    return null;
                case KEY_DOMAIN_VERIFICATION:
                    return pm.getDomainVerificationBackup(mUserId);
                default:
                    Slog.w(TAG, "Unexpected backup key " + key);
            }
@@ -70,22 +101,24 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper {
    }

    @Override
    protected void applyRestoredPayload(String key, byte[] payload) {
    protected void applyRestoredPayload(@Key String key, byte[] payload) {
        IPackageManager pm = AppGlobals.getPackageManager();
        if (DEBUG) {
            Slog.d(TAG, "Handling restore of " + key);
        }
        try {
            // TODO: http://b/22388012
            switch (key) {
                case KEY_PREFERRED:
                    pm.restorePreferredActivities(payload, UserHandle.USER_SYSTEM);
                    pm.restorePreferredActivities(payload, mUserId);
                    break;
                case KEY_DEFAULT_APPS:
                    pm.restoreDefaultApps(payload, UserHandle.USER_SYSTEM);
                    pm.restoreDefaultApps(payload, mUserId);
                    break;
                case KEY_INTENT_VERIFICATION:
                    pm.restoreIntentFilterVerification(payload, UserHandle.USER_SYSTEM);
                    // Deprecated
                    break;
                case KEY_DOMAIN_VERIFICATION:
                    pm.restoreDomainVerification(payload, mUserId);
                    break;
                default:
                    Slog.w(TAG, "Unexpected restore key " + key);
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
        mUserId = user.getIdentifier();

        addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
        addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
        addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
        addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
        addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
+47 −6
Original line number Diff line number Diff line
@@ -1788,6 +1788,24 @@ public class PackageManagerService extends IPackageManager.Stub
            }
        }
        @Override
        public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
                withPackageSettingsThrowing2(
                        @NonNull Throwing2Consumer<Function<String, PackageSetting>, ExceptionOne,
                                ExceptionTwo> block) throws ExceptionOne, ExceptionTwo {
            final Computer snapshot = snapshotComputer();
            // This method needs to either lock or not lock consistently throughout the method,
            // so if the live computer is returned, force a wrapping sync block.
            if (snapshot == mLiveComputer) {
                synchronized (mLock) {
                    block.accept(snapshot::getPackageSetting);
                }
            } else {
                block.accept(snapshot::getPackageSetting);
            }
        }
        @Override
        public <Output, ExceptionType extends Exception> Output
                withPackageSettingsReturningThrowing(@NonNull ThrowingFunction<Function<String,
@@ -22618,21 +22636,44 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    @Override
    public byte[] getIntentFilterVerificationBackup(int userId) {
    public byte[] getDomainVerificationBackup(int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
            throw new SecurityException("Only the system may call getDomainVerificationBackup()");
        }
        // TODO(b/170746586)
        try {
            try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
                TypedXmlSerializer serializer = Xml.resolveSerializer(output);
                mDomainVerificationManager.writeSettings(serializer, true, userId);
                return output.toByteArray();
            }
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Unable to write domain verification for backup", e);
            }
            return null;
        }
    }
    @Override
    public void restoreIntentFilterVerification(byte[] backup, int userId) {
    public void restoreDomainVerification(byte[] backup, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call restorePreferredActivities()");
        }
        // TODO(b/170746586)
        try {
            ByteArrayInputStream input = new ByteArrayInputStream(backup);
            TypedXmlPullParser parser = Xml.resolvePullParser(input);
            // User ID input isn't necessary here as it assumes the user integers match and that
            // the only states inside the backup XML are for the target user.
            mDomainVerificationManager.restoreSettings(parser);
            input.close();
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage());
            }
        }
    }
    @Override
+3 −8
Original line number Diff line number Diff line
@@ -2323,7 +2323,8 @@ public final class Settings implements Watchable, Snappable {
                }
            }

            mDomainVerificationManager.writeSettings(serializer);
            mDomainVerificationManager.writeSettings(serializer, false /* includeSignatures */,
                    UserHandle.USER_ALL);

            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);

@@ -2900,13 +2901,7 @@ public final class Settings implements Watchable, Snappable {
            }

            str.close();

        } catch (XmlPullParserException e) {
            mReadMessages.append("Error reading: " + e.toString());
            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);

        } catch (java.io.IOException e) {
        } catch (IOException | XmlPullParserException e) {
            mReadMessages.append("Error reading: " + e.toString());
            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
Loading