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

Commit 16d49b40 authored by JW Wang's avatar JW Wang
Browse files

Clean up the code that deletes snapshots by inode (1/n)

Per b/147806409, the old code to delete snapshots by inode didn't work.
There is no point in storing mCeSnapshotInodes inside
PackageRollbackInfo. Let's remove related code.

TODO: fix ApexManager/Installer APIs that have unused parameter/return
values.

Bug: 154897348
Test: atest RollbackStoreTest RollbackUnitTest AppDataRollbackHelperTest

Change-Id: I66357c22607bfffbe4d9f55fc13c4c657d5f700c
parent 95f8df1a
Loading
Loading
Loading
Loading
+2 −24
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseLongArray;

import java.util.ArrayList;
import java.util.List;
@@ -87,12 +86,6 @@ public final class PackageRollbackInfo implements Parcelable {
    // NOTE: Not a part of the Parcelable representation of this object.
    private final List<Integer> mSnapshottedUsers;

    /**
     * A mapping between user and an inode of theirs CE data snapshot.
     */
    // NOTE: Not a part of the Parcelable representation of this object.
    private final SparseLongArray mCeSnapshotInodes;

    /**
     * The userdata policy to execute when a rollback for this package is committed.
     */
@@ -172,16 +165,6 @@ public final class PackageRollbackInfo implements Parcelable {
        return mSnapshottedUsers;
    }

    /** @hide */
    public SparseLongArray getCeSnapshotInodes() {
        return mCeSnapshotInodes;
    }

    /** @hide */
    public void putCeSnapshotInode(int userId, long ceSnapshotInode) {
        mCeSnapshotInodes.put(userId, ceSnapshotInode);
    }

    /** @hide */
    public void removePendingBackup(int userId) {
        mPendingBackups.remove((Integer) userId);
@@ -196,11 +179,9 @@ public final class PackageRollbackInfo implements Parcelable {
    public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
            VersionedPackage packageRolledBackTo,
            @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
            boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers,
            @NonNull SparseLongArray ceSnapshotInodes) {
            boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers) {
        this(packageRolledBackFrom, packageRolledBackTo, pendingBackups, pendingRestores, isApex,
                isApkInApex, snapshottedUsers, ceSnapshotInodes,
                PackageManager.RollbackDataPolicy.RESTORE);
                isApkInApex, snapshottedUsers, PackageManager.RollbackDataPolicy.RESTORE);
    }

    /** @hide */
@@ -208,7 +189,6 @@ public final class PackageRollbackInfo implements Parcelable {
            VersionedPackage packageRolledBackTo,
            @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
            boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers,
            @NonNull SparseLongArray ceSnapshotInodes,
            @PackageManager.RollbackDataPolicy int rollbackDataPolicy) {
        this.mVersionRolledBackFrom = packageRolledBackFrom;
        this.mVersionRolledBackTo = packageRolledBackTo;
@@ -218,7 +198,6 @@ public final class PackageRollbackInfo implements Parcelable {
        this.mRollbackDataPolicy = rollbackDataPolicy;
        this.mIsApkInApex = isApkInApex;
        this.mSnapshottedUsers = snapshottedUsers;
        this.mCeSnapshotInodes = ceSnapshotInodes;
    }

    private PackageRollbackInfo(Parcel in) {
@@ -229,7 +208,6 @@ public final class PackageRollbackInfo implements Parcelable {
        this.mPendingRestores = null;
        this.mPendingBackups = null;
        this.mSnapshottedUsers = null;
        this.mCeSnapshotInodes = null;
        this.mRollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
    }

+4 −18
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.os.storage.StorageManager;
import android.util.Slog;
import android.util.SparseLongArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -130,20 +129,15 @@ public class AppDataRollbackHelper {
            if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
                long ceSnapshotInode = mApexManager.snapshotCeData(
                        userId, rollbackId, packageRollbackInfo.getPackageName());
                if (ceSnapshotInode > 0) {
                    packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
                } else {
                if (ceSnapshotInode <= 0) {
                    return false;
                }
            }
        } else {
            // APK
            try {
                long ceSnapshotInode = mInstaller.snapshotAppData(
                mInstaller.snapshotAppData(
                        packageRollbackInfo.getPackageName(), userId, rollbackId, flags);
                if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
                    packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
                }
            } catch (InstallerException ie) {
                Slog.e(TAG, "Unable to create app data snapshot for: "
                        + packageRollbackInfo.getPackageName() + ", userId: " + userId, ie);
@@ -204,18 +198,10 @@ public class AppDataRollbackHelper {
    // TODO(b/136241838): Move into Rollback and synchronize there.
    public void destroyAppDataSnapshot(int rollbackId, PackageRollbackInfo packageRollbackInfo,
            int user) {
        int storageFlags = Installer.FLAG_STORAGE_DE;
        final SparseLongArray ceSnapshotInodes = packageRollbackInfo.getCeSnapshotInodes();
        long ceSnapshotInode = ceSnapshotInodes.get(user);
        if (ceSnapshotInode > 0) {
            storageFlags |= Installer.FLAG_STORAGE_CE;
        }
        try {
            // Delete both DE and CE snapshots if any
            mInstaller.destroyAppDataSnapshot(packageRollbackInfo.getPackageName(), user,
                    ceSnapshotInode, rollbackId, storageFlags);
            if ((storageFlags & Installer.FLAG_STORAGE_CE) != 0) {
                ceSnapshotInodes.delete(user);
            }
                    0, rollbackId, Installer.FLAG_STORAGE_DE | Installer.FLAG_STORAGE_CE);
        } catch (InstallerException ie) {
            Slog.e(TAG, "Unable to delete app data snapshot for "
                        + packageRollbackInfo.getPackageName(), ie);
+2 −5
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import android.os.ext.SdkExtensions;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.SparseLongArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -374,8 +373,7 @@ class Rollback {
                new VersionedPackage(packageName, newVersion),
                new VersionedPackage(packageName, installedVersion),
                new ArrayList<>() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
                isApex, false /* isApkInApex */, new ArrayList<>(),
                new SparseLongArray() /* ceSnapshotInodes */, rollbackDataPolicy);
                isApex, false /* isApkInApex */, new ArrayList<>(), rollbackDataPolicy);

        synchronized (mLock) {
            info.getPackages().add(packageRollbackInfo);
@@ -400,8 +398,7 @@ class Rollback {
                new VersionedPackage(packageName, 0 /* newVersion */),
                new VersionedPackage(packageName, installedVersion),
                new ArrayList<>() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
                false /* isApex */, true /* isApkInApex */, new ArrayList<>(),
                new SparseLongArray() /* ceSnapshotInodes */, rollbackDataPolicy);
                false /* isApex */, true /* isApkInApex */, new ArrayList<>(), rollbackDataPolicy);
        synchronized (mLock) {
            info.getPackages().add(packageRollbackInfo);
        }
+1 −27
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.content.rollback.RollbackInfo;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.SparseLongArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -150,28 +149,6 @@ class RollbackStore {
        return restoreInfos;
    }

    private static @NonNull JSONArray ceSnapshotInodesToJson(
            @NonNull SparseLongArray ceSnapshotInodes) throws JSONException {
        JSONArray array = new JSONArray();
        for (int i = 0; i < ceSnapshotInodes.size(); i++) {
            JSONObject entryJson = new JSONObject();
            entryJson.put("userId", ceSnapshotInodes.keyAt(i));
            entryJson.put("ceSnapshotInode", ceSnapshotInodes.valueAt(i));
            array.put(entryJson);
        }
        return array;
    }

    private static @NonNull SparseLongArray ceSnapshotInodesFromJson(JSONArray json)
            throws JSONException {
        SparseLongArray ceSnapshotInodes = new SparseLongArray(json.length());
        for (int i = 0; i < json.length(); i++) {
            JSONObject entry = json.getJSONObject(i);
            ceSnapshotInodes.append(entry.getInt("userId"), entry.getLong("ceSnapshotInode"));
        }
        return ceSnapshotInodes;
    }

    private static @NonNull JSONArray extensionVersionsToJson(
            SparseIntArray extensionVersions) throws JSONException {
        JSONArray array = new JSONArray();
@@ -374,7 +351,6 @@ class RollbackStore {

        // Field is named 'installedUsers' for legacy reasons.
        json.put("installedUsers", fromIntList(snapshottedUsers));
        json.put("ceSnapshotInodes", ceSnapshotInodesToJson(info.getCeSnapshotInodes()));

        json.put("rollbackDataPolicy", info.getRollbackDataPolicy());

@@ -398,8 +374,6 @@ class RollbackStore {

        // Field is named 'installedUsers' for legacy reasons.
        final List<Integer> snapshottedUsers = toIntList(json.getJSONArray("installedUsers"));
        final SparseLongArray ceSnapshotInodes = ceSnapshotInodesFromJson(
                json.getJSONArray("ceSnapshotInodes"));

        // Backward compatibility: no such field for old versions.
        final int rollbackDataPolicy = json.optInt("rollbackDataPolicy",
@@ -407,7 +381,7 @@ class RollbackStore {

        return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo,
                pendingBackups, pendingRestores, isApex, isApkInApex, snapshottedUsers,
                ceSnapshotInodes, rollbackDataPolicy);
                rollbackDataPolicy);
    }

    private static JSONArray versionedPackagesToJson(List<VersionedPackage> packages)
+3 −15
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import static org.mockito.MockitoAnnotations.initMocks;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.util.SparseLongArray;

import com.android.server.pm.ApexManager;
import com.android.server.pm.Installer;
@@ -74,8 +73,6 @@ public class AppDataRollbackHelperTest {
        assertEquals(10, (int) info.getPendingBackups().get(0));
        assertEquals(11, (int) info.getPendingBackups().get(1));

        assertEquals(0, info.getCeSnapshotInodes().size());

        InOrder inOrder = Mockito.inOrder(installer);
        inOrder.verify(installer).snapshotAppData(
                eq("com.foo.bar"), eq(10), eq(5), eq(Installer.FLAG_STORAGE_DE));
@@ -93,9 +90,6 @@ public class AppDataRollbackHelperTest {
        assertEquals(1, info2.getPendingBackups().size());
        assertEquals(11, (int) info2.getPendingBackups().get(0));

        assertEquals(1, info2.getCeSnapshotInodes().size());
        assertEquals(239L, info2.getCeSnapshotInodes().get(10));

        inOrder = Mockito.inOrder(installer);
        inOrder.verify(installer).snapshotAppData(
                eq("com.foo.bar"), eq(10), eq(7),
@@ -117,8 +111,7 @@ public class AppDataRollbackHelperTest {
            final int[] installedUsers) {
        return new PackageRollbackInfo(
                new VersionedPackage(packageName, 2), new VersionedPackage(packageName, 1),
                new ArrayList<>(), new ArrayList<>(), false, false, toList(installedUsers),
                new SparseLongArray());
                new ArrayList<>(), new ArrayList<>(), false, false, toList(installedUsers));
    }

    private static PackageRollbackInfo createPackageRollbackInfo(String packageName) {
@@ -206,20 +199,17 @@ public class AppDataRollbackHelperTest {
        AppDataRollbackHelper helper = new AppDataRollbackHelper(installer, mApexManager);

        PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar");
        info.putCeSnapshotInode(11, 239L);
        helper.destroyAppDataSnapshot(5 /* rollbackId */, info, 10 /* userId */);
        helper.destroyAppDataSnapshot(5 /* rollbackId */, info, 11 /* userId */);

        InOrder inOrder = Mockito.inOrder(installer);
        inOrder.verify(installer).destroyAppDataSnapshot(
                eq("com.foo.bar"), eq(10) /* userId */, eq(0L) /* ceSnapshotInode */,
                eq(5) /* rollbackId */, eq(Installer.FLAG_STORAGE_DE));
                eq(5) /* rollbackId */, eq(Installer.FLAG_STORAGE_DE | Installer.FLAG_STORAGE_CE));
        inOrder.verify(installer).destroyAppDataSnapshot(
                eq("com.foo.bar"), eq(11) /* userId */, eq(239L) /* ceSnapshotInode */,
                eq("com.foo.bar"), eq(11) /* userId */, eq(0L) /* ceSnapshotInode */,
                eq(5) /* rollbackId */, eq(Installer.FLAG_STORAGE_DE | Installer.FLAG_STORAGE_CE));
        inOrder.verifyNoMoreInteractions();

        assertEquals(0, info.getCeSnapshotInodes().size());
    }

    @Test
@@ -243,7 +233,6 @@ public class AppDataRollbackHelperTest {
        // This one should be restored
        PackageRollbackInfo pendingRestore = createPackageRollbackInfo("com.abc",
                new int[]{37, 73});
        pendingRestore.putCeSnapshotInode(37, 1543L);
        pendingRestore.getPendingRestores().add(
                new RestoreInfo(37 /* userId */, 57 /* appId*/, "seInfo"));

@@ -281,7 +270,6 @@ public class AppDataRollbackHelperTest {
        inOrder.verify(installer).snapshotAppData(eq("com.foo"), eq(37), eq(101),
                eq(Installer.FLAG_STORAGE_CE));
        assertEquals(-1, pendingBackup.getPendingBackups().indexOf(37));
        assertEquals(53, pendingBackup.getCeSnapshotInodes().get(37));

        // Check that restore was performed.
        assertTrue(helper.commitPendingBackupAndRestoreForUser(37, dataForRestore));
Loading