Rename RollbackData to Rollback.
Because "Data" doesn't add anything useful to the name. Also prefer the variable name "rollback" over "data" and "rd" for instances of Rollback. Test: builds. Change-Id: Ibaa3326660345a763c67c573368ba1da11c0a830 Merged-In: I5ae3866753d6badcdf019525b40522937568dee5
This commit is contained in:
@@ -98,14 +98,14 @@ public class AppDataRollbackHelper {
|
|||||||
|
|
||||||
final IntArray pendingBackups = packageRollbackInfo.getPendingBackups();
|
final IntArray pendingBackups = packageRollbackInfo.getPendingBackups();
|
||||||
final List<RestoreInfo> pendingRestores = packageRollbackInfo.getPendingRestores();
|
final List<RestoreInfo> pendingRestores = packageRollbackInfo.getPendingRestores();
|
||||||
boolean changedRollbackData = false;
|
boolean changedRollback = false;
|
||||||
|
|
||||||
// If we still have a userdata backup pending for this user, it implies that the user
|
// If we still have a userdata backup pending for this user, it implies that the user
|
||||||
// hasn't unlocked their device between the point of backup and the point of restore,
|
// hasn't unlocked their device between the point of backup and the point of restore,
|
||||||
// so the data cannot have changed. We simply skip restoring CE data in this case.
|
// so the data cannot have changed. We simply skip restoring CE data in this case.
|
||||||
if (pendingBackups != null && pendingBackups.indexOf(userId) != -1) {
|
if (pendingBackups != null && pendingBackups.indexOf(userId) != -1) {
|
||||||
pendingBackups.remove(pendingBackups.indexOf(userId));
|
pendingBackups.remove(pendingBackups.indexOf(userId));
|
||||||
changedRollbackData = true;
|
changedRollback = true;
|
||||||
} else {
|
} else {
|
||||||
// There's no pending CE backup for this user, which means that we successfully
|
// There's no pending CE backup for this user, which means that we successfully
|
||||||
// managed to backup data for the user, which means we seek to restore it
|
// managed to backup data for the user, which means we seek to restore it
|
||||||
@@ -113,7 +113,7 @@ public class AppDataRollbackHelper {
|
|||||||
// We've encountered a user that hasn't unlocked on a FBE device, so we can't
|
// We've encountered a user that hasn't unlocked on a FBE device, so we can't
|
||||||
// copy across app user data until the user unlocks their device.
|
// copy across app user data until the user unlocks their device.
|
||||||
pendingRestores.add(new RestoreInfo(userId, appId, seInfo));
|
pendingRestores.add(new RestoreInfo(userId, appId, seInfo));
|
||||||
changedRollbackData = true;
|
changedRollback = true;
|
||||||
} else {
|
} else {
|
||||||
// This user has unlocked, we can proceed to restore both CE and DE data.
|
// This user has unlocked, we can proceed to restore both CE and DE data.
|
||||||
storageFlags = storageFlags | Installer.FLAG_STORAGE_CE;
|
storageFlags = storageFlags | Installer.FLAG_STORAGE_CE;
|
||||||
@@ -128,7 +128,7 @@ public class AppDataRollbackHelper {
|
|||||||
+ packageRollbackInfo.getPackageName(), ie);
|
+ packageRollbackInfo.getPackageName(), ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
return changedRollbackData;
|
return changedRollback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,29 +160,29 @@ public class AppDataRollbackHelper {
|
|||||||
* Packages pending backup for the given user are added to {@code pendingBackupPackages} along
|
* Packages pending backup for the given user are added to {@code pendingBackupPackages} along
|
||||||
* with their corresponding {@code PackageRollbackInfo}.
|
* with their corresponding {@code PackageRollbackInfo}.
|
||||||
*
|
*
|
||||||
* @return the list of {@code RollbackData} that has pending backups. Note that some of the
|
* @return the list of rollbacks that have pending backups. Note that some of the
|
||||||
* backups won't be performed, because they might be counteracted by pending restores.
|
* backups won't be performed, because they might be counteracted by pending restores.
|
||||||
*/
|
*/
|
||||||
private static List<RollbackData> computePendingBackups(int userId,
|
private static List<Rollback> computePendingBackups(int userId,
|
||||||
Map<String, PackageRollbackInfo> pendingBackupPackages,
|
Map<String, PackageRollbackInfo> pendingBackupPackages,
|
||||||
List<RollbackData> rollbacks) {
|
List<Rollback> rollbacks) {
|
||||||
List<RollbackData> rd = new ArrayList<>();
|
List<Rollback> rollbacksWithPendingBackups = new ArrayList<>();
|
||||||
|
|
||||||
for (RollbackData data : rollbacks) {
|
for (Rollback rollback : rollbacks) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
final IntArray pendingBackupUsers = info.getPendingBackups();
|
final IntArray pendingBackupUsers = info.getPendingBackups();
|
||||||
if (pendingBackupUsers != null) {
|
if (pendingBackupUsers != null) {
|
||||||
final int idx = pendingBackupUsers.indexOf(userId);
|
final int idx = pendingBackupUsers.indexOf(userId);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
pendingBackupPackages.put(info.getPackageName(), info);
|
pendingBackupPackages.put(info.getPackageName(), info);
|
||||||
if (rd.indexOf(data) == -1) {
|
if (rollbacksWithPendingBackups.indexOf(rollback) == -1) {
|
||||||
rd.add(data);
|
rollbacksWithPendingBackups.add(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rd;
|
return rollbacksWithPendingBackups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,45 +190,45 @@ public class AppDataRollbackHelper {
|
|||||||
* Packages pending restore are added to {@code pendingRestores} along with their corresponding
|
* Packages pending restore are added to {@code pendingRestores} along with their corresponding
|
||||||
* {@code PackageRollbackInfo}.
|
* {@code PackageRollbackInfo}.
|
||||||
*
|
*
|
||||||
* @return the list of {@code RollbackData} that has pending restores. Note that some of the
|
* @return the list of rollbacks that have pending restores. Note that some of the
|
||||||
* restores won't be performed, because they might be counteracted by pending backups.
|
* restores won't be performed, because they might be counteracted by pending backups.
|
||||||
*/
|
*/
|
||||||
private static List<RollbackData> computePendingRestores(int userId,
|
private static List<Rollback> computePendingRestores(int userId,
|
||||||
Map<String, PackageRollbackInfo> pendingRestorePackages,
|
Map<String, PackageRollbackInfo> pendingRestorePackages,
|
||||||
List<RollbackData> rollbacks) {
|
List<Rollback> rollbacks) {
|
||||||
List<RollbackData> rd = new ArrayList<>();
|
List<Rollback> rollbacksWithPendingRestores = new ArrayList<>();
|
||||||
|
|
||||||
for (RollbackData data : rollbacks) {
|
for (Rollback rollback : rollbacks) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
final RestoreInfo ri = info.getRestoreInfo(userId);
|
final RestoreInfo ri = info.getRestoreInfo(userId);
|
||||||
if (ri != null) {
|
if (ri != null) {
|
||||||
pendingRestorePackages.put(info.getPackageName(), info);
|
pendingRestorePackages.put(info.getPackageName(), info);
|
||||||
if (rd.indexOf(data) == -1) {
|
if (rollbacksWithPendingRestores.indexOf(rollback) == -1) {
|
||||||
rd.add(data);
|
rollbacksWithPendingRestores.add(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rd;
|
return rollbacksWithPendingRestores;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commits the list of pending backups and restores for a given {@code userId}. For the pending
|
* Commits the list of pending backups and restores for a given {@code userId}. For rollbacks
|
||||||
* backups updates corresponding {@code changedRollbackData} with a mapping from {@code userId}
|
* with pending backups, updates the {@code Rollback} instance with a mapping from
|
||||||
* to a inode of theirs CE user data snapshot.
|
* {@code userId} to inode of the CE user data snapshot.
|
||||||
*
|
*
|
||||||
* @return the set of {@code RollbackData} that have been changed and should be stored on disk.
|
* @return the set of rollbacks with changes that should be stored on disk.
|
||||||
*/
|
*/
|
||||||
public Set<RollbackData> commitPendingBackupAndRestoreForUser(int userId,
|
public Set<Rollback> commitPendingBackupAndRestoreForUser(int userId,
|
||||||
List<RollbackData> rollbacks) {
|
List<Rollback> rollbacks) {
|
||||||
|
|
||||||
final Map<String, PackageRollbackInfo> pendingBackupPackages = new HashMap<>();
|
final Map<String, PackageRollbackInfo> pendingBackupPackages = new HashMap<>();
|
||||||
final List<RollbackData> pendingBackups = computePendingBackups(userId,
|
final List<Rollback> pendingBackups = computePendingBackups(userId,
|
||||||
pendingBackupPackages, rollbacks);
|
pendingBackupPackages, rollbacks);
|
||||||
|
|
||||||
final Map<String, PackageRollbackInfo> pendingRestorePackages = new HashMap<>();
|
final Map<String, PackageRollbackInfo> pendingRestorePackages = new HashMap<>();
|
||||||
final List<RollbackData> pendingRestores = computePendingRestores(userId,
|
final List<Rollback> pendingRestores = computePendingRestores(userId,
|
||||||
pendingRestorePackages, rollbacks);
|
pendingRestorePackages, rollbacks);
|
||||||
|
|
||||||
// First remove unnecessary backups, i.e. when user did not unlock their phone between the
|
// First remove unnecessary backups, i.e. when user did not unlock their phone between the
|
||||||
@@ -248,14 +248,15 @@ public class AppDataRollbackHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pendingBackupPackages.isEmpty()) {
|
if (!pendingBackupPackages.isEmpty()) {
|
||||||
for (RollbackData data : pendingBackups) {
|
for (Rollback rollback : pendingBackups) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
final IntArray pendingBackupUsers = info.getPendingBackups();
|
final IntArray pendingBackupUsers = info.getPendingBackups();
|
||||||
final int idx = pendingBackupUsers.indexOf(userId);
|
final int idx = pendingBackupUsers.indexOf(userId);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
try {
|
try {
|
||||||
long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
|
long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
|
||||||
userId, data.info.getRollbackId(), Installer.FLAG_STORAGE_CE);
|
userId, rollback.info.getRollbackId(),
|
||||||
|
Installer.FLAG_STORAGE_CE);
|
||||||
info.putCeSnapshotInode(userId, ceSnapshotInode);
|
info.putCeSnapshotInode(userId, ceSnapshotInode);
|
||||||
pendingBackupUsers.remove(idx);
|
pendingBackupUsers.remove(idx);
|
||||||
} catch (InstallerException ie) {
|
} catch (InstallerException ie) {
|
||||||
@@ -269,13 +270,13 @@ public class AppDataRollbackHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pendingRestorePackages.isEmpty()) {
|
if (!pendingRestorePackages.isEmpty()) {
|
||||||
for (RollbackData data : pendingRestores) {
|
for (Rollback rollback : pendingRestores) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
final RestoreInfo ri = info.getRestoreInfo(userId);
|
final RestoreInfo ri = info.getRestoreInfo(userId);
|
||||||
if (ri != null) {
|
if (ri != null) {
|
||||||
try {
|
try {
|
||||||
mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
|
mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
|
||||||
ri.seInfo, userId, data.info.getRollbackId(),
|
ri.seInfo, userId, rollback.info.getRollbackId(),
|
||||||
Installer.FLAG_STORAGE_CE);
|
Installer.FLAG_STORAGE_CE);
|
||||||
info.removeRestoreInfo(ri);
|
info.removeRestoreInfo(ri);
|
||||||
} catch (InstallerException ie) {
|
} catch (InstallerException ie) {
|
||||||
@@ -287,7 +288,7 @@ public class AppDataRollbackHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<RollbackData> changed = new HashSet<>(pendingBackups);
|
final Set<Rollback> changed = new HashSet<>(pendingBackups);
|
||||||
changed.addAll(pendingRestores);
|
changed.addAll(pendingRestores);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import java.util.ArrayList;
|
|||||||
* Information about a rollback available for a set of atomically installed
|
* Information about a rollback available for a set of atomically installed
|
||||||
* packages.
|
* packages.
|
||||||
*/
|
*/
|
||||||
class RollbackData {
|
class Rollback {
|
||||||
@IntDef(flag = true, prefix = { "ROLLBACK_STATE_" }, value = {
|
@IntDef(flag = true, prefix = { "ROLLBACK_STATE_" }, value = {
|
||||||
ROLLBACK_STATE_ENABLING,
|
ROLLBACK_STATE_ENABLING,
|
||||||
ROLLBACK_STATE_AVAILABLE,
|
ROLLBACK_STATE_AVAILABLE,
|
||||||
@@ -102,13 +102,13 @@ class RollbackData {
|
|||||||
public boolean restoreUserDataInProgress = false;
|
public boolean restoreUserDataInProgress = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new, empty RollbackData instance.
|
* Constructs a new, empty Rollback instance.
|
||||||
*
|
*
|
||||||
* @param rollbackId the id of the rollback.
|
* @param rollbackId the id of the rollback.
|
||||||
* @param backupDir the directory where the rollback data is stored.
|
* @param backupDir the directory where the rollback data is stored.
|
||||||
* @param stagedSessionId the session id if this is a staged rollback, -1 otherwise.
|
* @param stagedSessionId the session id if this is a staged rollback, -1 otherwise.
|
||||||
*/
|
*/
|
||||||
RollbackData(int rollbackId, File backupDir, int stagedSessionId) {
|
Rollback(int rollbackId, File backupDir, int stagedSessionId) {
|
||||||
this.info = new RollbackInfo(rollbackId,
|
this.info = new RollbackInfo(rollbackId,
|
||||||
/* packages */ new ArrayList<>(),
|
/* packages */ new ArrayList<>(),
|
||||||
/* isStaged */ stagedSessionId != -1,
|
/* isStaged */ stagedSessionId != -1,
|
||||||
@@ -121,9 +121,9 @@ class RollbackData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a RollbackData instance with full rollback data information.
|
* Constructs a pre-populated Rollback instance.
|
||||||
*/
|
*/
|
||||||
RollbackData(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
|
Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
|
||||||
@RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) {
|
@RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) {
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.backupDir = backupDir;
|
this.backupDir = backupDir;
|
||||||
@@ -143,9 +143,9 @@ class RollbackData {
|
|||||||
|
|
||||||
static String rollbackStateToString(@RollbackState int state) {
|
static String rollbackStateToString(@RollbackState int state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case RollbackData.ROLLBACK_STATE_ENABLING: return "enabling";
|
case Rollback.ROLLBACK_STATE_ENABLING: return "enabling";
|
||||||
case RollbackData.ROLLBACK_STATE_AVAILABLE: return "available";
|
case Rollback.ROLLBACK_STATE_AVAILABLE: return "available";
|
||||||
case RollbackData.ROLLBACK_STATE_COMMITTED: return "committed";
|
case Rollback.ROLLBACK_STATE_COMMITTED: return "committed";
|
||||||
}
|
}
|
||||||
throw new AssertionError("Invalid rollback state: " + state);
|
throw new AssertionError("Invalid rollback state: " + state);
|
||||||
}
|
}
|
||||||
@@ -153,9 +153,9 @@ class RollbackData {
|
|||||||
static @RollbackState int rollbackStateFromString(String state)
|
static @RollbackState int rollbackStateFromString(String state)
|
||||||
throws ParseException {
|
throws ParseException {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case "enabling": return RollbackData.ROLLBACK_STATE_ENABLING;
|
case "enabling": return Rollback.ROLLBACK_STATE_ENABLING;
|
||||||
case "available": return RollbackData.ROLLBACK_STATE_AVAILABLE;
|
case "available": return Rollback.ROLLBACK_STATE_AVAILABLE;
|
||||||
case "committed": return RollbackData.ROLLBACK_STATE_COMMITTED;
|
case "committed": return Rollback.ROLLBACK_STATE_COMMITTED;
|
||||||
}
|
}
|
||||||
throw new ParseException("Invalid rollback state: " + state, 0);
|
throw new ParseException("Invalid rollback state: " + state, 0);
|
||||||
}
|
}
|
||||||
@@ -110,13 +110,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseBooleanArray mAllocatedRollbackIds = new SparseBooleanArray();
|
private final SparseBooleanArray mAllocatedRollbackIds = new SparseBooleanArray();
|
||||||
|
|
||||||
// Package rollback data for rollbacks we are in the process of enabling.
|
// Rollbacks we are in the process of enabling.
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final Set<NewRollback> mNewRollbacks = new ArraySet<>();
|
private final Set<NewRollback> mNewRollbacks = new ArraySet<>();
|
||||||
|
|
||||||
// The list of all rollbacks, including available and committed rollbacks.
|
// The list of all rollbacks, including available and committed rollbacks.
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final List<RollbackData> mRollbacks;
|
private final List<Rollback> mRollbacks;
|
||||||
|
|
||||||
private final RollbackStore mRollbackStore;
|
private final RollbackStore mRollbackStore;
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
private final AppDataRollbackHelper mAppDataRollbackHelper;
|
private final AppDataRollbackHelper mAppDataRollbackHelper;
|
||||||
|
|
||||||
// This field stores the difference in Millis between the uptime (millis since device
|
// This field stores the difference in Millis between the uptime (millis since device
|
||||||
// has booted) and current time (device wall clock) - it's used to update rollback data
|
// has booted) and current time (device wall clock) - it's used to update rollback
|
||||||
// timestamps when the time is changed, by the user or by change of timezone.
|
// timestamps when the time is changed, by the user or by change of timezone.
|
||||||
// No need for guarding with lock because value is only accessed in handler thread.
|
// No need for guarding with lock because value is only accessed in handler thread.
|
||||||
private long mRelativeBootTime = calculateRelativeBootTime();
|
private long mRelativeBootTime = calculateRelativeBootTime();
|
||||||
@@ -146,9 +146,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
|
|
||||||
// Load rollback data from device storage.
|
// Load rollback data from device storage.
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mRollbacks = mRollbackStore.loadAllRollbackData();
|
mRollbacks = mRollbackStore.loadRollbacks();
|
||||||
for (RollbackData data : mRollbacks) {
|
for (Rollback rollback : mRollbacks) {
|
||||||
mAllocatedRollbackIds.put(data.info.getRollbackId(), true);
|
mAllocatedRollbackIds.put(rollback.info.getRollbackId(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,9 +301,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
List<RollbackInfo> rollbacks = new ArrayList<>();
|
List<RollbackInfo> rollbacks = new ArrayList<>();
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback rollback = mRollbacks.get(i);
|
||||||
if (data.state == RollbackData.ROLLBACK_STATE_AVAILABLE) {
|
if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE) {
|
||||||
rollbacks.add(data.info);
|
rollbacks.add(rollback.info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ParceledListSlice<>(rollbacks);
|
return new ParceledListSlice<>(rollbacks);
|
||||||
@@ -317,9 +317,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
List<RollbackInfo> rollbacks = new ArrayList<>();
|
List<RollbackInfo> rollbacks = new ArrayList<>();
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback rollback = mRollbacks.get(i);
|
||||||
if (data.state == RollbackData.ROLLBACK_STATE_COMMITTED) {
|
if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
|
||||||
rollbacks.add(data.info);
|
rollbacks.add(rollback.info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ParceledListSlice<>(rollbacks);
|
return new ParceledListSlice<>(rollbacks);
|
||||||
@@ -349,11 +349,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
final long timeDifference = mRelativeBootTime - oldRelativeBootTime;
|
final long timeDifference = mRelativeBootTime - oldRelativeBootTime;
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Iterator<RollbackData> iter = mRollbacks.iterator();
|
Iterator<Rollback> iter = mRollbacks.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
RollbackData data = iter.next();
|
Rollback rollback = iter.next();
|
||||||
data.timestamp = data.timestamp.plusMillis(timeDifference);
|
rollback.timestamp = rollback.timestamp.plusMillis(timeDifference);
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,8 +377,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
String callerPackageName, IntentSender statusReceiver) {
|
String callerPackageName, IntentSender statusReceiver) {
|
||||||
Slog.i(TAG, "Initiating rollback");
|
Slog.i(TAG, "Initiating rollback");
|
||||||
|
|
||||||
RollbackData data = getRollbackForId(rollbackId);
|
Rollback rollback = getRollbackForId(rollbackId);
|
||||||
if (data == null || data.state != RollbackData.ROLLBACK_STATE_AVAILABLE) {
|
if (rollback == null || rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
|
||||||
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
|
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
|
||||||
"Rollback unavailable");
|
"Rollback unavailable");
|
||||||
return;
|
return;
|
||||||
@@ -402,14 +402,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||||
parentParams.setRequestDowngrade(true);
|
parentParams.setRequestDowngrade(true);
|
||||||
parentParams.setMultiPackage();
|
parentParams.setMultiPackage();
|
||||||
if (data.isStaged()) {
|
if (rollback.isStaged()) {
|
||||||
parentParams.setStaged();
|
parentParams.setStaged();
|
||||||
}
|
}
|
||||||
|
|
||||||
int parentSessionId = packageInstaller.createSession(parentParams);
|
int parentSessionId = packageInstaller.createSession(parentParams);
|
||||||
PackageInstaller.Session parentSession = packageInstaller.openSession(parentSessionId);
|
PackageInstaller.Session parentSession = packageInstaller.openSession(parentSessionId);
|
||||||
|
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
|
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
|
||||||
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||||
// TODO: We can't get the installerPackageName for apex
|
// TODO: We can't get the installerPackageName for apex
|
||||||
@@ -424,7 +424,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
params.setRequestDowngrade(true);
|
params.setRequestDowngrade(true);
|
||||||
params.setRequiredInstalledVersionCode(
|
params.setRequiredInstalledVersionCode(
|
||||||
info.getVersionRolledBackFrom().getLongVersionCode());
|
info.getVersionRolledBackFrom().getLongVersionCode());
|
||||||
if (data.isStaged()) {
|
if (rollback.isStaged()) {
|
||||||
params.setStaged();
|
params.setStaged();
|
||||||
}
|
}
|
||||||
if (info.isApex()) {
|
if (info.isApex()) {
|
||||||
@@ -433,7 +433,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
int sessionId = packageInstaller.createSession(params);
|
int sessionId = packageInstaller.createSession(params);
|
||||||
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||||
File[] packageCodePaths = RollbackStore.getPackageCodePaths(
|
File[] packageCodePaths = RollbackStore.getPackageCodePaths(
|
||||||
data, info.getPackageName());
|
rollback, info.getPackageName());
|
||||||
if (packageCodePaths == null) {
|
if (packageCodePaths == null) {
|
||||||
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
|
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
|
||||||
"Backup copy of package inaccessible");
|
"Backup copy of package inaccessible");
|
||||||
@@ -474,8 +474,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
// TODO: Could this cause a rollback to be
|
// TODO: Could this cause a rollback to be
|
||||||
// resurrected if it should otherwise have
|
// resurrected if it should otherwise have
|
||||||
// expired by now?
|
// expired by now?
|
||||||
data.state = RollbackData.ROLLBACK_STATE_AVAILABLE;
|
rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
|
||||||
data.restoreUserDataInProgress = false;
|
rollback.restoreUserDataInProgress = false;
|
||||||
}
|
}
|
||||||
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_INSTALL,
|
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_INSTALL,
|
||||||
"Rollback downgrade install failed: "
|
"Rollback downgrade install failed: "
|
||||||
@@ -485,17 +485,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!data.isStaged()) {
|
if (!rollback.isStaged()) {
|
||||||
// All calls to restoreUserData should have
|
// All calls to restoreUserData should have
|
||||||
// completed by now for a non-staged install.
|
// completed by now for a non-staged install.
|
||||||
data.restoreUserDataInProgress = false;
|
rollback.restoreUserDataInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.info.setCommittedSessionId(parentSessionId);
|
rollback.info.setCommittedSessionId(parentSessionId);
|
||||||
data.info.getCausePackages().addAll(causePackages);
|
rollback.info.getCausePackages().addAll(causePackages);
|
||||||
}
|
}
|
||||||
mRollbackStore.deletePackageCodePaths(data);
|
mRollbackStore.deletePackageCodePaths(rollback);
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
|
|
||||||
sendSuccess(statusReceiver);
|
sendSuccess(statusReceiver);
|
||||||
|
|
||||||
@@ -510,8 +510,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
);
|
);
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
data.state = RollbackData.ROLLBACK_STATE_COMMITTED;
|
rollback.state = Rollback.ROLLBACK_STATE_COMMITTED;
|
||||||
data.restoreUserDataInProgress = true;
|
rollback.restoreUserDataInProgress = true;
|
||||||
}
|
}
|
||||||
parentSession.commit(receiver.getIntentSender());
|
parentSession.commit(receiver.getIntentSender());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -533,7 +533,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
updateRollbackLifetimeDurationInMillis();
|
updateRollbackLifetimeDurationInMillis();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mRollbacks.clear();
|
mRollbacks.clear();
|
||||||
mRollbacks.addAll(mRollbackStore.loadAllRollbackData());
|
mRollbacks.addAll(mRollbackStore.loadRollbacks());
|
||||||
}
|
}
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
});
|
});
|
||||||
@@ -551,13 +551,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
Manifest.permission.TEST_MANAGE_ROLLBACKS,
|
Manifest.permission.TEST_MANAGE_ROLLBACKS,
|
||||||
"expireRollbackForPackage");
|
"expireRollbackForPackage");
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Iterator<RollbackData> iter = mRollbacks.iterator();
|
Iterator<Rollback> iter = mRollbacks.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
RollbackData data = iter.next();
|
Rollback rollback = iter.next();
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
if (info.getPackageName().equals(packageName)) {
|
if (info.getPackageName().equals(packageName)) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -581,16 +581,16 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
|
|
||||||
void onUnlockUser(int userId) {
|
void onUnlockUser(int userId) {
|
||||||
getHandler().post(() -> {
|
getHandler().post(() -> {
|
||||||
final List<RollbackData> rollbacks;
|
final List<Rollback> rollbacks;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
rollbacks = new ArrayList<>(mRollbacks);
|
rollbacks = new ArrayList<>(mRollbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<RollbackData> changed =
|
final Set<Rollback> changed =
|
||||||
mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser(userId, rollbacks);
|
mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser(userId, rollbacks);
|
||||||
|
|
||||||
for (RollbackData rd : changed) {
|
for (Rollback rollback : changed) {
|
||||||
saveRollbackData(rd);
|
saveRollback(rollback);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -613,19 +613,19 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
getHandler().post(() -> {
|
getHandler().post(() -> {
|
||||||
// Check to see if any rollback-enabled staged sessions or staged
|
// Check to see if any rollback-enabled staged sessions or staged
|
||||||
// rollback sessions been applied.
|
// rollback sessions been applied.
|
||||||
List<RollbackData> enabling = new ArrayList<>();
|
List<Rollback> enabling = new ArrayList<>();
|
||||||
List<RollbackData> restoreInProgress = new ArrayList<>();
|
List<Rollback> restoreInProgress = new ArrayList<>();
|
||||||
Set<String> apexPackageNames = new HashSet<>();
|
Set<String> apexPackageNames = new HashSet<>();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (RollbackData data : mRollbacks) {
|
for (Rollback rollback : mRollbacks) {
|
||||||
if (data.isStaged()) {
|
if (rollback.isStaged()) {
|
||||||
if (data.state == RollbackData.ROLLBACK_STATE_ENABLING) {
|
if (rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
|
||||||
enabling.add(data);
|
enabling.add(rollback);
|
||||||
} else if (data.restoreUserDataInProgress) {
|
} else if (rollback.restoreUserDataInProgress) {
|
||||||
restoreInProgress.add(data);
|
restoreInProgress.add(rollback);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
if (info.isApex()) {
|
if (info.isApex()) {
|
||||||
apexPackageNames.add(info.getPackageName());
|
apexPackageNames.add(info.getPackageName());
|
||||||
}
|
}
|
||||||
@@ -634,32 +634,32 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RollbackData data : enabling) {
|
for (Rollback rollback : enabling) {
|
||||||
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
|
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
|
||||||
PackageInstaller.SessionInfo session = installer.getSessionInfo(
|
PackageInstaller.SessionInfo session = installer.getSessionInfo(
|
||||||
data.stagedSessionId);
|
rollback.stagedSessionId);
|
||||||
if (session == null || session.isStagedSessionFailed()) {
|
if (session == null || session.isStagedSessionFailed()) {
|
||||||
// TODO: Do we need to remove this from
|
// TODO: Do we need to remove this from
|
||||||
// mRollbacks, or is it okay to leave as
|
// mRollbacks, or is it okay to leave as
|
||||||
// unavailable until the next reboot when it will go
|
// unavailable until the next reboot when it will go
|
||||||
// away on its own?
|
// away on its own?
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
} else if (session.isStagedSessionApplied()) {
|
} else if (session.isStagedSessionApplied()) {
|
||||||
makeRollbackAvailable(data);
|
makeRollbackAvailable(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RollbackData data : restoreInProgress) {
|
for (Rollback rollback : restoreInProgress) {
|
||||||
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
|
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
|
||||||
PackageInstaller.SessionInfo session = installer.getSessionInfo(
|
PackageInstaller.SessionInfo session = installer.getSessionInfo(
|
||||||
data.stagedSessionId);
|
rollback.stagedSessionId);
|
||||||
// TODO: What if session is null?
|
// TODO: What if session is null?
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
|
if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
data.restoreUserDataInProgress = false;
|
rollback.restoreUserDataInProgress = false;
|
||||||
}
|
}
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,19 +686,19 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
VersionedPackage installedVersion = getInstalledPackageVersion(packageName);
|
VersionedPackage installedVersion = getInstalledPackageVersion(packageName);
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Iterator<RollbackData> iter = mRollbacks.iterator();
|
Iterator<Rollback> iter = mRollbacks.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
RollbackData data = iter.next();
|
Rollback rollback = iter.next();
|
||||||
// TODO: Should we remove rollbacks in the ENABLING state here?
|
// TODO: Should we remove rollbacks in the ENABLING state here?
|
||||||
if (data.state == RollbackData.ROLLBACK_STATE_AVAILABLE
|
if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE
|
||||||
|| data.state == RollbackData.ROLLBACK_STATE_ENABLING) {
|
|| rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
if (info.getPackageName().equals(packageName)
|
if (info.getPackageName().equals(packageName)
|
||||||
&& !packageVersionsEqual(
|
&& !packageVersionsEqual(
|
||||||
info.getVersionRolledBackFrom(),
|
info.getVersionRolledBackFrom(),
|
||||||
installedVersion)) {
|
installedVersion)) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,17 +754,18 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
Instant oldest = null;
|
Instant oldest = null;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Iterator<RollbackData> iter = mRollbacks.iterator();
|
Iterator<Rollback> iter = mRollbacks.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
RollbackData data = iter.next();
|
Rollback rollback = iter.next();
|
||||||
if (data.state != RollbackData.ROLLBACK_STATE_AVAILABLE) {
|
if (rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!now.isBefore(data.timestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
|
if (!now.isBefore(
|
||||||
|
rollback.timestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
} else if (oldest == null || oldest.isAfter(data.timestamp)) {
|
} else if (oldest == null || oldest.isAfter(rollback.timestamp)) {
|
||||||
oldest = data.timestamp;
|
oldest = rollback.timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -871,8 +872,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
// rollback enabled.
|
// rollback enabled.
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback rollback = mRollbacks.get(i);
|
||||||
if (data.apkSessionId == parentSession.getSessionId()) {
|
if (rollback.apkSessionId == parentSession.getSessionId()) {
|
||||||
// This is the apk session for a staged session with rollback enabled. We do not
|
// This is the apk session for a staged session with rollback enabled. We do not
|
||||||
// need to create a new rollback for this session.
|
// need to create a new rollback for this session.
|
||||||
return true;
|
return true;
|
||||||
@@ -893,7 +894,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
newRollback.addToken(token);
|
newRollback.addToken(token);
|
||||||
|
|
||||||
return enableRollbackForPackageSession(newRollback.data, packageSession);
|
return enableRollbackForPackageSession(newRollback.rollback, packageSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -903,7 +904,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
*
|
*
|
||||||
* @return true on success, false on failure.
|
* @return true on success, false on failure.
|
||||||
*/
|
*/
|
||||||
private boolean enableRollbackForPackageSession(RollbackData data,
|
private boolean enableRollbackForPackageSession(Rollback rollback,
|
||||||
PackageInstaller.SessionInfo session) {
|
PackageInstaller.SessionInfo session) {
|
||||||
// TODO: Don't attempt to enable rollback for split installs.
|
// TODO: Don't attempt to enable rollback for split installs.
|
||||||
final int installFlags = session.installFlags;
|
final int installFlags = session.installFlags;
|
||||||
@@ -966,10 +967,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ApplicationInfo appInfo = pkgInfo.applicationInfo;
|
ApplicationInfo appInfo = pkgInfo.applicationInfo;
|
||||||
RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir);
|
RollbackStore.backupPackageCodePath(rollback, packageName, appInfo.sourceDir);
|
||||||
if (!ArrayUtils.isEmpty(appInfo.splitSourceDirs)) {
|
if (!ArrayUtils.isEmpty(appInfo.splitSourceDirs)) {
|
||||||
for (String sourceDir : appInfo.splitSourceDirs) {
|
for (String sourceDir : appInfo.splitSourceDirs) {
|
||||||
RollbackStore.backupPackageCodePath(data, packageName, sourceDir);
|
RollbackStore.backupPackageCodePath(rollback, packageName, sourceDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -978,7 +979,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
data.info.getPackages().add(packageRollbackInfo);
|
rollback.info.getPackages().add(packageRollbackInfo);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1004,16 +1005,16 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// staged installs
|
// staged installs
|
||||||
for (int i = 0; i < mRollbacks.size(); i++) {
|
for (int i = 0; i < mRollbacks.size(); i++) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback rollback = mRollbacks.get(i);
|
||||||
if (data.state != RollbackData.ROLLBACK_STATE_ENABLING) {
|
if (rollback.state != Rollback.ROLLBACK_STATE_ENABLING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
if (info.getPackageName().equals(packageName)) {
|
if (info.getPackageName().equals(packageName)) {
|
||||||
mAppDataRollbackHelper.snapshotAppData(
|
mAppDataRollbackHelper.snapshotAppData(
|
||||||
data.info.getRollbackId(), info, userIds);
|
rollback.info.getRollbackId(), info, userIds);
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1021,11 +1022,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
// non-staged installs
|
// non-staged installs
|
||||||
PackageRollbackInfo info;
|
PackageRollbackInfo info;
|
||||||
for (NewRollback rollback : mNewRollbacks) {
|
for (NewRollback rollback : mNewRollbacks) {
|
||||||
info = getPackageRollbackInfo(rollback.data, packageName);
|
info = getPackageRollbackInfo(rollback.rollback, packageName);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
mAppDataRollbackHelper.snapshotAppData(
|
mAppDataRollbackHelper.snapshotAppData(
|
||||||
rollback.data.info.getRollbackId(), info, userIds);
|
rollback.rollback.info.getRollbackId(), info, userIds);
|
||||||
saveRollbackData(rollback.data);
|
saveRollback(rollback.rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1034,31 +1035,31 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
private void restoreUserDataInternal(String packageName, int[] userIds, int appId,
|
private void restoreUserDataInternal(String packageName, int[] userIds, int appId,
|
||||||
long ceDataInode, String seInfo, int token) {
|
long ceDataInode, String seInfo, int token) {
|
||||||
PackageRollbackInfo info = null;
|
PackageRollbackInfo info = null;
|
||||||
RollbackData rollbackData = null;
|
Rollback rollback = null;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback candidate = mRollbacks.get(i);
|
||||||
if (data.restoreUserDataInProgress) {
|
if (candidate.restoreUserDataInProgress) {
|
||||||
info = getPackageRollbackInfo(data, packageName);
|
info = getPackageRollbackInfo(candidate, packageName);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
rollbackData = data;
|
rollback = candidate;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rollbackData == null) {
|
if (rollback == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int userId : userIds) {
|
for (int userId : userIds) {
|
||||||
final boolean changedRollbackData = mAppDataRollbackHelper.restoreAppData(
|
final boolean changedRollback = mAppDataRollbackHelper.restoreAppData(
|
||||||
rollbackData.info.getRollbackId(), info, userId, appId, seInfo);
|
rollback.info.getRollbackId(), info, userId, appId, seInfo);
|
||||||
|
|
||||||
// We've updated metadata about this rollback, so save it to flash.
|
// We've updated metadata about this rollback, so save it to flash.
|
||||||
if (changedRollbackData) {
|
if (changedRollback) {
|
||||||
saveRollbackData(rollbackData);
|
saveRollback(rollback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1089,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!session.isMultiPackage()) {
|
if (!session.isMultiPackage()) {
|
||||||
if (!enableRollbackForPackageSession(newRollback.data, session)) {
|
if (!enableRollbackForPackageSession(newRollback.rollback, session)) {
|
||||||
Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
|
Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
|
||||||
result.offer(false);
|
result.offer(false);
|
||||||
return;
|
return;
|
||||||
@@ -1102,7 +1103,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
result.offer(false);
|
result.offer(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!enableRollbackForPackageSession(newRollback.data, childSession)) {
|
if (!enableRollbackForPackageSession(newRollback.rollback, childSession)) {
|
||||||
Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
|
Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
|
||||||
result.offer(false);
|
result.offer(false);
|
||||||
return;
|
return;
|
||||||
@@ -1127,20 +1128,20 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
throw new SecurityException("notifyStagedApkSession may only be called by the system.");
|
throw new SecurityException("notifyStagedApkSession may only be called by the system.");
|
||||||
}
|
}
|
||||||
getHandler().post(() -> {
|
getHandler().post(() -> {
|
||||||
RollbackData rd = null;
|
Rollback rollback = null;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback candidate = mRollbacks.get(i);
|
||||||
if (data.stagedSessionId == originalSessionId) {
|
if (candidate.stagedSessionId == originalSessionId) {
|
||||||
data.apkSessionId = apkSessionId;
|
candidate.apkSessionId = apkSessionId;
|
||||||
rd = data;
|
rollback = candidate;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rd != null) {
|
if (rollback != null) {
|
||||||
saveRollbackData(rd);
|
saveRollback(rollback);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1250,7 +1251,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newRollback != null) {
|
if (newRollback != null) {
|
||||||
RollbackData rollback = completeEnableRollback(newRollback, success);
|
Rollback rollback = completeEnableRollback(newRollback, success);
|
||||||
if (rollback != null && !rollback.isStaged()) {
|
if (rollback != null && !rollback.isStaged()) {
|
||||||
makeRollbackAvailable(rollback);
|
makeRollbackAvailable(rollback);
|
||||||
}
|
}
|
||||||
@@ -1263,32 +1264,32 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
* This should be called after rollback has been enabled for all packages
|
* This should be called after rollback has been enabled for all packages
|
||||||
* in the rollback. It does not make the rollback available yet.
|
* in the rollback. It does not make the rollback available yet.
|
||||||
*
|
*
|
||||||
* @return the rollback data for a successfully enable-completed rollback,
|
* @return the Rollback instance for a successfully enable-completed rollback,
|
||||||
* or null on error.
|
* or null on error.
|
||||||
*/
|
*/
|
||||||
private RollbackData completeEnableRollback(NewRollback newRollback, boolean success) {
|
private Rollback completeEnableRollback(NewRollback newRollback, boolean success) {
|
||||||
RollbackData data = newRollback.data;
|
Rollback rollback = newRollback.rollback;
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// The install session was aborted, clean up the pending install.
|
// The install session was aborted, clean up the pending install.
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (newRollback.isCancelled) {
|
if (newRollback.isCancelled) {
|
||||||
Slog.e(TAG, "Rollback has been cancelled by PackageManager");
|
Slog.e(TAG, "Rollback has been cancelled by PackageManager");
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's safe to access data.info outside a synchronized block because
|
// It's safe to access rollback.info outside a synchronized block because
|
||||||
// this is running on the handler thread and all changes to the
|
// this is running on the handler thread and all changes to the
|
||||||
// data.info occur on the handler thread.
|
// rollback.info occur on the handler thread.
|
||||||
if (data.info.getPackages().size() != newRollback.packageSessionIds.length) {
|
if (rollback.info.getPackages().size() != newRollback.packageSessionIds.length) {
|
||||||
Slog.e(TAG, "Failed to enable rollback for all packages in session.");
|
Slog.e(TAG, "Failed to enable rollback for all packages in session.");
|
||||||
deleteRollback(data);
|
deleteRollback(rollback);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// Note: There is a small window of time between when
|
// Note: There is a small window of time between when
|
||||||
// the session has been committed by the package
|
// the session has been committed by the package
|
||||||
@@ -1296,25 +1297,25 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
// here. Presumably the window is small enough that
|
// here. Presumably the window is small enough that
|
||||||
// nobody will want to roll back the newly installed
|
// nobody will want to roll back the newly installed
|
||||||
// package before we make the rollback available.
|
// package before we make the rollback available.
|
||||||
// TODO: We'll lose the rollback data if the
|
// TODO: We'll lose the rollback if the
|
||||||
// device reboots between when the session is
|
// device reboots between when the session is
|
||||||
// committed and this point. Revisit this after
|
// committed and this point. Revisit this after
|
||||||
// adding support for rollback of staged installs.
|
// adding support for rollback of staged installs.
|
||||||
mRollbacks.add(data);
|
mRollbacks.add(rollback);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return rollback;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeRollbackAvailable(RollbackData data) {
|
private void makeRollbackAvailable(Rollback rollback) {
|
||||||
// TODO: What if the rollback has since been expired, for example due
|
// TODO: What if the rollback has since been expired, for example due
|
||||||
// to a new package being installed. Won't this revive an expired
|
// to a new package being installed. Won't this revive an expired
|
||||||
// rollback? Consider adding a ROLLBACK_STATE_EXPIRED to address this.
|
// rollback? Consider adding a ROLLBACK_STATE_EXPIRED to address this.
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
data.state = RollbackData.ROLLBACK_STATE_AVAILABLE;
|
rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
|
||||||
data.timestamp = Instant.now();
|
rollback.timestamp = Instant.now();
|
||||||
}
|
}
|
||||||
saveRollbackData(data);
|
saveRollback(rollback);
|
||||||
|
|
||||||
// TODO(zezeozue): Provide API to explicitly start observing instead
|
// TODO(zezeozue): Provide API to explicitly start observing instead
|
||||||
// of doing this for all rollbacks. If we do this for all rollbacks,
|
// of doing this for all rollbacks. If we do this for all rollbacks,
|
||||||
@@ -1322,8 +1323,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
// After enabling and commiting any rollback, observe packages and
|
// After enabling and commiting any rollback, observe packages and
|
||||||
// prepare to rollback if packages crashes too frequently.
|
// prepare to rollback if packages crashes too frequently.
|
||||||
List<String> packages = new ArrayList<>();
|
List<String> packages = new ArrayList<>();
|
||||||
for (int i = 0; i < data.info.getPackages().size(); i++) {
|
for (int i = 0; i < rollback.info.getPackages().size(); i++) {
|
||||||
packages.add(data.info.getPackages().get(i).getPackageName());
|
packages.add(rollback.info.getPackages().get(i).getPackageName());
|
||||||
}
|
}
|
||||||
mPackageHealthObserver.startObservingHealth(packages,
|
mPackageHealthObserver.startObservingHealth(packages,
|
||||||
mRollbackLifetimeDurationInMillis);
|
mRollbackLifetimeDurationInMillis);
|
||||||
@@ -1331,15 +1332,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the RollbackData, if any, for a rollback with the given
|
* Returns the rollback with the given rollbackId, if any.
|
||||||
* rollbackId.
|
|
||||||
*/
|
*/
|
||||||
private RollbackData getRollbackForId(int rollbackId) {
|
private Rollback getRollbackForId(int rollbackId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = 0; i < mRollbacks.size(); ++i) {
|
for (int i = 0; i < mRollbacks.size(); ++i) {
|
||||||
RollbackData data = mRollbacks.get(i);
|
Rollback rollback = mRollbacks.get(i);
|
||||||
if (data.info.getRollbackId() == rollbackId) {
|
if (rollback.info.getRollbackId() == rollbackId) {
|
||||||
return data;
|
return rollback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1349,11 +1349,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@code PackageRollbackInfo} associated with {@code packageName} from
|
* Returns the {@code PackageRollbackInfo} associated with {@code packageName} from
|
||||||
* a specified {@code RollbackData}.
|
* a specified {@code Rollback}.
|
||||||
*/
|
*/
|
||||||
private static PackageRollbackInfo getPackageRollbackInfo(RollbackData data,
|
private static PackageRollbackInfo getPackageRollbackInfo(Rollback rollback,
|
||||||
String packageName) {
|
String packageName) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
if (info.getPackageName().equals(packageName)) {
|
if (info.getPackageName().equals(packageName)) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -1377,30 +1377,30 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
throw new IllegalStateException("Failed to allocate rollback ID");
|
throw new IllegalStateException("Failed to allocate rollback ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteRollback(RollbackData rollbackData) {
|
private void deleteRollback(Rollback rollback) {
|
||||||
for (PackageRollbackInfo info : rollbackData.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
IntArray snapshottedUsers = info.getSnapshottedUsers();
|
IntArray snapshottedUsers = info.getSnapshottedUsers();
|
||||||
for (int i = 0; i < snapshottedUsers.size(); i++) {
|
for (int i = 0; i < snapshottedUsers.size(); i++) {
|
||||||
int userId = snapshottedUsers.get(i);
|
int userId = snapshottedUsers.get(i);
|
||||||
mAppDataRollbackHelper.destroyAppDataSnapshot(rollbackData.info.getRollbackId(),
|
mAppDataRollbackHelper.destroyAppDataSnapshot(rollback.info.getRollbackId(),
|
||||||
info, userId);
|
info, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mRollbackStore.deleteRollbackData(rollbackData);
|
mRollbackStore.deleteRollback(rollback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves rollback data, swallowing any IOExceptions.
|
* Saves a rollback, swallowing any IOExceptions.
|
||||||
* For those times when it's not obvious what to do about the IOException.
|
* For those times when it's not obvious what to do about the IOException.
|
||||||
* TODO: Double check we can't do a better job handling the IOException in
|
* TODO: Double check we can't do a better job handling the IOException in
|
||||||
* a cases where this method is called.
|
* a cases where this method is called.
|
||||||
*/
|
*/
|
||||||
private void saveRollbackData(RollbackData rollbackData) {
|
private void saveRollback(Rollback rollback) {
|
||||||
try {
|
try {
|
||||||
mRollbackStore.saveRollbackData(rollbackData);
|
mRollbackStore.saveRollback(rollback);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Slog.e(TAG, "Unable to save rollback info for: "
|
Slog.e(TAG, "Unable to save rollback for: "
|
||||||
+ rollbackData.info.getRollbackId(), ioe);
|
+ rollback.info.getRollbackId(), ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1408,14 +1408,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (RollbackData data : mRollbacks) {
|
for (Rollback rollback : mRollbacks) {
|
||||||
RollbackInfo info = data.info;
|
RollbackInfo info = rollback.info;
|
||||||
ipw.println(info.getRollbackId() + ":");
|
ipw.println(info.getRollbackId() + ":");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
ipw.println("-state: " + data.getStateAsString());
|
ipw.println("-state: " + rollback.getStateAsString());
|
||||||
ipw.println("-timestamp: " + data.timestamp);
|
ipw.println("-timestamp: " + rollback.timestamp);
|
||||||
if (data.stagedSessionId != -1) {
|
if (rollback.stagedSessionId != -1) {
|
||||||
ipw.println("-stagedSessionId: " + data.stagedSessionId);
|
ipw.println("-stagedSessionId: " + rollback.stagedSessionId);
|
||||||
}
|
}
|
||||||
ipw.println("-packages:");
|
ipw.println("-packages:");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
@@ -1425,7 +1425,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
+ " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
|
+ " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
|
||||||
}
|
}
|
||||||
ipw.decreaseIndent();
|
ipw.decreaseIndent();
|
||||||
if (data.state == RollbackData.ROLLBACK_STATE_COMMITTED) {
|
if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
|
||||||
ipw.println("-causePackages:");
|
ipw.println("-causePackages:");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
for (VersionedPackage cPkg : info.getCausePackages()) {
|
for (VersionedPackage cPkg : info.getCausePackages()) {
|
||||||
@@ -1451,7 +1451,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class NewRollback {
|
private static class NewRollback {
|
||||||
public final RollbackData data;
|
public final Rollback rollback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This array holds all of the rollback tokens associated with package sessions included
|
* This array holds all of the rollback tokens associated with package sessions included
|
||||||
@@ -1469,9 +1469,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
public final int[] packageSessionIds;
|
public final int[] packageSessionIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to determine whether the RollbackData has been cancelled.
|
* Flag to determine whether the rollback has been cancelled.
|
||||||
*
|
*
|
||||||
* <p>RollbackData could be invalidated and cancelled if RollbackManager receives
|
* <p>Rollback could be invalidated and cancelled if RollbackManager receives
|
||||||
* {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}.
|
* {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}.
|
||||||
*
|
*
|
||||||
* <p>The main underlying assumption here is that if enabling the rollback times out, then
|
* <p>The main underlying assumption here is that if enabling the rollback times out, then
|
||||||
@@ -1481,8 +1481,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
*/
|
*/
|
||||||
public boolean isCancelled = false;
|
public boolean isCancelled = false;
|
||||||
|
|
||||||
NewRollback(RollbackData data, int[] packageSessionIds) {
|
NewRollback(Rollback rollback, int[] packageSessionIds) {
|
||||||
this.data = data;
|
this.rollback = rollback;
|
||||||
this.packageSessionIds = packageSessionIds;
|
this.packageSessionIds = packageSessionIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,13 +1497,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
|
|
||||||
NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) {
|
NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) {
|
||||||
int rollbackId = allocateRollbackIdLocked();
|
int rollbackId = allocateRollbackIdLocked();
|
||||||
final RollbackData data;
|
final Rollback rollback;
|
||||||
int parentSessionId = parentSession.getSessionId();
|
int parentSessionId = parentSession.getSessionId();
|
||||||
|
|
||||||
if (parentSession.isStaged()) {
|
if (parentSession.isStaged()) {
|
||||||
data = mRollbackStore.createStagedRollback(rollbackId, parentSessionId);
|
rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId);
|
||||||
} else {
|
} else {
|
||||||
data = mRollbackStore.createNonStagedRollback(rollbackId);
|
rollback = mRollbackStore.createNonStagedRollback(rollbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] packageSessionIds;
|
int[] packageSessionIds;
|
||||||
@@ -1513,7 +1513,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
packageSessionIds = new int[]{parentSessionId};
|
packageSessionIds = new int[]{parentSessionId};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NewRollback(data, packageSessionIds);
|
return new NewRollback(rollback, packageSessionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1524,10 +1524,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
|
|||||||
NewRollback getNewRollbackForPackageSessionLocked(int packageSessionId) {
|
NewRollback getNewRollbackForPackageSessionLocked(int packageSessionId) {
|
||||||
// We expect mNewRollbacks to be a very small list; linear search
|
// We expect mNewRollbacks to be a very small list; linear search
|
||||||
// should be plenty fast.
|
// should be plenty fast.
|
||||||
for (NewRollback newRollbackData : mNewRollbacks) {
|
for (NewRollback newRollback: mNewRollbacks) {
|
||||||
for (int id : newRollbackData.packageSessionIds) {
|
for (int id : newRollback.packageSessionIds) {
|
||||||
if (id == packageSessionId) {
|
if (id == packageSessionId) {
|
||||||
return newRollbackData;
|
return newRollback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.rollback;
|
package com.android.server.rollback;
|
||||||
|
|
||||||
import static com.android.server.rollback.RollbackData.rollbackStateFromString;
|
import static com.android.server.rollback.Rollback.rollbackStateFromString;
|
||||||
import static com.android.server.rollback.RollbackData.rollbackStateToString;
|
import static com.android.server.rollback.Rollback.rollbackStateToString;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.pm.VersionedPackage;
|
import android.content.pm.VersionedPackage;
|
||||||
@@ -73,17 +73,17 @@ class RollbackStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the rollback data from persistent storage.
|
* Reads the rollbacks from persistent storage.
|
||||||
*/
|
*/
|
||||||
List<RollbackData> loadAllRollbackData() {
|
List<Rollback> loadRollbacks() {
|
||||||
List<RollbackData> rollbacks = new ArrayList<>();
|
List<Rollback> rollbacks = new ArrayList<>();
|
||||||
mRollbackDataDir.mkdirs();
|
mRollbackDataDir.mkdirs();
|
||||||
for (File rollbackDir : mRollbackDataDir.listFiles()) {
|
for (File rollbackDir : mRollbackDataDir.listFiles()) {
|
||||||
if (rollbackDir.isDirectory()) {
|
if (rollbackDir.isDirectory()) {
|
||||||
try {
|
try {
|
||||||
rollbacks.add(loadRollbackData(rollbackDir));
|
rollbacks.add(loadRollback(rollbackDir));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "Unable to read rollback data at " + rollbackDir, e);
|
Slog.e(TAG, "Unable to read rollback at " + rollbackDir, e);
|
||||||
removeFile(rollbackDir);
|
removeFile(rollbackDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,21 +191,21 @@ class RollbackStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new RollbackData instance for a non-staged rollback with
|
* Creates a new Rollback instance for a non-staged rollback with
|
||||||
* backupDir assigned.
|
* backupDir assigned.
|
||||||
*/
|
*/
|
||||||
RollbackData createNonStagedRollback(int rollbackId) {
|
Rollback createNonStagedRollback(int rollbackId) {
|
||||||
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
|
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
|
||||||
return new RollbackData(rollbackId, backupDir, -1);
|
return new Rollback(rollbackId, backupDir, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new RollbackData instance for a staged rollback with
|
* Creates a new Rollback instance for a staged rollback with
|
||||||
* backupDir assigned.
|
* backupDir assigned.
|
||||||
*/
|
*/
|
||||||
RollbackData createStagedRollback(int rollbackId, int stagedSessionId) {
|
Rollback createStagedRollback(int rollbackId, int stagedSessionId) {
|
||||||
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
|
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
|
||||||
return new RollbackData(rollbackId, backupDir, stagedSessionId);
|
return new Rollback(rollbackId, backupDir, stagedSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -213,10 +213,10 @@ class RollbackStore {
|
|||||||
* For packages containing splits, this method should be called for each
|
* For packages containing splits, this method should be called for each
|
||||||
* of the package's split apks in addition to the base apk.
|
* of the package's split apks in addition to the base apk.
|
||||||
*/
|
*/
|
||||||
static void backupPackageCodePath(RollbackData data, String packageName, String codePath)
|
static void backupPackageCodePath(Rollback rollback, String packageName, String codePath)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
File sourceFile = new File(codePath);
|
File sourceFile = new File(codePath);
|
||||||
File targetDir = new File(data.backupDir, packageName);
|
File targetDir = new File(rollback.backupDir, packageName);
|
||||||
targetDir.mkdirs();
|
targetDir.mkdirs();
|
||||||
File targetFile = new File(targetDir, sourceFile.getName());
|
File targetFile = new File(targetDir, sourceFile.getName());
|
||||||
|
|
||||||
@@ -228,8 +228,8 @@ class RollbackStore {
|
|||||||
* Returns the apk or apex files backed up for the given package.
|
* Returns the apk or apex files backed up for the given package.
|
||||||
* Includes the base apk and any splits. Returns null if none found.
|
* Includes the base apk and any splits. Returns null if none found.
|
||||||
*/
|
*/
|
||||||
static File[] getPackageCodePaths(RollbackData data, String packageName) {
|
static File[] getPackageCodePaths(Rollback rollback, String packageName) {
|
||||||
File targetDir = new File(data.backupDir, packageName);
|
File targetDir = new File(rollback.backupDir, packageName);
|
||||||
File[] files = targetDir.listFiles();
|
File[] files = targetDir.listFiles();
|
||||||
if (files == null || files.length == 0) {
|
if (files == null || files.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
@@ -241,27 +241,27 @@ class RollbackStore {
|
|||||||
* Deletes all backed up apks and apex files associated with the given
|
* Deletes all backed up apks and apex files associated with the given
|
||||||
* rollback.
|
* rollback.
|
||||||
*/
|
*/
|
||||||
static void deletePackageCodePaths(RollbackData data) {
|
static void deletePackageCodePaths(Rollback rollback) {
|
||||||
for (PackageRollbackInfo info : data.info.getPackages()) {
|
for (PackageRollbackInfo info : rollback.info.getPackages()) {
|
||||||
File targetDir = new File(data.backupDir, info.getPackageName());
|
File targetDir = new File(rollback.backupDir, info.getPackageName());
|
||||||
removeFile(targetDir);
|
removeFile(targetDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the rollback data to persistent storage.
|
* Saves the given rollback to persistent storage.
|
||||||
*/
|
*/
|
||||||
void saveRollbackData(RollbackData data) throws IOException {
|
void saveRollback(Rollback rollback) throws IOException {
|
||||||
try {
|
try {
|
||||||
JSONObject dataJson = new JSONObject();
|
JSONObject dataJson = new JSONObject();
|
||||||
dataJson.put("info", rollbackInfoToJson(data.info));
|
dataJson.put("info", rollbackInfoToJson(rollback.info));
|
||||||
dataJson.put("timestamp", data.timestamp.toString());
|
dataJson.put("timestamp", rollback.timestamp.toString());
|
||||||
dataJson.put("stagedSessionId", data.stagedSessionId);
|
dataJson.put("stagedSessionId", rollback.stagedSessionId);
|
||||||
dataJson.put("state", rollbackStateToString(data.state));
|
dataJson.put("state", rollbackStateToString(rollback.state));
|
||||||
dataJson.put("apkSessionId", data.apkSessionId);
|
dataJson.put("apkSessionId", rollback.apkSessionId);
|
||||||
dataJson.put("restoreUserDataInProgress", data.restoreUserDataInProgress);
|
dataJson.put("restoreUserDataInProgress", rollback.restoreUserDataInProgress);
|
||||||
|
|
||||||
PrintWriter pw = new PrintWriter(new File(data.backupDir, "rollback.json"));
|
PrintWriter pw = new PrintWriter(new File(rollback.backupDir, "rollback.json"));
|
||||||
pw.println(dataJson.toString());
|
pw.println(dataJson.toString());
|
||||||
pw.close();
|
pw.close();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
@@ -270,23 +270,23 @@ class RollbackStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all persistant storage associated with the given rollback data.
|
* Removes all persistent storage associated with the given rollback.
|
||||||
*/
|
*/
|
||||||
void deleteRollbackData(RollbackData data) {
|
void deleteRollback(Rollback rollback) {
|
||||||
removeFile(data.backupDir);
|
removeFile(rollback.backupDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the metadata for a rollback from the given directory.
|
* Reads the metadata for a rollback from the given directory.
|
||||||
* @throws IOException in case of error reading the data.
|
* @throws IOException in case of error reading the data.
|
||||||
*/
|
*/
|
||||||
private static RollbackData loadRollbackData(File backupDir) throws IOException {
|
private static Rollback loadRollback(File backupDir) throws IOException {
|
||||||
try {
|
try {
|
||||||
File rollbackJsonFile = new File(backupDir, "rollback.json");
|
File rollbackJsonFile = new File(backupDir, "rollback.json");
|
||||||
JSONObject dataJson = new JSONObject(
|
JSONObject dataJson = new JSONObject(
|
||||||
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
|
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
|
||||||
|
|
||||||
return new RollbackData(
|
return new Rollback(
|
||||||
rollbackInfoFromJson(dataJson.getJSONObject("info")),
|
rollbackInfoFromJson(dataJson.getJSONObject("info")),
|
||||||
backupDir,
|
backupDir,
|
||||||
Instant.parse(dataJson.getString("timestamp")),
|
Instant.parse(dataJson.getString("timestamp")),
|
||||||
|
|||||||
@@ -235,22 +235,22 @@ public class AppDataRollbackHelperTest {
|
|||||||
wasRecentlyRestored.getPendingRestores().add(
|
wasRecentlyRestored.getPendingRestores().add(
|
||||||
new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo"));
|
new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo"));
|
||||||
|
|
||||||
RollbackData dataWithPendingBackup = new RollbackData(101, new File("/does/not/exist"), -1);
|
Rollback dataWithPendingBackup = new Rollback(101, new File("/does/not/exist"), -1);
|
||||||
dataWithPendingBackup.info.getPackages().add(pendingBackup);
|
dataWithPendingBackup.info.getPackages().add(pendingBackup);
|
||||||
|
|
||||||
RollbackData dataWithRecentRestore = new RollbackData(17239, new File("/does/not/exist"),
|
Rollback dataWithRecentRestore = new Rollback(17239, new File("/does/not/exist"),
|
||||||
-1);
|
-1);
|
||||||
dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored);
|
dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored);
|
||||||
|
|
||||||
RollbackData dataForDifferentUser = new RollbackData(17239, new File("/does/not/exist"),
|
Rollback dataForDifferentUser = new Rollback(17239, new File("/does/not/exist"),
|
||||||
-1);
|
-1);
|
||||||
dataForDifferentUser.info.getPackages().add(ignoredInfo);
|
dataForDifferentUser.info.getPackages().add(ignoredInfo);
|
||||||
|
|
||||||
RollbackData dataForRestore = new RollbackData(17239, new File("/does/not/exist"), -1);
|
Rollback dataForRestore = new Rollback(17239, new File("/does/not/exist"), -1);
|
||||||
dataForRestore.info.getPackages().add(pendingRestore);
|
dataForRestore.info.getPackages().add(pendingRestore);
|
||||||
dataForRestore.info.getPackages().add(wasRecentlyRestored);
|
dataForRestore.info.getPackages().add(wasRecentlyRestored);
|
||||||
|
|
||||||
Set<RollbackData> changed = helper.commitPendingBackupAndRestoreForUser(37,
|
Set<Rollback> changed = helper.commitPendingBackupAndRestoreForUser(37,
|
||||||
Arrays.asList(dataWithPendingBackup, dataWithRecentRestore, dataForDifferentUser,
|
Arrays.asList(dataWithPendingBackup, dataWithRecentRestore, dataForDifferentUser,
|
||||||
dataForRestore));
|
dataForRestore));
|
||||||
InOrder inOrder = Mockito.inOrder(installer);
|
InOrder inOrder = Mockito.inOrder(installer);
|
||||||
@@ -265,7 +265,7 @@ public class AppDataRollbackHelperTest {
|
|||||||
assertEquals(-1, pendingBackup.getPendingBackups().indexOf(37));
|
assertEquals(-1, pendingBackup.getPendingBackups().indexOf(37));
|
||||||
assertEquals(53, pendingBackup.getCeSnapshotInodes().get(37));
|
assertEquals(53, pendingBackup.getCeSnapshotInodes().get(37));
|
||||||
|
|
||||||
// Check that changed returns correct RollbackData.
|
// Check that changed returns correct Rollback.
|
||||||
assertEquals(3, changed.size());
|
assertEquals(3, changed.size());
|
||||||
assertTrue(changed.contains(dataWithPendingBackup));
|
assertTrue(changed.contains(dataWithPendingBackup));
|
||||||
assertTrue(changed.contains(dataWithRecentRestore));
|
assertTrue(changed.contains(dataWithRecentRestore));
|
||||||
|
|||||||
Reference in New Issue
Block a user