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

Commit 639e1e74 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Iae43f695,I6ca164ad,I4f579393,Icbb67c3c

* changes:
  Rename saveAvailableRollback to saveRollbackData.
  Have RollbackData reuse RollbackInfo.
  Miscellaneous cleanup in RollbackStore.
  Rename RollbackData.inProgress to restoreUserDataInProgress.
parents 3ff9abc1 aad02c07
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -17,12 +17,10 @@
package android.content.rollback;

import android.annotation.SystemApi;
import android.content.pm.PackageInstaller;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Collections;
import java.util.List;

/**
@@ -44,13 +42,7 @@ public final class RollbackInfo implements Parcelable {
    private final List<VersionedPackage> mCausePackages;

    private final boolean mIsStaged;
    private final int mCommittedSessionId;

    /** @hide */
    public RollbackInfo(int rollbackId, List<PackageRollbackInfo> packages, boolean isStaged) {
        this(rollbackId, packages, isStaged, Collections.emptyList(),
                PackageInstaller.SessionInfo.INVALID_ID);
    }
    private int mCommittedSessionId;

    /** @hide */
    public RollbackInfo(int rollbackId, List<PackageRollbackInfo> packages, boolean isStaged,
@@ -100,6 +92,14 @@ public final class RollbackInfo implements Parcelable {
        return mCommittedSessionId;
    }

    /**
     * Sets the session ID for the committed rollback for staged rollbacks.
     * @hide
     */
    public void setCommittedSessionId(int sessionId) {
        mCommittedSessionId = sessionId;
    }

    /**
     * Gets the list of package versions that motivated this rollback.
     * As provided to {@link #commitRollback} when the rollback was committed.
+3 −3
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ public class AppDataRollbackHelper {
        List<RollbackData> rd = new ArrayList<>();

        for (RollbackData data : availableRollbacks) {
            for (PackageRollbackInfo info : data.packages) {
            for (PackageRollbackInfo info : data.info.getPackages()) {
                final IntArray pendingBackupUsers = info.getPendingBackups();
                if (pendingBackupUsers != null) {
                    final int idx = pendingBackupUsers.indexOf(userId);
@@ -246,13 +246,13 @@ public class AppDataRollbackHelper {

        if (!pendingBackupPackages.isEmpty()) {
            for (RollbackData data : pendingBackups) {
                for (PackageRollbackInfo info : data.packages) {
                for (PackageRollbackInfo info : data.info.getPackages()) {
                    final IntArray pendingBackupUsers = info.getPendingBackups();
                    final int idx = pendingBackupUsers.indexOf(userId);
                    if (idx != -1) {
                        try {
                            long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
                                    userId, data.rollbackId, Installer.FLAG_STORAGE_CE);
                                    userId, data.info.getRollbackId(), Installer.FLAG_STORAGE_CE);
                            info.putCeSnapshotInode(userId, ceSnapshotInode);
                            pendingBackupUsers.remove(idx);
                        } catch (InstallerException ie) {
+35 −16
Original line number Diff line number Diff line
@@ -16,12 +16,11 @@

package com.android.server.rollback;

import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;

import java.io.File;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

/**
 * Information about a rollback available for a set of atomically installed
@@ -29,14 +28,9 @@ import java.util.List;
 */
class RollbackData {
    /**
     * A unique identifier for this rollback.
     * The rollback info for this rollback.
     */
    public final int rollbackId;

    /**
     * The per-package rollback information.
     */
    public final List<PackageRollbackInfo> packages = new ArrayList<>();
    public final RollbackInfo info;

    /**
     * The directory where the rollback data is stored.
@@ -69,24 +63,49 @@ class RollbackData {
    public int apkSessionId = -1;

    /**
     * Whether this Rollback is currently in progress. This field is true from the point
     * we commit a {@code PackageInstaller} session containing these packages to the point the
     * {@code PackageInstaller} calls into the {@code onFinished} callback.
     * True if we are expecting the package manager to call restoreUserData
     * for this rollback because it has just been committed but the rollback
     * has not yet been fully applied.
     */
    // NOTE: All accesses to this field are from the RollbackManager handler thread.
    public boolean inProgress = false;
    public boolean restoreUserDataInProgress = false;

    /**
     * Constructs a new, empty RollbackData instance.
     *
     * @param rollbackId the id of the rollback.
     * @param backupDir the directory where the rollback data is stored.
     * @param stagedSessionId the session id if this is a staged rollback, -1 otherwise.
     */
    RollbackData(int rollbackId, File backupDir, int stagedSessionId) {
        this.info = new RollbackInfo(rollbackId,
                /* packages */ new ArrayList<>(),
                /* isStaged */ stagedSessionId != -1,
                /* causePackages */ new ArrayList<>(),
                /* committedSessionId */ -1);
        this.backupDir = backupDir;
        this.stagedSessionId = stagedSessionId;
        this.isAvailable = (stagedSessionId == -1);
    }

    RollbackData(int rollbackId, File backupDir, int stagedSessionId, boolean isAvailable) {
        this.rollbackId = rollbackId;
    /**
     * Constructs a RollbackData instance with full rollback data information.
     */
    RollbackData(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
            boolean isAvailable, int apkSessionId, boolean restoreUserDataInProgress) {
        this.info = info;
        this.backupDir = backupDir;
        this.timestamp = timestamp;
        this.stagedSessionId = stagedSessionId;
        this.isAvailable = isAvailable;
        this.apkSessionId = apkSessionId;
        this.restoreUserDataInProgress = restoreUserDataInProgress;
    }

    /**
     * Whether the rollback is for rollback of a staged install.
     */
    public boolean isStaged() {
        return stagedSessionId != -1;
        return info.isStaged();
    }
}
+45 −44
Original line number Diff line number Diff line
@@ -243,8 +243,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                RollbackData data = mAvailableRollbacks.get(i);
                if (data.isAvailable) {
                    rollbacks.add(new RollbackInfo(data.rollbackId,
                                data.packages, data.isStaged()));
                    rollbacks.add(data.info);
                }
            }
            return new ParceledListSlice<>(rollbacks);
@@ -297,12 +296,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

                        data.timestamp = data.timestamp.plusMillis(timeDifference);
                        try {
                            mRollbackStore.saveAvailableRollback(data);
                            mRollbackStore.saveRollbackData(data);
                        } catch (IOException ioe) {
                            // TODO: figure out the right way to deal with this, especially if
                            //  it fails for some data and succeeds for others.
                            Log.e(TAG, "Unable to save rollback info for : " + data.rollbackId,
                                    ioe);
                            Log.e(TAG, "Unable to save rollback info for : "
                                    + data.info.getRollbackId(), ioe);
                        }
                    }

@@ -335,7 +334,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            return;
        }

        if (data.inProgress) {
        if (data.restoreUserDataInProgress) {
            sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
                    "Rollback for package is already in progress.");
            return;
@@ -349,7 +348,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        // rollback racing with a roll-forward fix of a buggy package.
        // Figure out how to ensure we don't commit the rollback if
        // roll forward happens at the same time.
        for (PackageRollbackInfo info : data.packages) {
        for (PackageRollbackInfo info : data.info.getPackages()) {
            VersionedPackage installedVersion = getInstalledPackageVersion(info.getPackageName());
            if (installedVersion == null) {
                // TODO: Test this case
@@ -391,7 +390,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            int parentSessionId = packageInstaller.createSession(parentParams);
            PackageInstaller.Session parentSession = packageInstaller.openSession(parentSessionId);

            for (PackageRollbackInfo info : data.packages) {
            for (PackageRollbackInfo info : data.info.getPackages()) {
                PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                        PackageInstaller.SessionParams.MODE_FULL_INSTALL);
                // TODO: We can't get the installerPackageName for apex
@@ -441,7 +440,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                        getHandler().post(() -> {
                            // We've now completed the rollback, so we mark it as no longer in
                            // progress.
                            data.inProgress = false;
                            data.restoreUserDataInProgress = false;

                            int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                                    PackageInstaller.STATUS_FAILURE);
@@ -453,9 +452,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                                return;
                            }

                            addRecentlyExecutedRollback(new RollbackInfo(
                                        data.rollbackId, data.packages, data.isStaged(),
                                        causePackages, parentSessionId));
                            data.info.setCommittedSessionId(parentSessionId);
                            data.info.getCausePackages().addAll(causePackages);
                            addRecentlyExecutedRollback(data.info);
                            sendSuccess(statusReceiver);

                            Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
@@ -469,7 +468,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    }
            );

            data.inProgress = true;
            data.restoreUserDataInProgress = true;
            parentSession.commit(receiver.getIntentSender());
        } catch (IOException e) {
            Log.e(TAG, "Rollback failed", e);
@@ -510,7 +509,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            Iterator<RollbackData> iter = mAvailableRollbacks.iterator();
            while (iter.hasNext()) {
                RollbackData data = iter.next();
                for (PackageRollbackInfo info : data.packages) {
                for (PackageRollbackInfo info : data.info.getPackages()) {
                    if (info.getPackageName().equals(packageName)) {
                        iter.remove();
                        deleteRollback(data);
@@ -537,9 +536,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

            for (RollbackData rd : changed) {
                try {
                    mRollbackStore.saveAvailableRollback(rd);
                    mRollbackStore.saveRollbackData(rd);
                } catch (IOException ioe) {
                    Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
                    Log.e(TAG, "Unable to save rollback info for : "
                            + rd.info.getRollbackId(), ioe);
                }
            }

@@ -575,7 +575,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            synchronized (mLock) {
                ensureRollbackDataLoadedLocked();
                for (RollbackData data : mAvailableRollbacks) {
                    if (data.stagedSessionId != -1) {
                    if (!data.isAvailable && data.isStaged()) {
                        staged.add(data);
                    }
                }
@@ -591,10 +591,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                            data.isAvailable = true;
                        }
                        try {
                            mRollbackStore.saveAvailableRollback(data);
                            mRollbackStore.saveRollbackData(data);
                        } catch (IOException ioe) {
                            Log.e(TAG, "Unable to save rollback info for : "
                                    + data.rollbackId, ioe);
                                    + data.info.getRollbackId(), ioe);
                        }
                    } else if (session.isStagedSessionFailed()) {
                        // TODO: Do we need to remove this from
@@ -641,7 +641,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private void loadAllRollbackDataLocked() {
        mAvailableRollbacks = mRollbackStore.loadAvailableRollbacks();
        for (RollbackData data : mAvailableRollbacks) {
            mAllocatedRollbackIds.put(data.rollbackId, true);
            mAllocatedRollbackIds.put(data.info.getRollbackId(), true);
        }

        mRecentlyExecutedRollbacks = mRollbackStore.loadRecentlyExecutedRollbacks();
@@ -665,7 +665,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            Iterator<RollbackData> iter = mAvailableRollbacks.iterator();
            while (iter.hasNext()) {
                RollbackData data = iter.next();
                for (PackageRollbackInfo info : data.packages) {
                for (PackageRollbackInfo info : data.info.getPackages()) {
                    if (info.getPackageName().equals(packageName)
                            && !packageVersionsEqual(
                                        info.getVersionRolledBackFrom(),
@@ -897,18 +897,19 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                return false;
            }
            String packageName = newPackage.packageName;
            for (PackageRollbackInfo info : rd.packages) {
            for (PackageRollbackInfo info : rd.info.getPackages()) {
                if (info.getPackageName().equals(packageName)) {
                    info.getInstalledUsers().addAll(IntArray.wrap(installedUsers));
                    mAppDataRollbackHelper.snapshotAppData(rd.rollbackId, info);
                    mAppDataRollbackHelper.snapshotAppData(rd.info.getRollbackId(), info);
                    try {
                        mRollbackStore.saveAvailableRollback(rd);
                        mRollbackStore.saveRollbackData(rd);
                    } catch (IOException ioe) {
                        // TODO: Hopefully this is okay because we will try
                        // again to save the rollback when the staged session
                        // is applied. Just so long as the device doesn't
                        // reboot before then.
                        Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
                        Log.e(TAG, "Unable to save rollback info for : "
                                + rd.info.getRollbackId(), ioe);
                    }
                    return true;
                }
@@ -989,14 +990,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                if (data == null) {
                    int rollbackId = allocateRollbackIdLocked();
                    if (session.isStaged()) {
                        data = mRollbackStore.createPendingStagedRollback(rollbackId,
                            parentSessionId);
                        data = mRollbackStore.createStagedRollback(rollbackId, parentSessionId);
                    } else {
                        data = mRollbackStore.createAvailableRollback(rollbackId);
                        data = mRollbackStore.createNonStagedRollback(rollbackId);
                    }
                    mPendingRollbacks.put(parentSessionId, data);
                }
                data.packages.add(info);
                data.info.getPackages().add(info);
            }
        } catch (IOException e) {
            Log.e(TAG, "Unable to create rollback for " + packageName, e);
@@ -1004,7 +1004,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        }

        if (snapshotUserData && !isApex) {
            mAppDataRollbackHelper.snapshotAppData(data.rollbackId, info);
            mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info);
        }

        try {
@@ -1044,7 +1044,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            return;
        }

        if (!rollbackData.inProgress) {
        if (!rollbackData.restoreUserDataInProgress) {
            Log.e(TAG, "Request to restore userData for: " + packageName
                    + ", but no rollback in progress.");
            return;
@@ -1053,12 +1053,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        for (int userId : userIds) {
            final PackageRollbackInfo info = getPackageRollbackInfo(rollbackData, packageName);
            final boolean changedRollbackData = mAppDataRollbackHelper.restoreAppData(
                    rollbackData.rollbackId, info, userId, appId, seInfo);
                    rollbackData.info.getRollbackId(), info, userId, appId, seInfo);

            // We've updated metadata about this rollback, so save it to flash.
            if (changedRollbackData) {
                try {
                    mRollbackStore.saveAvailableRollback(rollbackData);
                    mRollbackStore.saveRollbackData(rollbackData);
                } catch (IOException ioe) {
                    // TODO(narayan): What is the right thing to do here ? This isn't a fatal
                    // error, since it will only result in us trying to restore data again,
@@ -1137,9 +1137,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

            if (rd != null) {
                try {
                    mRollbackStore.saveAvailableRollback(rd);
                    mRollbackStore.saveRollbackData(rd);
                } catch (IOException ioe) {
                    Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
                    Log.e(TAG, "Unable to save rollback info for : "
                            + rd.info.getRollbackId(), ioe);
                }
            }
        });
@@ -1212,7 +1213,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                try {
                    data.timestamp = Instant.now();

                    mRollbackStore.saveAvailableRollback(data);
                    mRollbackStore.saveRollbackData(data);
                    synchronized (mLock) {
                        // Note: There is a small window of time between when
                        // the session has been committed by the package
@@ -1233,8 +1234,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    // After enabling and commiting any rollback, observe packages and
                    // prepare to rollback if packages crashes too frequently.
                    List<String> packages = new ArrayList<>();
                    for (int i = 0; i < data.packages.size(); i++) {
                        packages.add(data.packages.get(i).getPackageName());
                    for (int i = 0; i < data.info.getPackages().size(); i++) {
                        packages.add(data.info.getPackages().get(i).getPackageName());
                    }
                    mPackageHealthObserver.startObservingHealth(packages,
                            mRollbackLifetimeDurationInMillis);
@@ -1307,7 +1308,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            ensureRollbackDataLoadedLocked();
            for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                RollbackData data = mAvailableRollbacks.get(i);
                if (data.isAvailable && data.rollbackId == rollbackId) {
                if (data.isAvailable && data.info.getRollbackId() == rollbackId) {
                    return data;
                }
            }
@@ -1322,7 +1323,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     */
    private static PackageRollbackInfo getPackageRollbackInfo(RollbackData data,
            String packageName) {
        for (PackageRollbackInfo info : data.packages) {
        for (PackageRollbackInfo info : data.info.getPackages()) {
            if (info.getPackageName().equals(packageName)) {
                return info;
            }
@@ -1347,14 +1348,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    }

    private void deleteRollback(RollbackData rollbackData) {
        for (PackageRollbackInfo info : rollbackData.packages) {
        for (PackageRollbackInfo info : rollbackData.info.getPackages()) {
            IntArray installedUsers = info.getInstalledUsers();
            for (int i = 0; i < installedUsers.size(); i++) {
                int userId = installedUsers.get(i);
                mAppDataRollbackHelper.destroyAppDataSnapshot(rollbackData.rollbackId, info,
                        userId);
                mAppDataRollbackHelper.destroyAppDataSnapshot(rollbackData.info.getRollbackId(),
                        info, userId);
            }
        }
        mRollbackStore.deleteAvailableRollback(rollbackData);
        mRollbackStore.deleteRollbackData(rollbackData);
    }
}
+56 −48

File changed.

Preview size limit exceeded, changes collapsed.

Loading