1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content.rollback; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.content.pm.PackageManager; 23 import android.content.pm.VersionedPackage; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * Information about a rollback available for a particular package. 32 * 33 * @hide 34 */ 35 @SystemApi 36 public final class PackageRollbackInfo implements Parcelable { 37 38 private final VersionedPackage mVersionRolledBackFrom; 39 private final VersionedPackage mVersionRolledBackTo; 40 41 /** 42 * Encapsulates information required to restore a snapshot of an app's userdata. 43 * 44 * @hide 45 */ 46 public static class RestoreInfo { 47 public final int userId; 48 public final int appId; 49 public final String seInfo; 50 RestoreInfo(int userId, int appId, String seInfo)51 public RestoreInfo(int userId, int appId, String seInfo) { 52 this.userId = userId; 53 this.appId = appId; 54 this.seInfo = seInfo; 55 } 56 } 57 58 /* 59 * The list of users for which we need to backup userdata for this package. Backups of 60 * credential encrypted data are listed as pending if the user hasn't unlocked their device 61 * with credentials yet. 62 */ 63 // NOTE: Not a part of the Parcelable representation of this object. 64 private final List<Integer> mPendingBackups; 65 66 /** 67 * The list of users for which we need to restore userdata for this package. This field is 68 * non-null only after a rollback for this package has been committed. 69 */ 70 // NOTE: Not a part of the Parcelable representation of this object. 71 private final ArrayList<RestoreInfo> mPendingRestores; 72 73 /** 74 * Whether this instance represents the PackageRollbackInfo for an APEX module. 75 */ 76 private final boolean mIsApex; 77 78 /** 79 * Whether this instance represents the PackageRollbackInfo for an APK in APEX. 80 */ 81 private final boolean mIsApkInApex; 82 83 /* 84 * The list of users for which snapshots have been saved. 85 */ 86 // NOTE: Not a part of the Parcelable representation of this object. 87 private final List<Integer> mSnapshottedUsers; 88 89 /** 90 * The userdata policy to execute when a rollback for this package is committed. 91 */ 92 private final int mRollbackDataPolicy; 93 94 /** 95 * Returns the name of the package to roll back from. 96 */ 97 @NonNull getPackageName()98 public String getPackageName() { 99 return mVersionRolledBackFrom.getPackageName(); 100 } 101 102 /** 103 * Returns the version of the package rolled back from. 104 */ 105 @NonNull getVersionRolledBackFrom()106 public VersionedPackage getVersionRolledBackFrom() { 107 return mVersionRolledBackFrom; 108 } 109 110 /** 111 * Returns the version of the package rolled back to. 112 */ 113 @NonNull getVersionRolledBackTo()114 public VersionedPackage getVersionRolledBackTo() { 115 return mVersionRolledBackTo; 116 } 117 118 /** @hide */ addPendingBackup(int userId)119 public void addPendingBackup(int userId) { 120 mPendingBackups.add(userId); 121 } 122 123 /** @hide */ getPendingBackups()124 public List<Integer> getPendingBackups() { 125 return mPendingBackups; 126 } 127 128 /** @hide */ getPendingRestores()129 public ArrayList<RestoreInfo> getPendingRestores() { 130 return mPendingRestores; 131 } 132 133 /** @hide */ getRestoreInfo(int userId)134 public RestoreInfo getRestoreInfo(int userId) { 135 for (RestoreInfo ri : mPendingRestores) { 136 if (ri.userId == userId) { 137 return ri; 138 } 139 } 140 141 return null; 142 } 143 144 /** @hide */ removeRestoreInfo(RestoreInfo ri)145 public void removeRestoreInfo(RestoreInfo ri) { 146 mPendingRestores.remove(ri); 147 } 148 149 /** 150 * True if the package is an apex else false. 151 */ 152 @FlaggedApi(android.crashrecovery.flags.Flags.FLAG_ENABLE_CRASHRECOVERY) isApex()153 public boolean isApex() { 154 return mIsApex; 155 } 156 157 /** @hide */ getRollbackDataPolicy()158 public @PackageManager.RollbackDataPolicy int getRollbackDataPolicy() { 159 return mRollbackDataPolicy; 160 } 161 162 /** 163 * True if the package is apk-in-apex else false. 164 */ 165 @FlaggedApi(android.crashrecovery.flags.Flags.FLAG_ENABLE_CRASHRECOVERY) isApkInApex()166 public boolean isApkInApex() { 167 return mIsApkInApex; 168 } 169 170 /** @hide */ getSnapshottedUsers()171 public List<Integer> getSnapshottedUsers() { 172 return mSnapshottedUsers; 173 } 174 175 /** @hide */ removePendingBackup(int userId)176 public void removePendingBackup(int userId) { 177 mPendingBackups.remove((Integer) userId); 178 } 179 180 /** @hide */ removePendingRestoreInfo(int userId)181 public void removePendingRestoreInfo(int userId) { 182 removeRestoreInfo(getRestoreInfo(userId)); 183 } 184 185 /** @hide */ PackageRollbackInfo(VersionedPackage packageRolledBackFrom, VersionedPackage packageRolledBackTo, @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers)186 public PackageRollbackInfo(VersionedPackage packageRolledBackFrom, 187 VersionedPackage packageRolledBackTo, 188 @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, 189 boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers) { 190 this(packageRolledBackFrom, packageRolledBackTo, pendingBackups, pendingRestores, isApex, 191 isApkInApex, snapshottedUsers, PackageManager.ROLLBACK_DATA_POLICY_RESTORE); 192 } 193 194 /** @hide */ PackageRollbackInfo(VersionedPackage packageRolledBackFrom, VersionedPackage packageRolledBackTo, @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers, @PackageManager.RollbackDataPolicy int rollbackDataPolicy)195 public PackageRollbackInfo(VersionedPackage packageRolledBackFrom, 196 VersionedPackage packageRolledBackTo, 197 @NonNull List<Integer> pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, 198 boolean isApex, boolean isApkInApex, @NonNull List<Integer> snapshottedUsers, 199 @PackageManager.RollbackDataPolicy int rollbackDataPolicy) { 200 this.mVersionRolledBackFrom = packageRolledBackFrom; 201 this.mVersionRolledBackTo = packageRolledBackTo; 202 this.mPendingBackups = pendingBackups; 203 this.mPendingRestores = pendingRestores; 204 this.mIsApex = isApex; 205 this.mRollbackDataPolicy = rollbackDataPolicy; 206 this.mIsApkInApex = isApkInApex; 207 this.mSnapshottedUsers = snapshottedUsers; 208 } 209 PackageRollbackInfo(Parcel in)210 private PackageRollbackInfo(Parcel in) { 211 this.mVersionRolledBackFrom = VersionedPackage.CREATOR.createFromParcel(in); 212 this.mVersionRolledBackTo = VersionedPackage.CREATOR.createFromParcel(in); 213 this.mIsApex = in.readBoolean(); 214 this.mIsApkInApex = in.readBoolean(); 215 this.mPendingRestores = null; 216 this.mPendingBackups = null; 217 this.mSnapshottedUsers = null; 218 this.mRollbackDataPolicy = PackageManager.ROLLBACK_DATA_POLICY_RESTORE; 219 } 220 221 @Override describeContents()222 public int describeContents() { 223 return 0; 224 } 225 226 @Override writeToParcel(Parcel out, int flags)227 public void writeToParcel(Parcel out, int flags) { 228 mVersionRolledBackFrom.writeToParcel(out, flags); 229 mVersionRolledBackTo.writeToParcel(out, flags); 230 out.writeBoolean(mIsApex); 231 out.writeBoolean(mIsApkInApex); 232 } 233 234 public static final @NonNull Parcelable.Creator<PackageRollbackInfo> CREATOR = 235 new Parcelable.Creator<PackageRollbackInfo>() { 236 public PackageRollbackInfo createFromParcel(Parcel in) { 237 return new PackageRollbackInfo(in); 238 } 239 240 public PackageRollbackInfo[] newArray(int size) { 241 return new PackageRollbackInfo[size]; 242 } 243 }; 244 } 245