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

Commit a7e9b2db authored by Richard Uhler's avatar Richard Uhler Committed by Narayan Kamath
Browse files

Use VersionedPackage in PackageRollbackInfo.

Rather than defining a new custom PackageRollbackInfo.PackageVersion
type.

Also clean up PackageRollbackInfo API by replacing public fields with
methods and picking better names.

Bug: 112431924
Test: atest RollbackTest
Change-Id: I68a91e07b8745df9c5ecb22fdccbfcd76385814a
parent b9d54474
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -1672,18 +1672,12 @@ package android.content.pm.permission {
package android.content.rollback {
  public final class PackageRollbackInfo implements android.os.Parcelable {
    ctor public PackageRollbackInfo(String, android.content.rollback.PackageRollbackInfo.PackageVersion, android.content.rollback.PackageRollbackInfo.PackageVersion);
    method public int describeContents();
    method public String getPackageName();
    method public android.content.pm.VersionedPackage getVersionRolledBackFrom();
    method public android.content.pm.VersionedPackage getVersionRolledBackTo();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.rollback.PackageRollbackInfo> CREATOR;
    field public final android.content.rollback.PackageRollbackInfo.PackageVersion higherVersion;
    field public final android.content.rollback.PackageRollbackInfo.PackageVersion lowerVersion;
    field public final String packageName;
  }
  public static class PackageRollbackInfo.PackageVersion {
    ctor public PackageRollbackInfo.PackageVersion(long);
    field public final long versionCode;
  }
  public final class RollbackInfo implements android.os.Parcelable {
+24 −44
Original line number Diff line number Diff line
@@ -17,11 +17,10 @@
package android.content.rollback;

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

import java.util.Objects;

/**
 * Information about a rollback available for a particular package.
 *
@@ -29,59 +28,41 @@ import java.util.Objects;
 */
@SystemApi
public final class PackageRollbackInfo implements Parcelable {
    /**
     * The name of a package being rolled back.
     */
    public final String packageName;

    /**
     * The version the package was rolled back from.
     */
    public final PackageVersion higherVersion;
    private final VersionedPackage mVersionRolledBackFrom;
    private final VersionedPackage mVersionRolledBackTo;

    /**
     * The version the package was rolled back to.
     * Returns the name of the package to roll back from.
     */
    public final PackageVersion lowerVersion;
    public String getPackageName() {
        return mVersionRolledBackFrom.getPackageName();
    }

    /**
     * Represents a version of a package.
     * Returns the version of the package rolled back from.
     */
    public static class PackageVersion {
        public final long versionCode;

        // TODO(b/120200473): Include apk sha or some other way to distinguish
        // between two different apks with the same version code.
        public PackageVersion(long versionCode) {
            this.versionCode = versionCode;
    public VersionedPackage getVersionRolledBackFrom() {
        return mVersionRolledBackFrom;
    }

        @Override
        public boolean equals(Object other) {
            if (other instanceof PackageVersion)  {
                PackageVersion otherVersion = (PackageVersion) other;
                return versionCode == otherVersion.versionCode;
            }
            return false;
        }

        @Override
        public int hashCode() {
            return Objects.hash(versionCode);
        }
    /**
     * Returns the version of the package rolled back to.
     */
    public VersionedPackage getVersionRolledBackTo() {
        return mVersionRolledBackTo;
    }

    public PackageRollbackInfo(String packageName,
            PackageVersion higherVersion, PackageVersion lowerVersion) {
        this.packageName = packageName;
        this.higherVersion = higherVersion;
        this.lowerVersion = lowerVersion;
    /** @hide */
    public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
            VersionedPackage packageRolledBackTo) {
        this.mVersionRolledBackFrom = packageRolledBackFrom;
        this.mVersionRolledBackTo = packageRolledBackTo;
    }

    private PackageRollbackInfo(Parcel in) {
        this.packageName = in.readString();
        this.higherVersion = new PackageVersion(in.readLong());
        this.lowerVersion = new PackageVersion(in.readLong());
        this.mVersionRolledBackFrom = VersionedPackage.CREATOR.createFromParcel(in);
        this.mVersionRolledBackTo = VersionedPackage.CREATOR.createFromParcel(in);
    }

    @Override
@@ -91,9 +72,8 @@ public final class PackageRollbackInfo implements Parcelable {

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(packageName);
        out.writeLong(higherVersion.versionCode);
        out.writeLong(lowerVersion.versionCode);
        mVersionRolledBackFrom.writeToParcel(out, flags);
        mVersionRolledBackTo.writeToParcel(out, flags);
    }

    public static final Parcelable.Creator<PackageRollbackInfo> CREATOR =
+26 −22
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.StringParceledListSlice;
import android.content.pm.VersionedPackage;
import android.content.rollback.IRollbackManager;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
@@ -219,7 +220,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        // it's out of date or not, so no need to check package versions here.

        for (PackageRollbackInfo info : data.packages) {
            if (info.packageName.equals(packageName)) {
            if (info.getPackageName().equals(packageName)) {
                // TODO: Once the RollbackInfo API supports info about
                // dependant packages, add that info here.
                return new RollbackInfo(data.rollbackId, info);
@@ -240,7 +241,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                RollbackData data = mAvailableRollbacks.get(i);
                for (PackageRollbackInfo info : data.packages) {
                    packageNames.add(info.packageName);
                    packageNames.add(info.getPackageName());
                }
            }
        }
@@ -282,7 +283,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     */
    private void executeRollbackInternal(RollbackInfo rollback,
            String callerPackageName, IntentSender statusReceiver) {
        String targetPackageName = rollback.targetPackage.packageName;
        String targetPackageName = rollback.targetPackage.getPackageName();
        Log.i(TAG, "Initiating rollback of " + targetPackageName);

        // Get the latest RollbackData for the target package.
@@ -306,15 +307,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        // Figure out how to ensure we don't commit the rollback if
        // roll forward happens at the same time.
        for (PackageRollbackInfo info : data.packages) {
            PackageRollbackInfo.PackageVersion installedVersion =
                    getInstalledPackageVersion(info.packageName);
            VersionedPackage installedVersion = getInstalledPackageVersion(info.getPackageName());
            if (installedVersion == null) {
                // TODO: Test this case
                sendFailure(statusReceiver, "Package to roll back is not installed");
                return;
            }

            if (!info.higherVersion.equals(installedVersion)) {
            if (!packageVersionsEqual(info.getVersionRolledBackFrom(), installedVersion)) {
                // TODO: Test this case
                sendFailure(statusReceiver, "Package version to roll back not installed.");
                return;
@@ -357,7 +357,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

                // TODO: Will it always be called "base.apk"? What about splits?
                // What about apex?
                File packageDir = new File(data.backupDir, info.packageName);
                File packageDir = new File(data.backupDir, info.getPackageName());
                File baseApk = new File(packageDir, "base.apk");
                try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(baseApk,
                        ParcelFileDescriptor.MODE_READ_ONLY)) {
@@ -431,7 +431,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            while (iter.hasNext()) {
                RollbackData data = iter.next();
                for (PackageRollbackInfo info : data.packages) {
                    if (info.packageName.equals(packageName)) {
                    if (info.getPackageName().equals(packageName)) {
                        iter.remove();
                        mRollbackStore.deleteAvailableRollback(data);
                        break;
@@ -493,8 +493,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private void onPackageReplaced(String packageName) {
        // TODO: Could this end up incorrectly deleting a rollback for a
        // package that is about to be installed?
        PackageRollbackInfo.PackageVersion installedVersion =
                getInstalledPackageVersion(packageName);
        VersionedPackage installedVersion = getInstalledPackageVersion(packageName);

        synchronized (mLock) {
            ensureRollbackDataLoadedLocked();
@@ -502,8 +501,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            while (iter.hasNext()) {
                RollbackData data = iter.next();
                for (PackageRollbackInfo info : data.packages) {
                    if (info.packageName.equals(packageName)
                            && !info.higherVersion.equals(installedVersion)) {
                    if (info.getPackageName().equals(packageName)
                            && !packageVersionsEqual(
                                        info.getVersionRolledBackFrom(),
                                        installedVersion)) {
                        iter.remove();
                        mRollbackStore.deleteAvailableRollback(data);
                        break;
@@ -526,7 +527,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            boolean changed = false;
            while (iter.hasNext()) {
                RollbackInfo rollback = iter.next();
                if (packageName.equals(rollback.targetPackage.packageName)) {
                if (packageName.equals(rollback.targetPackage.getPackageName())) {
                    iter.remove();
                    changed = true;
                }
@@ -701,8 +702,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            return false;
        }

        PackageRollbackInfo.PackageVersion newVersion =
                new PackageRollbackInfo.PackageVersion(newPackage.versionCode);
        VersionedPackage newVersion = new VersionedPackage(packageName, newPackage.versionCode);

        // Get information about the currently installed package.
        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
@@ -713,8 +713,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            Log.e(TAG, packageName + " is not installed");
            return false;
        }
        PackageRollbackInfo.PackageVersion installedVersion =
                new PackageRollbackInfo.PackageVersion(installedPackage.getLongVersionCode());
        VersionedPackage installedVersion = new VersionedPackage(packageName,
                installedPackage.getLongVersionCode());

        for (int user : installedUsers) {
            final int storageFlags;
@@ -735,8 +735,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }

        PackageRollbackInfo info = new PackageRollbackInfo(
                packageName, newVersion, installedVersion);
        PackageRollbackInfo info = new PackageRollbackInfo(newVersion, installedVersion);

        RollbackData data;
        try {
@@ -832,7 +831,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     * Gets the version of the package currently installed.
     * Returns null if the package is not currently installed.
     */
    private PackageRollbackInfo.PackageVersion getInstalledPackageVersion(String packageName) {
    private VersionedPackage getInstalledPackageVersion(String packageName) {
        PackageManager pm = mContext.getPackageManager();
        PackageInfo pkgInfo = null;
        try {
@@ -841,7 +840,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            return null;
        }

        return new PackageRollbackInfo.PackageVersion(pkgInfo.getLongVersionCode());
        return new VersionedPackage(packageName, pkgInfo.getLongVersionCode());
    }

    private boolean packageVersionsEqual(VersionedPackage a, VersionedPackage b) {
        return a.getPackageName().equals(b.getPackageName())
            && a.getLongVersionCode() == b.getLongVersionCode();
    }

    private class SessionCallback extends PackageInstaller.SessionCallback {
@@ -917,7 +921,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                RollbackData data = mAvailableRollbacks.get(i);
                for (PackageRollbackInfo info : data.packages) {
                    if (info.packageName.equals(packageName)) {
                    if (info.getPackageName().equals(packageName)) {
                        return data;
                    }
                }
+17 −12
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.rollback;

import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.util.Log;
@@ -116,9 +117,9 @@ class RollbackStore {
                    String packageName = element.getString("packageName");
                    long higherVersionCode = element.getLong("higherVersionCode");
                    long lowerVersionCode = element.getLong("lowerVersionCode");
                    PackageRollbackInfo target = new PackageRollbackInfo(packageName,
                            new PackageRollbackInfo.PackageVersion(higherVersionCode),
                            new PackageRollbackInfo.PackageVersion(lowerVersionCode));
                    PackageRollbackInfo target = new PackageRollbackInfo(
                            new VersionedPackage(packageName, higherVersionCode),
                            new VersionedPackage(packageName, lowerVersionCode));
                    RollbackInfo rollback = new RollbackInfo(rollbackId, target);
                    recentlyExecutedRollbacks.add(rollback);
                }
@@ -157,9 +158,11 @@ class RollbackStore {
            JSONArray packagesJson = new JSONArray();
            for (PackageRollbackInfo info : data.packages) {
                JSONObject infoJson = new JSONObject();
                infoJson.put("packageName", info.packageName);
                infoJson.put("higherVersionCode", info.higherVersion.versionCode);
                infoJson.put("lowerVersionCode", info.lowerVersion.versionCode);
                infoJson.put("packageName", info.getPackageName());
                infoJson.put("higherVersionCode",
                        info.getVersionRolledBackFrom().getLongVersionCode());
                infoJson.put("lowerVersionCode",
                        info.getVersionRolledBackTo().getVersionCode());
                packagesJson.put(infoJson);
            }
            dataJson.put("rollbackId", data.rollbackId);
@@ -197,9 +200,11 @@ class RollbackStore {
                RollbackInfo rollback = recentlyExecutedRollbacks.get(i);
                JSONObject element = new JSONObject();
                element.put("rollbackId", rollback.getRollbackId());
                element.put("packageName", rollback.targetPackage.packageName);
                element.put("higherVersionCode", rollback.targetPackage.higherVersion.versionCode);
                element.put("lowerVersionCode", rollback.targetPackage.lowerVersion.versionCode);
                element.put("packageName", rollback.targetPackage.getPackageName());
                element.put("higherVersionCode",
                        rollback.targetPackage.getVersionRolledBackFrom().getLongVersionCode());
                element.put("lowerVersionCode",
                        rollback.targetPackage.getVersionRolledBackTo().getLongVersionCode());
                array.put(element);
            }

@@ -231,9 +236,9 @@ class RollbackStore {
                String packageName = infoJson.getString("packageName");
                long higherVersionCode = infoJson.getLong("higherVersionCode");
                long lowerVersionCode = infoJson.getLong("lowerVersionCode");
                data.packages.add(new PackageRollbackInfo(packageName,
                        new PackageRollbackInfo.PackageVersion(higherVersionCode),
                        new PackageRollbackInfo.PackageVersion(lowerVersionCode)));
                data.packages.add(new PackageRollbackInfo(
                        new VersionedPackage(packageName, higherVersionCode),
                        new VersionedPackage(packageName, lowerVersionCode)));
            }

            data.timestamp = Instant.parse(dataJson.getString("timestamp"));
+33 −47

File changed.

Preview size limit exceeded, changes collapsed.