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

Commit 91fc4db1 authored by Richard Uhler's avatar Richard Uhler Committed by Bill Lin
Browse files

Rename RollbackData to Rollback.

Because "Data" doesn't add anything useful to the name.

Also prefer the variable name "rollback" over "data" and "rd" for
instances of Rollback.

Test: builds.
Change-Id: Ibaa3326660345a763c67c573368ba1da11c0a830
Merged-In: I5ae3866753d6badcdf019525b40522937568dee5
parent 87a504d1
Loading
Loading
Loading
Loading
+38 −37
Original line number Diff line number Diff line
@@ -98,14 +98,14 @@ public class AppDataRollbackHelper {

        final IntArray pendingBackups = packageRollbackInfo.getPendingBackups();
        final List<RestoreInfo> pendingRestores = packageRollbackInfo.getPendingRestores();
        boolean changedRollbackData = false;
        boolean changedRollback = false;

        // If we still have a userdata backup pending for this user, it implies that the user
        // hasn't unlocked their device between the point of backup and the point of restore,
        // so the data cannot have changed. We simply skip restoring CE data in this case.
        if (pendingBackups != null && pendingBackups.indexOf(userId) != -1) {
            pendingBackups.remove(pendingBackups.indexOf(userId));
            changedRollbackData = true;
            changedRollback = true;
        } else {
            // There's no pending CE backup for this user, which means that we successfully
            // managed to backup data for the user, which means we seek to restore it
@@ -113,7 +113,7 @@ public class AppDataRollbackHelper {
                // We've encountered a user that hasn't unlocked on a FBE device, so we can't
                // copy across app user data until the user unlocks their device.
                pendingRestores.add(new RestoreInfo(userId, appId, seInfo));
                changedRollbackData = true;
                changedRollback = true;
            } else {
                // This user has unlocked, we can proceed to restore both CE and DE data.
                storageFlags = storageFlags | Installer.FLAG_STORAGE_CE;
@@ -128,7 +128,7 @@ public class AppDataRollbackHelper {
                        + packageRollbackInfo.getPackageName(), ie);
        }

        return changedRollbackData;
        return changedRollback;
    }

    /**
@@ -160,29 +160,29 @@ public class AppDataRollbackHelper {
     * Packages pending backup for the given user are added to {@code pendingBackupPackages} along
     * with their corresponding {@code PackageRollbackInfo}.
     *
     * @return the list of {@code RollbackData} that has pending backups. Note that some of the
     * @return the list of rollbacks that have pending backups. Note that some of the
     *         backups won't be performed, because they might be counteracted by pending restores.
     */
    private static List<RollbackData> computePendingBackups(int userId,
    private static List<Rollback> computePendingBackups(int userId,
            Map<String, PackageRollbackInfo> pendingBackupPackages,
            List<RollbackData> rollbacks) {
        List<RollbackData> rd = new ArrayList<>();
            List<Rollback> rollbacks) {
        List<Rollback> rollbacksWithPendingBackups = new ArrayList<>();

        for (RollbackData data : rollbacks) {
            for (PackageRollbackInfo info : data.info.getPackages()) {
        for (Rollback rollback : rollbacks) {
            for (PackageRollbackInfo info : rollback.info.getPackages()) {
                final IntArray pendingBackupUsers = info.getPendingBackups();
                if (pendingBackupUsers != null) {
                    final int idx = pendingBackupUsers.indexOf(userId);
                    if (idx != -1) {
                        pendingBackupPackages.put(info.getPackageName(), info);
                        if (rd.indexOf(data) == -1) {
                            rd.add(data);
                        if (rollbacksWithPendingBackups.indexOf(rollback) == -1) {
                            rollbacksWithPendingBackups.add(rollback);
                        }
                    }
                }
            }
        }
        return rd;
        return rollbacksWithPendingBackups;
    }

    /**
@@ -190,45 +190,45 @@ public class AppDataRollbackHelper {
     * Packages pending restore are added to {@code pendingRestores} along with their corresponding
     * {@code PackageRollbackInfo}.
     *
     * @return the list of {@code RollbackData} that has pending restores. Note that some of the
     * @return the list of rollbacks that have pending restores. Note that some of the
     *         restores won't be performed, because they might be counteracted by pending backups.
     */
    private static List<RollbackData> computePendingRestores(int userId,
    private static List<Rollback> computePendingRestores(int userId,
            Map<String, PackageRollbackInfo> pendingRestorePackages,
            List<RollbackData> rollbacks) {
        List<RollbackData> rd = new ArrayList<>();
            List<Rollback> rollbacks) {
        List<Rollback> rollbacksWithPendingRestores = new ArrayList<>();

        for (RollbackData data : rollbacks) {
            for (PackageRollbackInfo info : data.info.getPackages()) {
        for (Rollback rollback : rollbacks) {
            for (PackageRollbackInfo info : rollback.info.getPackages()) {
                final RestoreInfo ri = info.getRestoreInfo(userId);
                if (ri != null) {
                    pendingRestorePackages.put(info.getPackageName(), info);
                    if (rd.indexOf(data) == -1) {
                        rd.add(data);
                    if (rollbacksWithPendingRestores.indexOf(rollback) == -1) {
                        rollbacksWithPendingRestores.add(rollback);
                    }
                }
            }
        }

        return rd;
        return rollbacksWithPendingRestores;
    }

    /**
     * Commits the list of pending backups and restores for a given {@code userId}. For the pending
     * backups updates corresponding {@code changedRollbackData} with a mapping from {@code userId}
     * to a inode of theirs CE user data snapshot.
     * Commits the list of pending backups and restores for a given {@code userId}. For rollbacks
     * with pending backups, updates the {@code Rollback} instance with a mapping from
     * {@code userId} to inode of the CE user data snapshot.
     *
     * @return the set of {@code RollbackData} that have been changed and should be stored on disk.
     * @return the set of rollbacks with changes that should be stored on disk.
     */
    public Set<RollbackData> commitPendingBackupAndRestoreForUser(int userId,
            List<RollbackData> rollbacks) {
    public Set<Rollback> commitPendingBackupAndRestoreForUser(int userId,
            List<Rollback> rollbacks) {

        final Map<String, PackageRollbackInfo> pendingBackupPackages = new HashMap<>();
        final List<RollbackData> pendingBackups = computePendingBackups(userId,
        final List<Rollback> pendingBackups = computePendingBackups(userId,
                pendingBackupPackages, rollbacks);

        final Map<String, PackageRollbackInfo> pendingRestorePackages = new HashMap<>();
        final List<RollbackData> pendingRestores = computePendingRestores(userId,
        final List<Rollback> pendingRestores = computePendingRestores(userId,
                pendingRestorePackages, rollbacks);

        // First remove unnecessary backups, i.e. when user did not unlock their phone between the
@@ -248,14 +248,15 @@ public class AppDataRollbackHelper {
        }

        if (!pendingBackupPackages.isEmpty()) {
            for (RollbackData data : pendingBackups) {
                for (PackageRollbackInfo info : data.info.getPackages()) {
            for (Rollback rollback : pendingBackups) {
                for (PackageRollbackInfo info : rollback.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.info.getRollbackId(), Installer.FLAG_STORAGE_CE);
                                    userId, rollback.info.getRollbackId(),
                                    Installer.FLAG_STORAGE_CE);
                            info.putCeSnapshotInode(userId, ceSnapshotInode);
                            pendingBackupUsers.remove(idx);
                        } catch (InstallerException ie) {
@@ -269,13 +270,13 @@ public class AppDataRollbackHelper {
        }

        if (!pendingRestorePackages.isEmpty()) {
            for (RollbackData data : pendingRestores) {
                for (PackageRollbackInfo info : data.info.getPackages()) {
            for (Rollback rollback : pendingRestores) {
                for (PackageRollbackInfo info : rollback.info.getPackages()) {
                    final RestoreInfo ri = info.getRestoreInfo(userId);
                    if (ri != null) {
                        try {
                            mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
                                    ri.seInfo, userId, data.info.getRollbackId(),
                                    ri.seInfo, userId, rollback.info.getRollbackId(),
                                    Installer.FLAG_STORAGE_CE);
                            info.removeRestoreInfo(ri);
                        } catch (InstallerException ie) {
@@ -287,7 +288,7 @@ public class AppDataRollbackHelper {
            }
        }

        final Set<RollbackData> changed = new HashSet<>(pendingBackups);
        final Set<Rollback> changed = new HashSet<>(pendingBackups);
        changed.addAll(pendingRestores);
        return changed;
    }
+11 −11
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ import java.util.ArrayList;
 * Information about a rollback available for a set of atomically installed
 * packages.
 */
class RollbackData {
class Rollback {
    @IntDef(flag = true, prefix = { "ROLLBACK_STATE_" }, value = {
            ROLLBACK_STATE_ENABLING,
            ROLLBACK_STATE_AVAILABLE,
@@ -102,13 +102,13 @@ class RollbackData {
    public boolean restoreUserDataInProgress = false;

    /**
     * Constructs a new, empty RollbackData instance.
     * Constructs a new, empty Rollback 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) {
    Rollback(int rollbackId, File backupDir, int stagedSessionId) {
        this.info = new RollbackInfo(rollbackId,
                /* packages */ new ArrayList<>(),
                /* isStaged */ stagedSessionId != -1,
@@ -121,9 +121,9 @@ class RollbackData {
    }

    /**
     * Constructs a RollbackData instance with full rollback data information.
     * Constructs a pre-populated Rollback instance.
     */
    RollbackData(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
    Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
            @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) {
        this.info = info;
        this.backupDir = backupDir;
@@ -143,9 +143,9 @@ class RollbackData {

    static String rollbackStateToString(@RollbackState int state) {
        switch (state) {
            case RollbackData.ROLLBACK_STATE_ENABLING: return "enabling";
            case RollbackData.ROLLBACK_STATE_AVAILABLE: return "available";
            case RollbackData.ROLLBACK_STATE_COMMITTED: return "committed";
            case Rollback.ROLLBACK_STATE_ENABLING: return "enabling";
            case Rollback.ROLLBACK_STATE_AVAILABLE: return "available";
            case Rollback.ROLLBACK_STATE_COMMITTED: return "committed";
        }
        throw new AssertionError("Invalid rollback state: " + state);
    }
@@ -153,9 +153,9 @@ class RollbackData {
    static @RollbackState int rollbackStateFromString(String state)
            throws ParseException {
        switch (state) {
            case "enabling": return RollbackData.ROLLBACK_STATE_ENABLING;
            case "available": return RollbackData.ROLLBACK_STATE_AVAILABLE;
            case "committed": return RollbackData.ROLLBACK_STATE_COMMITTED;
            case "enabling": return Rollback.ROLLBACK_STATE_ENABLING;
            case "available": return Rollback.ROLLBACK_STATE_AVAILABLE;
            case "committed": return Rollback.ROLLBACK_STATE_COMMITTED;
        }
        throw new ParseException("Invalid rollback state: " + state, 0);
    }
+162 −162

File changed.

Preview size limit exceeded, changes collapsed.

+35 −35
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.server.rollback;

import static com.android.server.rollback.RollbackData.rollbackStateFromString;
import static com.android.server.rollback.RollbackData.rollbackStateToString;
import static com.android.server.rollback.Rollback.rollbackStateFromString;
import static com.android.server.rollback.Rollback.rollbackStateToString;

import android.annotation.NonNull;
import android.content.pm.VersionedPackage;
@@ -73,17 +73,17 @@ class RollbackStore {
    }

    /**
     * Reads the rollback data from persistent storage.
     * Reads the rollbacks from persistent storage.
     */
    List<RollbackData> loadAllRollbackData() {
        List<RollbackData> rollbacks = new ArrayList<>();
    List<Rollback> loadRollbacks() {
        List<Rollback> rollbacks = new ArrayList<>();
        mRollbackDataDir.mkdirs();
        for (File rollbackDir : mRollbackDataDir.listFiles()) {
            if (rollbackDir.isDirectory()) {
                try {
                    rollbacks.add(loadRollbackData(rollbackDir));
                    rollbacks.add(loadRollback(rollbackDir));
                } catch (IOException e) {
                    Slog.e(TAG, "Unable to read rollback data at " + rollbackDir, e);
                    Slog.e(TAG, "Unable to read rollback at " + rollbackDir, e);
                    removeFile(rollbackDir);
                }
            }
@@ -191,21 +191,21 @@ class RollbackStore {
    }

    /**
     * Creates a new RollbackData instance for a non-staged rollback with
     * Creates a new Rollback instance for a non-staged rollback with
     * backupDir assigned.
     */
    RollbackData createNonStagedRollback(int rollbackId) {
    Rollback createNonStagedRollback(int rollbackId) {
        File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
        return new RollbackData(rollbackId, backupDir, -1);
        return new Rollback(rollbackId, backupDir, -1);
    }

    /**
     * Creates a new RollbackData instance for a staged rollback with
     * Creates a new Rollback instance for a staged rollback with
     * backupDir assigned.
     */
    RollbackData createStagedRollback(int rollbackId, int stagedSessionId) {
    Rollback createStagedRollback(int rollbackId, int stagedSessionId) {
        File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
        return new RollbackData(rollbackId, backupDir, stagedSessionId);
        return new Rollback(rollbackId, backupDir, stagedSessionId);
    }

    /**
@@ -213,10 +213,10 @@ class RollbackStore {
     * For packages containing splits, this method should be called for each
     * of the package's split apks in addition to the base apk.
     */
    static void backupPackageCodePath(RollbackData data, String packageName, String codePath)
    static void backupPackageCodePath(Rollback rollback, String packageName, String codePath)
            throws IOException {
        File sourceFile = new File(codePath);
        File targetDir = new File(data.backupDir, packageName);
        File targetDir = new File(rollback.backupDir, packageName);
        targetDir.mkdirs();
        File targetFile = new File(targetDir, sourceFile.getName());

@@ -228,8 +228,8 @@ class RollbackStore {
     * Returns the apk or apex files backed up for the given package.
     * Includes the base apk and any splits. Returns null if none found.
     */
    static File[] getPackageCodePaths(RollbackData data, String packageName) {
        File targetDir = new File(data.backupDir, packageName);
    static File[] getPackageCodePaths(Rollback rollback, String packageName) {
        File targetDir = new File(rollback.backupDir, packageName);
        File[] files = targetDir.listFiles();
        if (files == null || files.length == 0) {
            return null;
@@ -241,27 +241,27 @@ class RollbackStore {
     * Deletes all backed up apks and apex files associated with the given
     * rollback.
     */
    static void deletePackageCodePaths(RollbackData data) {
        for (PackageRollbackInfo info : data.info.getPackages()) {
            File targetDir = new File(data.backupDir, info.getPackageName());
    static void deletePackageCodePaths(Rollback rollback) {
        for (PackageRollbackInfo info : rollback.info.getPackages()) {
            File targetDir = new File(rollback.backupDir, info.getPackageName());
            removeFile(targetDir);
        }
    }

    /**
     * Saves the rollback data to persistent storage.
     * Saves the given rollback to persistent storage.
     */
    void saveRollbackData(RollbackData data) throws IOException {
    void saveRollback(Rollback rollback) throws IOException {
        try {
            JSONObject dataJson = new JSONObject();
            dataJson.put("info", rollbackInfoToJson(data.info));
            dataJson.put("timestamp", data.timestamp.toString());
            dataJson.put("stagedSessionId", data.stagedSessionId);
            dataJson.put("state", rollbackStateToString(data.state));
            dataJson.put("apkSessionId", data.apkSessionId);
            dataJson.put("restoreUserDataInProgress", data.restoreUserDataInProgress);

            PrintWriter pw = new PrintWriter(new File(data.backupDir, "rollback.json"));
            dataJson.put("info", rollbackInfoToJson(rollback.info));
            dataJson.put("timestamp", rollback.timestamp.toString());
            dataJson.put("stagedSessionId", rollback.stagedSessionId);
            dataJson.put("state", rollbackStateToString(rollback.state));
            dataJson.put("apkSessionId", rollback.apkSessionId);
            dataJson.put("restoreUserDataInProgress", rollback.restoreUserDataInProgress);

            PrintWriter pw = new PrintWriter(new File(rollback.backupDir, "rollback.json"));
            pw.println(dataJson.toString());
            pw.close();
        } catch (JSONException e) {
@@ -270,23 +270,23 @@ class RollbackStore {
    }

    /**
     * Removes all persistant storage associated with the given rollback data.
     * Removes all persistent storage associated with the given rollback.
     */
    void deleteRollbackData(RollbackData data) {
        removeFile(data.backupDir);
    void deleteRollback(Rollback rollback) {
        removeFile(rollback.backupDir);
    }

    /**
     * Reads the metadata for a rollback from the given directory.
     * @throws IOException in case of error reading the data.
     */
    private static RollbackData loadRollbackData(File backupDir) throws IOException {
    private static Rollback loadRollback(File backupDir) throws IOException {
        try {
            File rollbackJsonFile = new File(backupDir, "rollback.json");
            JSONObject dataJson = new JSONObject(
                    IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));

            return new RollbackData(
            return new Rollback(
                    rollbackInfoFromJson(dataJson.getJSONObject("info")),
                    backupDir,
                    Instant.parse(dataJson.getString("timestamp")),
+6 −6
Original line number Diff line number Diff line
@@ -235,22 +235,22 @@ public class AppDataRollbackHelperTest {
        wasRecentlyRestored.getPendingRestores().add(
                new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo"));

        RollbackData dataWithPendingBackup = new RollbackData(101, new File("/does/not/exist"), -1);
        Rollback dataWithPendingBackup = new Rollback(101, new File("/does/not/exist"), -1);
        dataWithPendingBackup.info.getPackages().add(pendingBackup);

        RollbackData dataWithRecentRestore = new RollbackData(17239, new File("/does/not/exist"),
        Rollback dataWithRecentRestore = new Rollback(17239, new File("/does/not/exist"),
                -1);
        dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored);

        RollbackData dataForDifferentUser = new RollbackData(17239, new File("/does/not/exist"),
        Rollback dataForDifferentUser = new Rollback(17239, new File("/does/not/exist"),
                -1);
        dataForDifferentUser.info.getPackages().add(ignoredInfo);

        RollbackData dataForRestore = new RollbackData(17239, new File("/does/not/exist"), -1);
        Rollback dataForRestore = new Rollback(17239, new File("/does/not/exist"), -1);
        dataForRestore.info.getPackages().add(pendingRestore);
        dataForRestore.info.getPackages().add(wasRecentlyRestored);

        Set<RollbackData> changed = helper.commitPendingBackupAndRestoreForUser(37,
        Set<Rollback> changed = helper.commitPendingBackupAndRestoreForUser(37,
                Arrays.asList(dataWithPendingBackup, dataWithRecentRestore, dataForDifferentUser,
                    dataForRestore));
        InOrder inOrder = Mockito.inOrder(installer);
@@ -265,7 +265,7 @@ public class AppDataRollbackHelperTest {
        assertEquals(-1, pendingBackup.getPendingBackups().indexOf(37));
        assertEquals(53, pendingBackup.getCeSnapshotInodes().get(37));

        // Check that changed returns correct RollbackData.
        // Check that changed returns correct Rollback.
        assertEquals(3, changed.size());
        assertTrue(changed.contains(dataWithPendingBackup));
        assertTrue(changed.contains(dataWithRecentRestore));