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.NonNull; 20 import android.annotation.SystemApi; 21 import android.annotation.TestApi; 22 import android.content.pm.VersionedPackage; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.util.IntArray; 26 import android.util.SparseLongArray; 27 28 import java.util.ArrayList; 29 30 /** 31 * Information about a rollback available for a particular package. 32 * 33 * @hide 34 */ 35 @SystemApi @TestApi 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 IntArray 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 * The list of users for which snapshots have been saved. 80 */ 81 // NOTE: Not a part of the Parcelable representation of this object. 82 private final IntArray mSnapshottedUsers; 83 84 /** 85 * A mapping between user and an inode of theirs CE data snapshot. 86 */ 87 // NOTE: Not a part of the Parcelable representation of this object. 88 private final SparseLongArray mCeSnapshotInodes; 89 90 /** 91 * Returns the name of the package to roll back from. 92 */ 93 @NonNull getPackageName()94 public String getPackageName() { 95 return mVersionRolledBackFrom.getPackageName(); 96 } 97 98 /** 99 * Returns the version of the package rolled back from. 100 */ 101 @NonNull getVersionRolledBackFrom()102 public VersionedPackage getVersionRolledBackFrom() { 103 return mVersionRolledBackFrom; 104 } 105 106 /** 107 * Returns the version of the package rolled back to. 108 */ 109 @NonNull getVersionRolledBackTo()110 public VersionedPackage getVersionRolledBackTo() { 111 return mVersionRolledBackTo; 112 } 113 114 /** @hide */ addPendingBackup(int userId)115 public void addPendingBackup(int userId) { 116 mPendingBackups.add(userId); 117 } 118 119 /** @hide */ getPendingBackups()120 public IntArray getPendingBackups() { 121 return mPendingBackups; 122 } 123 124 /** @hide */ getPendingRestores()125 public ArrayList<RestoreInfo> getPendingRestores() { 126 return mPendingRestores; 127 } 128 129 /** @hide */ getRestoreInfo(int userId)130 public RestoreInfo getRestoreInfo(int userId) { 131 for (RestoreInfo ri : mPendingRestores) { 132 if (ri.userId == userId) { 133 return ri; 134 } 135 } 136 137 return null; 138 } 139 140 /** @hide */ removeRestoreInfo(RestoreInfo ri)141 public void removeRestoreInfo(RestoreInfo ri) { 142 mPendingRestores.remove(ri); 143 } 144 145 /** @hide */ isApex()146 public boolean isApex() { 147 return mIsApex; 148 } 149 150 /** @hide */ getSnapshottedUsers()151 public IntArray getSnapshottedUsers() { 152 return mSnapshottedUsers; 153 } 154 155 /** @hide */ getCeSnapshotInodes()156 public SparseLongArray getCeSnapshotInodes() { 157 return mCeSnapshotInodes; 158 } 159 160 /** @hide */ putCeSnapshotInode(int userId, long ceSnapshotInode)161 public void putCeSnapshotInode(int userId, long ceSnapshotInode) { 162 mCeSnapshotInodes.put(userId, ceSnapshotInode); 163 } 164 165 /** @hide */ removePendingBackup(int userId)166 public void removePendingBackup(int userId) { 167 int idx = mPendingBackups.indexOf(userId); 168 if (idx != -1) { 169 mPendingBackups.remove(idx); 170 } 171 } 172 173 /** @hide */ removePendingRestoreInfo(int userId)174 public void removePendingRestoreInfo(int userId) { 175 removeRestoreInfo(getRestoreInfo(userId)); 176 } 177 178 /** @hide */ PackageRollbackInfo(VersionedPackage packageRolledBackFrom, VersionedPackage packageRolledBackTo, @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, boolean isApex, @NonNull IntArray snapshottedUsers, @NonNull SparseLongArray ceSnapshotInodes)179 public PackageRollbackInfo(VersionedPackage packageRolledBackFrom, 180 VersionedPackage packageRolledBackTo, 181 @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores, 182 boolean isApex, @NonNull IntArray snapshottedUsers, 183 @NonNull SparseLongArray ceSnapshotInodes) { 184 this.mVersionRolledBackFrom = packageRolledBackFrom; 185 this.mVersionRolledBackTo = packageRolledBackTo; 186 this.mPendingBackups = pendingBackups; 187 this.mPendingRestores = pendingRestores; 188 this.mIsApex = isApex; 189 this.mSnapshottedUsers = snapshottedUsers; 190 this.mCeSnapshotInodes = ceSnapshotInodes; 191 } 192 PackageRollbackInfo(Parcel in)193 private PackageRollbackInfo(Parcel in) { 194 this.mVersionRolledBackFrom = VersionedPackage.CREATOR.createFromParcel(in); 195 this.mVersionRolledBackTo = VersionedPackage.CREATOR.createFromParcel(in); 196 this.mIsApex = in.readBoolean(); 197 this.mPendingRestores = null; 198 this.mPendingBackups = null; 199 this.mSnapshottedUsers = null; 200 this.mCeSnapshotInodes = null; 201 } 202 203 @Override describeContents()204 public int describeContents() { 205 return 0; 206 } 207 208 @Override writeToParcel(Parcel out, int flags)209 public void writeToParcel(Parcel out, int flags) { 210 mVersionRolledBackFrom.writeToParcel(out, flags); 211 mVersionRolledBackTo.writeToParcel(out, flags); 212 out.writeBoolean(mIsApex); 213 } 214 215 public static final @NonNull Parcelable.Creator<PackageRollbackInfo> CREATOR = 216 new Parcelable.Creator<PackageRollbackInfo>() { 217 public PackageRollbackInfo createFromParcel(Parcel in) { 218 return new PackageRollbackInfo(in); 219 } 220 221 public PackageRollbackInfo[] newArray(int size) { 222 return new PackageRollbackInfo[size]; 223 } 224 }; 225 } 226