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

Commit d293fc8e authored by Shrinidhi Hegde's avatar Shrinidhi Hegde Committed by Harshit Mahajan
Browse files

Rollback info API change. Added impact level to RollbackInfo.

Rollbacks are currently stored only for some mainline packages, but
rollbacks will be added for phonesky and GMS core in V. These new
rollbacks should not be treated similar to mainline. We would want to
perform GMS core rollback only when all other rescue party mitigations
are already tried. And Phonesky should not be automatically rolled back.

We introduce a new field rollbackImpactLevel to RollbackInfo, which is
used to determine the order in which these rollbacks should be performed
relative to other mitigations in PackageWatchdog.

rollbackImpactLevel is exposed through PackageInstaller.SessionParams.

Bug: 291135724
Test: CTS test. Unit tests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a3ae2464aac43d8bbc2129bdea7733d09b90e2da)
Merged-In: I723405eb62577202893ff208af2ab01b212b112a
Change-Id: I723405eb62577202893ff208af2ab01b212b112a
parent 0a87e803
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3860,6 +3860,7 @@ package android.content.pm {
    method public void setInstallAsInstantApp(boolean);
    method public void setInstallAsVirtualPreload();
    method public void setRequestDowngrade(boolean);
    method @FlaggedApi("android.content.pm.recoverability_detection") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackImpactLevel(int);
    method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
  }
@@ -4023,6 +4024,9 @@ package android.content.pm {
    field public static final int ROLLBACK_DATA_POLICY_RESTORE = 0; // 0x0
    field public static final int ROLLBACK_DATA_POLICY_RETAIN = 2; // 0x2
    field public static final int ROLLBACK_DATA_POLICY_WIPE = 1; // 0x1
    field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_HIGH = 1; // 0x1
    field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_LOW = 0; // 0x0
    field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2; // 0x2
    field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; // 0x0
    field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; // 0x1
    field public static final int SYSTEM_APP_STATE_INSTALLED = 2; // 0x2
+4 −0
Original line number Diff line number Diff line
@@ -1148,6 +1148,10 @@ package android.content.res {

package android.content.rollback {

  public final class RollbackInfo implements android.os.Parcelable {
    method @FlaggedApi("android.content.pm.recoverability_detection") public int getRollbackImpactLevel();
  }

  public final class RollbackManager {
    method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
    method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
+33 −0
Original line number Diff line number Diff line
@@ -2374,6 +2374,8 @@ public class PackageInstaller {
        /** @hide */
        public long rollbackLifetimeMillis = 0;
        /** {@hide} */
        public int rollbackImpactLevel = PackageManager.ROLLBACK_USER_IMPACT_LOW;
        /** {@hide} */
        public boolean forceQueryableOverride;
        /** {@hide} */
        public int requireUserAction = USER_ACTION_UNSPECIFIED;
@@ -2428,6 +2430,7 @@ public class PackageInstaller {
            }
            rollbackDataPolicy = source.readInt();
            rollbackLifetimeMillis = source.readLong();
            rollbackImpactLevel = source.readInt();
            requireUserAction = source.readInt();
            packageSource = source.readInt();
            applicationEnabledSettingPersistent = source.readBoolean();
@@ -2461,6 +2464,7 @@ public class PackageInstaller {
            ret.dataLoaderParams = dataLoaderParams;
            ret.rollbackDataPolicy = rollbackDataPolicy;
            ret.rollbackLifetimeMillis = rollbackLifetimeMillis;
            ret.rollbackImpactLevel = rollbackImpactLevel;
            ret.requireUserAction = requireUserAction;
            ret.packageSource = packageSource;
            ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent;
@@ -2797,6 +2801,28 @@ public class PackageInstaller {
            rollbackLifetimeMillis = lifetimeMillis;
        }

        /**
         * rollbackImpactLevel is a measure of impact a rollback has on the user. This can take one
         * of 3 values:
         * <ul>
         *     <li>{@link PackageManager#ROLLBACK_USER_IMPACT_LOW} (default)</li>
         *     <li>{@link PackageManager#ROLLBACK_USER_IMPACT_HIGH} (1)</li>
         *     <li>{@link PackageManager#ROLLBACK_USER_IMPACT_ONLY_MANUAL} (2)</li>
         * </ul>
         *
         * @hide
         */
        @SystemApi
        @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
        @FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION)
        public void setRollbackImpactLevel(@PackageManager.RollbackImpactLevel int impactLevel) {
            if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
                throw new IllegalArgumentException(
                        "Can't set rollbackImpactLevel when rollback is not enabled");
            }
            rollbackImpactLevel = impactLevel;
        }

        /**
         * @deprecated use {@link #setRequestDowngrade(boolean)}.
         * {@hide}
@@ -3151,6 +3177,7 @@ public class PackageInstaller {
            pw.printPair("dataLoaderParams", dataLoaderParams);
            pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
            pw.printPair("rollbackLifetimeMillis", rollbackLifetimeMillis);
            pw.printPair("rollbackImpactLevel", rollbackImpactLevel);
            pw.printPair("applicationEnabledSettingPersistent",
                    applicationEnabledSettingPersistent);
            pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
@@ -3193,6 +3220,7 @@ public class PackageInstaller {
            }
            dest.writeInt(rollbackDataPolicy);
            dest.writeLong(rollbackLifetimeMillis);
            dest.writeInt(rollbackImpactLevel);
            dest.writeInt(requireUserAction);
            dest.writeInt(packageSource);
            dest.writeBoolean(applicationEnabledSettingPersistent);
@@ -3389,6 +3417,9 @@ public class PackageInstaller {
        /** @hide */
        public long rollbackLifetimeMillis;

        /** {@hide} */
        public int rollbackImpactLevel;

        /** {@hide} */
        public int requireUserAction;

@@ -3457,6 +3488,7 @@ public class PackageInstaller {
            isPreapprovalRequested = source.readBoolean();
            rollbackDataPolicy = source.readInt();
            rollbackLifetimeMillis = source.readLong();
            rollbackImpactLevel = source.readInt();
            createdMillis = source.readLong();
            requireUserAction = source.readInt();
            installerUid = source.readInt();
@@ -4081,6 +4113,7 @@ public class PackageInstaller {
            dest.writeBoolean(isPreapprovalRequested);
            dest.writeInt(rollbackDataPolicy);
            dest.writeLong(rollbackLifetimeMillis);
            dest.writeInt(rollbackImpactLevel);
            dest.writeLong(createdMillis);
            dest.writeInt(requireUserAction);
            dest.writeInt(installerUid);
+38 −0
Original line number Diff line number Diff line
@@ -1428,6 +1428,44 @@ public abstract class PackageManager {
    @SystemApi
    public static final int ROLLBACK_DATA_POLICY_RETAIN = 2;

    /** @hide */
    @IntDef(prefix = {"ROLLBACK_USER_IMPACT_"}, value = {
            ROLLBACK_USER_IMPACT_LOW,
            ROLLBACK_USER_IMPACT_HIGH,
            ROLLBACK_USER_IMPACT_ONLY_MANUAL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface RollbackImpactLevel {}

    /**
     * Rollback will be performed automatically in response to native crashes on startup or
     * persistent service crashes. More suitable for apps that do not store any user data.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
    public static final int ROLLBACK_USER_IMPACT_LOW = 0;

    /**
     * Rollback will be performed automatically only when the device is found to be unrecoverable.
     * More suitable for apps that store user data and have higher impact on user.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
    public static final int ROLLBACK_USER_IMPACT_HIGH = 1;

    /**
     * Rollback will not be performed automatically. It can be triggered externally.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
    public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2;

    /** @hide */
    @IntDef(flag = true, prefix = { "INSTALL_" }, value = {
            INSTALL_REPLACE_EXISTING,
+76 −30
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

package android.content.rollback;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.pm.Flags;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -25,17 +29,14 @@ import android.os.Parcelable;
import java.util.List;

/**
 * Information about a set of packages that can be, or already have been
 * rolled back together.
 * Information about a set of packages that can be, or already have been rolled back together.
 *
 * @hide
 */
@SystemApi
public final class RollbackInfo implements Parcelable {

    /**
     * A unique identifier for the rollback.
     */
    /** A unique identifier for the rollback. */
    private final int mRollbackId;

    private final List<PackageRollbackInfo> mPackages;
@@ -44,15 +45,39 @@ public final class RollbackInfo implements Parcelable {

    private final boolean mIsStaged;
    private int mCommittedSessionId;
    private int mRollbackImpactLevel;

    /** @hide */
    public RollbackInfo(int rollbackId, List<PackageRollbackInfo> packages, boolean isStaged,
            List<VersionedPackage> causePackages,  int committedSessionId) {
    public RollbackInfo(
            int rollbackId,
            List<PackageRollbackInfo> packages,
            boolean isStaged,
            List<VersionedPackage> causePackages,
            int committedSessionId,
            @PackageManager.RollbackImpactLevel int rollbackImpactLevel) {
        this.mRollbackId = rollbackId;
        this.mPackages = packages;
        this.mIsStaged = isStaged;
        this.mCausePackages = causePackages;
        this.mCommittedSessionId = committedSessionId;
        this.mRollbackImpactLevel = rollbackImpactLevel;
    }

    /** @hide */
    public RollbackInfo(
            int rollbackId,
            List<PackageRollbackInfo> packages,
            boolean isStaged,
            List<VersionedPackage> causePackages,
            int committedSessionId) {
        // If impact level is not set default to 0
        this(
                rollbackId,
                packages,
                isStaged,
                causePackages,
                committedSessionId,
                PackageManager.ROLLBACK_USER_IMPACT_LOW);
    }

    private RollbackInfo(Parcel in) {
@@ -61,34 +86,28 @@ public final class RollbackInfo implements Parcelable {
        mIsStaged = in.readBoolean();
        mCausePackages = in.createTypedArrayList(VersionedPackage.CREATOR);
        mCommittedSessionId = in.readInt();
        mRollbackImpactLevel = in.readInt();
    }

    /**
     * Returns a unique identifier for this rollback.
     */
    /** Returns a unique identifier for this rollback. */
    public int getRollbackId() {
        return mRollbackId;
    }

    /**
     * Returns the list of package that are rolled back.
     */
    /** Returns the list of package that are rolled back. */
    @NonNull
    public List<PackageRollbackInfo> getPackages() {
        return mPackages;
    }

    /**
     * Returns true if this rollback requires reboot to take effect after
     * being committed.
     */
    /** Returns true if this rollback requires reboot to take effect after being committed. */
    public boolean isStaged() {
        return mIsStaged;
    }

    /**
     * Returns the session ID for the committed rollback for staged rollbacks.
     * Only applicable for rollbacks that have been committed.
     * Returns the session ID for the committed rollback for staged rollbacks. Only applicable for
     * rollbacks that have been committed.
     */
    public int getCommittedSessionId() {
        return mCommittedSessionId;
@@ -96,6 +115,7 @@ public final class RollbackInfo implements Parcelable {

    /**
     * Sets the session ID for the committed rollback for staged rollbacks.
     *
     * @hide
     */
    public void setCommittedSessionId(int sessionId) {
@@ -103,15 +123,40 @@ public final class RollbackInfo implements Parcelable {
    }

    /**
     * Gets the list of package versions that motivated this rollback.
     * As provided to {@link #commitRollback} when the rollback was committed.
     * This is only applicable for rollbacks that have been committed.
     * Gets the list of package versions that motivated this rollback. As provided to {@link
     * #commitRollback} when the rollback was committed. This is only applicable for rollbacks that
     * have been committed.
     */
    @NonNull
    public List<VersionedPackage> getCausePackages() {
        return mCausePackages;
    }

    /**
     * Get rollback impact level. Refer {@link
     * android.content.pm.PackageInstaller.SessionParams#setRollbackImpactLevel(int)} for more info
     * on impact level.
     *
     * @hide
     */
    @TestApi
    @FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION)
    public @PackageManager.RollbackImpactLevel int getRollbackImpactLevel() {
        return mRollbackImpactLevel;
    }

    /**
     * Set rollback impact level. Refer {@link
     * android.content.pm.PackageInstaller.SessionParams#setRollbackImpactLevel(int)} for more info
     * on impact level.
     *
     * @hide
     */
    public void setRollbackImpactLevel(
            @PackageManager.RollbackImpactLevel int rollbackImpactLevel) {
        mRollbackImpactLevel = rollbackImpactLevel;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -124,6 +169,7 @@ public final class RollbackInfo implements Parcelable {
        out.writeBoolean(mIsStaged);
        out.writeTypedList(mCausePackages);
        out.writeInt(mCommittedSessionId);
        out.writeInt(mRollbackImpactLevel);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<RollbackInfo> CREATOR =
Loading