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

Commit 87a504d1 authored by Oli Lan's avatar Oli Lan Committed by Bill Lin
Browse files

Remove INSTALLED_USERS extra from ACTION_PACKAGE_ENABLE_ROLLBACK.

This changes RollbackManagerServiceImpl to use the list of installed users
that is passed in to snapshotAndRestoreUserData for the purpose of snapshotting.

With this change, it is no longer necessary for the list of installed users to be
added as an extra to the ENABLE_ROLLBACK intent, so that extra
(EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS) is removed.

Bug: 139181444
Test: atest RollbackTest
Test: atest AppDataRollbackHelperTest
Exempt-From-Owner-Approval: Already approved in
https://googleplex-android-review.git.corp.google.com/c/platform/frameworks/base/+/9168506

Change-Id: Iff42f4e5b2d02d1124d64a5fedc659a41cddd5fc
Merged-In: Iffd63977a7498e3cba20d2039af623c921d38f57
parent 3e7ef5ae
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -889,12 +889,6 @@ public abstract class PackageManagerInternal {
    public static final String EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS =
            "android.content.pm.extra.ENABLE_ROLLBACK_INSTALL_FLAGS";

    /**
     * Extra field name for the set of installed users for a given rollback package.
     */
    public static final String EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS =
            "android.content.pm.extra.ENABLE_ROLLBACK_INSTALLED_USERS";

    /**
     * Extra field name for the user id an install is associated with when
     * enabling rollback.
+7 −7
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ public final class PackageRollbackInfo implements Parcelable {
    private final boolean mIsApex;

    /*
     * The list of users the package is installed for.
     * The list of users for which snapshots have been saved.
     */
    // NOTE: Not a part of the Parcelable representation of this object.
    private final IntArray mInstalledUsers;
    private final IntArray mSnapshottedUsers;

    /**
     * A mapping between user and an inode of theirs CE data snapshot.
@@ -148,8 +148,8 @@ public final class PackageRollbackInfo implements Parcelable {
    }

    /** @hide */
    public IntArray getInstalledUsers() {
        return mInstalledUsers;
    public IntArray getSnapshottedUsers() {
        return mSnapshottedUsers;
    }

    /** @hide */
@@ -179,14 +179,14 @@ public final class PackageRollbackInfo implements Parcelable {
    public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
            VersionedPackage packageRolledBackTo,
            @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
            boolean isApex, @NonNull IntArray installedUsers,
            boolean isApex, @NonNull IntArray snapshottedUsers,
            @NonNull SparseLongArray ceSnapshotInodes) {
        this.mVersionRolledBackFrom = packageRolledBackFrom;
        this.mVersionRolledBackTo = packageRolledBackTo;
        this.mPendingBackups = pendingBackups;
        this.mPendingRestores = pendingRestores;
        this.mIsApex = isApex;
        this.mInstalledUsers = installedUsers;
        this.mSnapshottedUsers = snapshottedUsers;
        this.mCeSnapshotInodes = ceSnapshotInodes;
    }

@@ -196,7 +196,7 @@ public final class PackageRollbackInfo implements Parcelable {
        this.mIsApex = in.readBoolean();
        this.mPendingRestores = null;
        this.mPendingBackups = null;
        this.mInstalledUsers = null;
        this.mSnapshottedUsers = null;
        this.mCeSnapshotInodes = null;
    }

+0 −14
Original line number Diff line number Diff line
@@ -15092,17 +15092,6 @@ public class PackageManagerService extends IPackageManager.Stub
                            TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
                    mPendingEnableRollback.append(enableRollbackToken, this);
                    final int[] installedUsers;
                    synchronized (mPackages) {
                        PackageSetting ps = mSettings.getPackageLPr(pkgLite.packageName);
                        if (ps != null) {
                            installedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(),
                                    true);
                        } else {
                            installedUsers = new int[0];
                        }
                    }
                    Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
@@ -15110,9 +15099,6 @@ public class PackageManagerService extends IPackageManager.Stub
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS,
                            installFlags);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS,
                            installedUsers);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER,
                            getRollbackUser().getIdentifier());
+7 −5
Original line number Diff line number Diff line
@@ -52,12 +52,13 @@ public class AppDataRollbackHelper {
    }

    /**
     * Creates an app data snapshot for a specified {@code packageRollbackInfo}. Updates said {@code
     * packageRollbackInfo} with the inodes of the CE user data snapshot folders.
     * Creates an app data snapshot for a specified {@code packageRollbackInfo} and the specified
     * {@code userIds}. Updates said {@code packageRollbackInfo} with the inodes of the CE user data
     * snapshot folders.
     */
    public void snapshotAppData(int snapshotId, PackageRollbackInfo packageRollbackInfo) {
        final int[] installedUsers = packageRollbackInfo.getInstalledUsers().toArray();
        for (int user : installedUsers) {
    public void snapshotAppData(
            int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
        for (int user : userIds) {
            final int storageFlags;
            if (isUserCredentialLocked(user)) {
                // We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
@@ -80,6 +81,7 @@ public class AppDataRollbackHelper {
                        + packageRollbackInfo.getPackageName() + ", userId: " + user, ie);
            }
        }
        packageRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
    }

    /**
+20 −48
Original line number Diff line number Diff line
@@ -177,16 +177,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1);
                    int installFlags = intent.getIntExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, 0);
                    int[] installedUsers = intent.getIntArrayExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS);
                    int user = intent.getIntExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER, 0);

                    File newPackageCodePath = new File(intent.getData().getPath());

                    getHandler().post(() -> {
                        boolean success = enableRollback(installFlags, newPackageCodePath,
                                installedUsers, user, token);
                        boolean success =
                                enableRollback(installFlags, newPackageCodePath, user, token);
                        int ret = PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED;
                        if (!success) {
                            ret = PackageManagerInternal.ENABLE_ROLLBACK_FAILED;
@@ -821,13 +819,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     *
     * @param installFlags information about what is being installed.
     * @param newPackageCodePath path to the package about to be installed.
     * @param installedUsers the set of users for which a given package is installed.
     * @param user the user that owns the install session to enable rollback on.
     * @param token the distinct rollback token sent by package manager.
     * @return true if enabling the rollback succeeds, false otherwise.
     */
    private boolean enableRollback(int installFlags, File newPackageCodePath,
            int[] installedUsers, @UserIdInt int user, int token) {
    private boolean enableRollback(
            int installFlags, File newPackageCodePath, @UserIdInt int user, int token) {

        // Find the session id associated with this install.
        // TODO: It would be nice if package manager or package installer told
@@ -872,38 +869,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

        // Check to see if this is the apk session for a staged session with
        // rollback enabled.
        // TODO: This check could be made more efficient.
        RollbackData rd = null;
        synchronized (mLock) {
            for (int i = 0; i < mRollbacks.size(); ++i) {
                RollbackData data = mRollbacks.get(i);
                if (data.apkSessionId == parentSession.getSessionId()) {
                    rd = data;
                    break;
                }
            }
        }

        if (rd != null) {
            // This is the apk session for a staged session. We do not need to create a new rollback
            // for this session.
            PackageParser.PackageLite newPackage = null;
            try {
                newPackage = PackageParser.parsePackageLite(
                        new File(packageSession.resolvedBaseCodePath), 0);
            } catch (PackageParser.PackageParserException e) {
                Slog.e(TAG, "Unable to parse new package", e);
                return false;
            }
            String packageName = newPackage.packageName;
            for (PackageRollbackInfo info : rd.info.getPackages()) {
                if (info.getPackageName().equals(packageName)) {
                    info.getInstalledUsers().addAll(IntArray.wrap(installedUsers));
                    // This is the apk session for a staged session with rollback enabled. We do not
                    // need to create a new rollback for this session.
                    return true;
                }
            }
            Slog.e(TAG, "Unable to find package in apk session");
            return false;
        }

        NewRollback newRollback;
@@ -919,7 +893,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        }
        newRollback.addToken(token);

        return enableRollbackForPackageSession(newRollback.data, packageSession, installedUsers);
        return enableRollbackForPackageSession(newRollback.data, packageSession);
    }

    /**
@@ -930,7 +904,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     * @return true on success, false on failure.
     */
    private boolean enableRollbackForPackageSession(RollbackData data,
            PackageInstaller.SessionInfo session, @NonNull int[] installedUsers) {
            PackageInstaller.SessionInfo session) {
        // TODO: Don't attempt to enable rollback for split installs.
        final int installFlags = session.installFlags;
        if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
@@ -988,8 +962,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(
                newVersion, installedVersion,
                new IntArray() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
                isApex, IntArray.wrap(installedUsers),
                new SparseLongArray() /* ceSnapshotInodes */);
                isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */);

        try {
            ApplicationInfo appInfo = pkgInfo.applicationInfo;
@@ -1019,7 +992,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        }

        getHandler().post(() -> {
            snapshotUserDataInternal(packageName);
            snapshotUserDataInternal(packageName, userIds);
            restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token);
            final PackageManagerInternal pmi = LocalServices.getService(
                    PackageManagerInternal.class);
@@ -1027,7 +1000,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        });
    }

    private void snapshotUserDataInternal(String packageName) {
    private void snapshotUserDataInternal(String packageName, int[] userIds) {
        synchronized (mLock) {
            // staged installs
            for (int i = 0; i < mRollbacks.size(); i++) {
@@ -1038,7 +1011,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

                for (PackageRollbackInfo info : data.info.getPackages()) {
                    if (info.getPackageName().equals(packageName)) {
                        mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info);
                        mAppDataRollbackHelper.snapshotAppData(
                                data.info.getRollbackId(), info, userIds);
                        saveRollbackData(data);
                        break;
                    }
@@ -1049,8 +1023,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            for (NewRollback rollback : mNewRollbacks) {
                info = getPackageRollbackInfo(rollback.data, packageName);
                if (info != null) {
                    mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(),
                            info);
                    mAppDataRollbackHelper.snapshotAppData(
                            rollback.data.info.getRollbackId(), info, userIds);
                    saveRollbackData(rollback.data);
                }
            }
@@ -1114,8 +1088,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }

            if (!session.isMultiPackage()) {
                if (!enableRollbackForPackageSession(newRollback.data, session,
                            new int[0])) {
                if (!enableRollbackForPackageSession(newRollback.data, session)) {
                    Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
                    result.offer(false);
                    return;
@@ -1129,8 +1102,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                        result.offer(false);
                        return;
                    }
                    if (!enableRollbackForPackageSession(newRollback.data, childSession,
                                new int[0])) {
                    if (!enableRollbackForPackageSession(newRollback.data, childSession)) {
                        Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
                        result.offer(false);
                        return;
@@ -1407,9 +1379,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

    private void deleteRollback(RollbackData rollbackData) {
        for (PackageRollbackInfo info : rollbackData.info.getPackages()) {
            IntArray installedUsers = info.getInstalledUsers();
            for (int i = 0; i < installedUsers.size(); i++) {
                int userId = installedUsers.get(i);
            IntArray snapshottedUsers = info.getSnapshottedUsers();
            for (int i = 0; i < snapshottedUsers.size(); i++) {
                int userId = snapshottedUsers.get(i);
                mAppDataRollbackHelper.destroyAppDataSnapshot(rollbackData.info.getRollbackId(),
                        info, userId);
            }
Loading