summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/rollback/AppDataRollbackHelper.java8
-rw-r--r--services/core/java/com/android/server/rollback/Rollback.java547
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java338
-rw-r--r--services/core/java/com/android/server/rollback/RollbackStore.java2
4 files changed, 461 insertions, 434 deletions
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index a9f44b9bbeb1..1123f70b4334 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -51,7 +51,7 @@ public class AppDataRollbackHelper {
* {@code userIds}. Updates said {@code packageRollbackInfo} with the inodes of the CE user data
* snapshot folders.
*/
- @GuardedBy("rollback.getLock")
+ @GuardedBy("rollback.mLock")
// TODO(b/136241838): Move into Rollback and synchronize there.
public void snapshotAppData(
int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
@@ -88,7 +88,7 @@ public class AppDataRollbackHelper {
* to {@code packageRollbackInfo} are restricted to the removal or addition of {@code
* userId} to the list of pending backups or restores.
*/
- @GuardedBy("rollback.getLock")
+ @GuardedBy("rollback.mLock")
// TODO(b/136241838): Move into Rollback and synchronize there.
public boolean restoreAppData(int rollbackId, PackageRollbackInfo packageRollbackInfo,
int userId, int appId, String seInfo) {
@@ -133,7 +133,7 @@ public class AppDataRollbackHelper {
* Deletes an app data snapshot with a given {@code rollbackId} for a specified package
* {@code packageName} for a given {@code user}.
*/
- @GuardedBy("rollback.getLock")
+ @GuardedBy("rollback.mLock")
// TODO(b/136241838): Move into Rollback and synchronize there.
public void destroyAppDataSnapshot(int rollbackId, PackageRollbackInfo packageRollbackInfo,
int user) {
@@ -162,7 +162,7 @@ public class AppDataRollbackHelper {
*
* @return true if any backups or restores were found for the userId
*/
- @GuardedBy("rollback.getLock")
+ @GuardedBy("rollback.mLock")
boolean commitPendingBackupAndRestoreForUser(int userId, Rollback rollback) {
boolean foundBackupOrRestore = false;
for (PackageRollbackInfo info : rollback.info.getPackages()) {
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 78b8b2e78772..1cf07cb47f2f 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -40,6 +40,7 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
import java.io.File;
import java.io.IOException;
@@ -53,11 +54,6 @@ import java.util.List;
/**
* Information about a rollback available for a set of atomically installed packages.
- *
- * <p>When accessing the state of a Rollback object, the caller is responsible for synchronization.
- * The lock object provided by {@link #getLock} should be acquired when accessing any of the mutable
- * state of a Rollback, including from the {@link RollbackInfo} and any of the
- * {@link PackageRollbackInfo} objects held within.
*/
class Rollback {
@@ -101,11 +97,7 @@ class Rollback {
/**
* The rollback info for this rollback.
- *
- * <p>Any access to this field that touches any mutable state should be synchronized on
- * {@link #getLock}.
*/
- @GuardedBy("getLock")
public final RollbackInfo info;
/**
@@ -146,8 +138,6 @@ class Rollback {
/**
* Lock object to guard all access to Rollback state.
- *
- * @see #getLock
*/
private final Object mLock = new Object();
@@ -185,23 +175,8 @@ class Rollback {
}
/**
- * Returns a lock object that should be acquired before accessing any Rollback state from
- * {@link RollbackManagerServiceImpl}.
- *
- * <p>Note that while holding this lock, the lock for {@link RollbackManagerServiceImpl} should
- * not be acquired (but it is ok to acquire this lock while already holding the lock for that
- * class).
- */
- // TODO(b/136241838): Move rollback functionality into this class and synchronize on the lock
- // internally. Remove this method once this has been done for all cases.
- Object getLock() {
- return mLock;
- }
-
- /**
* Whether the rollback is for rollback of a staged install.
*/
- @GuardedBy("getLock")
boolean isStaged() {
return info.isStaged();
}
@@ -216,17 +191,20 @@ class Rollback {
/**
* Returns the time when the upgrade occurred, for purposes of expiring rollback data.
*/
- @GuardedBy("getLock")
Instant getTimestamp() {
- return mTimestamp;
+ synchronized (mLock) {
+ return mTimestamp;
+ }
}
/**
* Sets the time at which upgrade occurred.
*/
- @GuardedBy("getLock")
void setTimestamp(Instant timestamp) {
- mTimestamp = timestamp;
+ synchronized (mLock) {
+ mTimestamp = timestamp;
+ RollbackStore.saveRollback(this);
+ }
}
/**
@@ -240,33 +218,46 @@ class Rollback {
/**
* Returns true if the rollback is in the ENABLING state.
*/
- @GuardedBy("getLock")
boolean isEnabling() {
- return mState == ROLLBACK_STATE_ENABLING;
+ synchronized (mLock) {
+ return mState == ROLLBACK_STATE_ENABLING;
+ }
}
/**
* Returns true if the rollback is in the AVAILABLE state.
*/
- @GuardedBy("getLock")
boolean isAvailable() {
- return mState == ROLLBACK_STATE_AVAILABLE;
+ synchronized (mLock) {
+ return mState == ROLLBACK_STATE_AVAILABLE;
+ }
}
/**
* Returns true if the rollback is in the COMMITTED state.
*/
- @GuardedBy("getLock")
boolean isCommitted() {
- return mState == ROLLBACK_STATE_COMMITTED;
+ synchronized (mLock) {
+ return mState == ROLLBACK_STATE_COMMITTED;
+ }
}
/**
* Returns true if the rollback is in the DELETED state.
*/
- @GuardedBy("getLock")
boolean isDeleted() {
- return mState == ROLLBACK_STATE_DELETED;
+ synchronized (mLock) {
+ return mState == ROLLBACK_STATE_DELETED;
+ }
+ }
+
+ /**
+ * Saves this rollback to persistent storage.
+ */
+ void saveRollback() {
+ synchronized (mLock) {
+ RollbackStore.saveRollback(this);
+ }
}
/**
@@ -274,7 +265,6 @@ class Rollback {
*
* @return boolean True if the rollback was enabled successfully for the specified package.
*/
- @GuardedBy("getLock")
boolean enableForPackage(String packageName, long newVersion, long installedVersion,
boolean isApex, String sourceDir, String[] splitSourceDirs) {
try {
@@ -295,7 +285,9 @@ class Rollback {
new IntArray() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */);
- info.getPackages().add(packageRollbackInfo);
+ synchronized (mLock) {
+ info.getPackages().add(packageRollbackInfo);
+ }
return true;
}
@@ -304,19 +296,33 @@ class Rollback {
* Snapshots user data for the provided package and user ids. Does nothing if this rollback is
* not in the ENABLING state.
*/
- @GuardedBy("getLock")
void snapshotUserData(String packageName, int[] userIds, AppDataRollbackHelper dataHelper) {
- if (!isEnabling()) {
- return;
- }
+ synchronized (mLock) {
+ if (!isEnabling()) {
+ return;
+ }
+
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ if (pkgRollbackInfo.getPackageName().equals(packageName)) {
+ dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds);
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- if (pkgRollbackInfo.getPackageName().equals(packageName)) {
- dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds);
+ RollbackStore.saveRollback(this);
+ pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
+ break;
+ }
+ }
+ }
+ }
+ /**
+ * Commits the pending backups and restores for a given {@code userId}. If this rollback has a
+ * pending backup, it is updated with a mapping from {@code userId} to inode of the CE user data
+ * snapshot.
+ */
+ void commitPendingBackupAndRestoreForUser(int userId, AppDataRollbackHelper dataHelper) {
+ synchronized (mLock) {
+ if (dataHelper.commitPendingBackupAndRestoreForUser(userId, this)) {
RollbackStore.saveRollback(this);
- pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
- break;
}
}
}
@@ -326,168 +332,170 @@ class Rollback {
* current time and saves the rollback. Does nothing if this rollback is already in the
* DELETED state.
*/
- @GuardedBy("getLock")
void makeAvailable() {
- if (isDeleted()) {
- Slog.w(TAG, "Cannot make deleted rollback available.");
- return;
+ synchronized (mLock) {
+ if (isDeleted()) {
+ Slog.w(TAG, "Cannot make deleted rollback available.");
+ return;
+ }
+ mState = ROLLBACK_STATE_AVAILABLE;
+ mTimestamp = Instant.now();
+ RollbackStore.saveRollback(this);
}
- mState = ROLLBACK_STATE_AVAILABLE;
- mTimestamp = Instant.now();
- RollbackStore.saveRollback(this);
}
/**
* Commits the rollback.
*/
- @GuardedBy("getLock")
void commit(final Context context, List<VersionedPackage> causePackages,
String callerPackageName, IntentSender statusReceiver) {
-
- if (!isAvailable()) {
- sendFailure(context, statusReceiver,
- RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
- "Rollback unavailable");
- return;
- }
-
- // Get a context to use to install the downgraded version of the package.
- Context pkgContext;
- try {
- pkgContext = context.createPackageContext(callerPackageName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
- "Invalid callerPackageName");
- return;
- }
-
- PackageManager pm = pkgContext.getPackageManager();
- try {
- PackageInstaller packageInstaller = pm.getPackageInstaller();
- PackageInstaller.SessionParams parentParams = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- parentParams.setRequestDowngrade(true);
- parentParams.setMultiPackage();
- if (isStaged()) {
- parentParams.setStaged();
+ synchronized (mLock) {
+ if (!isAvailable()) {
+ sendFailure(context, statusReceiver,
+ RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
+ "Rollback unavailable");
+ return;
}
- int parentSessionId = packageInstaller.createSession(parentParams);
- PackageInstaller.Session parentSession = packageInstaller.openSession(
- parentSessionId);
+ // Get a context to use to install the downgraded version of the package.
+ Context pkgContext;
+ try {
+ pkgContext = context.createPackageContext(callerPackageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
+ "Invalid callerPackageName");
+ return;
+ }
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageManager pm = pkgContext.getPackageManager();
+ try {
+ PackageInstaller packageInstaller = pm.getPackageInstaller();
+ PackageInstaller.SessionParams parentParams = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- // TODO: We can't get the installerPackageName for apex
- // (b/123920130). Is it okay to ignore the installer package
- // for apex?
- if (!pkgRollbackInfo.isApex()) {
- String installerPackageName =
- pm.getInstallerPackageName(pkgRollbackInfo.getPackageName());
- if (installerPackageName != null) {
- params.setInstallerPackageName(installerPackageName);
- }
- }
- params.setRequestDowngrade(true);
- params.setRequiredInstalledVersionCode(
- pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode());
+ parentParams.setRequestDowngrade(true);
+ parentParams.setMultiPackage();
if (isStaged()) {
- params.setStaged();
- }
- if (pkgRollbackInfo.isApex()) {
- params.setInstallAsApex();
- }
- int sessionId = packageInstaller.createSession(params);
- PackageInstaller.Session session = packageInstaller.openSession(sessionId);
- File[] packageCodePaths = RollbackStore.getPackageCodePaths(
- this, pkgRollbackInfo.getPackageName());
- if (packageCodePaths == null) {
- sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
- "Backup copy of package inaccessible");
- return;
+ parentParams.setStaged();
}
- for (File packageCodePath : packageCodePaths) {
- try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(packageCodePath,
- ParcelFileDescriptor.MODE_READ_ONLY)) {
- final long token = Binder.clearCallingIdentity();
- try {
- session.write(packageCodePath.getName(), 0,
- packageCodePath.length(),
- fd);
- } finally {
- Binder.restoreCallingIdentity(token);
+ int parentSessionId = packageInstaller.createSession(parentParams);
+ PackageInstaller.Session parentSession = packageInstaller.openSession(
+ parentSessionId);
+
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+ // TODO: We can't get the installerPackageName for apex
+ // (b/123920130). Is it okay to ignore the installer package
+ // for apex?
+ if (!pkgRollbackInfo.isApex()) {
+ String installerPackageName =
+ pm.getInstallerPackageName(pkgRollbackInfo.getPackageName());
+ if (installerPackageName != null) {
+ params.setInstallerPackageName(installerPackageName);
}
}
- }
- parentSession.addChildSessionId(sessionId);
- }
+ params.setRequestDowngrade(true);
+ params.setRequiredInstalledVersionCode(
+ pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode());
+ if (isStaged()) {
+ params.setStaged();
+ }
+ if (pkgRollbackInfo.isApex()) {
+ params.setInstallAsApex();
+ }
+ int sessionId = packageInstaller.createSession(params);
+ PackageInstaller.Session session = packageInstaller.openSession(sessionId);
+ File[] packageCodePaths = RollbackStore.getPackageCodePaths(
+ this, pkgRollbackInfo.getPackageName());
+ if (packageCodePaths == null) {
+ sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
+ "Backup copy of package inaccessible");
+ return;
+ }
- final LocalIntentReceiver receiver = new LocalIntentReceiver(
- (Intent result) -> {
- int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
- if (status != PackageInstaller.STATUS_SUCCESS) {
- // Committing the rollback failed, but we still have all the info we
- // need to try rolling back again, so restore the rollback state to how
- // it was before we tried committing.
- // TODO: Should we just kill this rollback if commit failed?
- // Why would we expect commit not to fail again?
- // TODO: Could this cause a rollback to be resurrected
- // if it should otherwise have expired by now?
- synchronized (mLock) {
- mState = ROLLBACK_STATE_AVAILABLE;
- mRestoreUserDataInProgress = false;
+ for (File packageCodePath : packageCodePaths) {
+ try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(packageCodePath,
+ ParcelFileDescriptor.MODE_READ_ONLY)) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ session.write(packageCodePath.getName(), 0,
+ packageCodePath.length(),
+ fd);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- sendFailure(context, statusReceiver,
- RollbackManager.STATUS_FAILURE_INSTALL,
- "Rollback downgrade install failed: "
- + result.getStringExtra(
- PackageInstaller.EXTRA_STATUS_MESSAGE));
- return;
}
+ }
+ parentSession.addChildSessionId(sessionId);
+ }
- synchronized (mLock) {
- if (!isStaged()) {
- // All calls to restoreUserData should have
- // completed by now for a non-staged install.
- mRestoreUserDataInProgress = false;
+ final LocalIntentReceiver receiver = new LocalIntentReceiver(
+ (Intent result) -> {
+ int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+ if (status != PackageInstaller.STATUS_SUCCESS) {
+ // Committing the rollback failed, but we still have all the info we
+ // need to try rolling back again, so restore the rollback state to
+ // how it was before we tried committing.
+ // TODO: Should we just kill this rollback if commit failed?
+ // Why would we expect commit not to fail again?
+ // TODO: Could this cause a rollback to be resurrected
+ // if it should otherwise have expired by now?
+ synchronized (mLock) {
+ mState = ROLLBACK_STATE_AVAILABLE;
+ mRestoreUserDataInProgress = false;
+ }
+ sendFailure(context, statusReceiver,
+ RollbackManager.STATUS_FAILURE_INSTALL,
+ "Rollback downgrade install failed: "
+ + result.getStringExtra(
+ PackageInstaller.EXTRA_STATUS_MESSAGE));
+ return;
}
- info.setCommittedSessionId(parentSessionId);
- info.getCausePackages().addAll(causePackages);
- RollbackStore.deletePackageCodePaths(this);
- RollbackStore.saveRollback(this);
- }
+ synchronized (mLock) {
+ if (!isStaged()) {
+ // All calls to restoreUserData should have
+ // completed by now for a non-staged install.
+ mRestoreUserDataInProgress = false;
+ }
+
+ info.setCommittedSessionId(parentSessionId);
+ info.getCausePackages().addAll(causePackages);
+ RollbackStore.deletePackageCodePaths(this);
+ RollbackStore.saveRollback(this);
+ }
- // Send success.
- try {
- final Intent fillIn = new Intent();
- fillIn.putExtra(
- RollbackManager.EXTRA_STATUS, RollbackManager.STATUS_SUCCESS);
- statusReceiver.sendIntent(context, 0, fillIn, null, null);
- } catch (IntentSender.SendIntentException e) {
- // Nowhere to send the result back to, so don't bother.
- }
+ // Send success.
+ try {
+ final Intent fillIn = new Intent();
+ fillIn.putExtra(
+ RollbackManager.EXTRA_STATUS,
+ RollbackManager.STATUS_SUCCESS);
+ statusReceiver.sendIntent(context, 0, fillIn, null, null);
+ } catch (IntentSender.SendIntentException e) {
+ // Nowhere to send the result back to, so don't bother.
+ }
- Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
+ Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
- for (UserInfo userInfo : UserManager.get(context).getUsers(true)) {
- context.sendBroadcastAsUser(broadcast,
- userInfo.getUserHandle(),
- Manifest.permission.MANAGE_ROLLBACKS);
+ for (UserInfo userInfo : UserManager.get(context).getUsers(true)) {
+ context.sendBroadcastAsUser(broadcast,
+ userInfo.getUserHandle(),
+ Manifest.permission.MANAGE_ROLLBACKS);
+ }
}
- }
- );
-
- mState = ROLLBACK_STATE_COMMITTED;
- mRestoreUserDataInProgress = true;
- parentSession.commit(receiver.getIntentSender());
- } catch (IOException e) {
- Slog.e(TAG, "Rollback failed", e);
- sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
- "IOException: " + e.toString());
+ );
+
+ mState = ROLLBACK_STATE_COMMITTED;
+ mRestoreUserDataInProgress = true;
+ parentSession.commit(receiver.getIntentSender());
+ } catch (IOException e) {
+ Slog.e(TAG, "Rollback failed", e);
+ sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE,
+ "IOException: " + e.toString());
+ }
}
}
@@ -498,138 +506,156 @@ class Rollback {
* @return boolean True if this rollback has a restore in progress and contains the specified
* package.
*/
- @GuardedBy("getLock")
boolean restoreUserDataForPackageIfInProgress(String packageName, int[] userIds, int appId,
String seInfo, AppDataRollbackHelper dataHelper) {
- if (!isRestoreUserDataInProgress()) {
- return false;
- }
+ synchronized (mLock) {
+ if (!isRestoreUserDataInProgress()) {
+ return false;
+ }
- boolean foundPackage = false;
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- if (pkgRollbackInfo.getPackageName().equals(packageName)) {
- foundPackage = true;
- boolean changedRollback = false;
- for (int userId : userIds) {
- changedRollback |= dataHelper.restoreAppData(
- info.getRollbackId(), pkgRollbackInfo, userId, appId, seInfo);
- }
- // We've updated metadata about this rollback, so save it to flash.
- if (changedRollback) {
- RollbackStore.saveRollback(this);
+ boolean foundPackage = false;
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ if (pkgRollbackInfo.getPackageName().equals(packageName)) {
+ foundPackage = true;
+ boolean changedRollback = false;
+ for (int userId : userIds) {
+ changedRollback |= dataHelper.restoreAppData(
+ info.getRollbackId(), pkgRollbackInfo, userId, appId, seInfo);
+ }
+ // We've updated metadata about this rollback, so save it to flash.
+ if (changedRollback) {
+ RollbackStore.saveRollback(this);
+ }
+ break;
}
- break;
}
+ return foundPackage;
}
- return foundPackage;
}
/**
* Deletes app data snapshots associated with this rollback, and moves to the DELETED state.
*/
- @GuardedBy("getLock")
void delete(AppDataRollbackHelper dataHelper) {
- for (PackageRollbackInfo pkgInfo : info.getPackages()) {
- IntArray snapshottedUsers = pkgInfo.getSnapshottedUsers();
- for (int i = 0; i < snapshottedUsers.size(); i++) {
- // Destroy app data snapshot.
- int userId = snapshottedUsers.get(i);
-
- dataHelper.destroyAppDataSnapshot(info.getRollbackId(), pkgInfo, userId);
+ synchronized (mLock) {
+ for (PackageRollbackInfo pkgInfo : info.getPackages()) {
+ IntArray snapshottedUsers = pkgInfo.getSnapshottedUsers();
+ for (int i = 0; i < snapshottedUsers.size(); i++) {
+ // Destroy app data snapshot.
+ int userId = snapshottedUsers.get(i);
+
+ dataHelper.destroyAppDataSnapshot(info.getRollbackId(), pkgInfo, userId);
+ }
}
- }
- RollbackStore.deleteRollback(this);
- mState = ROLLBACK_STATE_DELETED;
+ RollbackStore.deleteRollback(this);
+ mState = ROLLBACK_STATE_DELETED;
+ }
}
/**
* Returns the id of the post-reboot apk session for a staged install, if any.
*/
- @GuardedBy("getLock")
int getApkSessionId() {
- return mApkSessionId;
+ synchronized (mLock) {
+ return mApkSessionId;
+ }
}
/**
* Sets the id of the post-reboot apk session for a staged install.
*/
- @GuardedBy("getLock")
void setApkSessionId(int apkSessionId) {
- mApkSessionId = apkSessionId;
+ synchronized (mLock) {
+ mApkSessionId = apkSessionId;
+ RollbackStore.saveRollback(this);
+ }
}
/**
* Returns true if we are expecting the package manager to call restoreUserData for this
* rollback because it has just been committed but the rollback has not yet been fully applied.
*/
- @GuardedBy("getLock")
boolean isRestoreUserDataInProgress() {
- return mRestoreUserDataInProgress;
+ synchronized (mLock) {
+ return mRestoreUserDataInProgress;
+ }
}
/**
* Sets whether we are expecting the package manager to call restoreUserData for this
* rollback because it has just been committed but the rollback has not yet been fully applied.
*/
- @GuardedBy("getLock")
void setRestoreUserDataInProgress(boolean restoreUserDataInProgress) {
- mRestoreUserDataInProgress = restoreUserDataInProgress;
+ synchronized (mLock) {
+ mRestoreUserDataInProgress = restoreUserDataInProgress;
+ RollbackStore.saveRollback(this);
+ }
}
/**
* Returns true if this rollback includes the package with the provided {@code packageName}.
*/
- @GuardedBy("getLock")
boolean includesPackage(String packageName) {
- for (PackageRollbackInfo packageRollbackInfo : info.getPackages()) {
- if (packageRollbackInfo.getPackageName().equals(packageName)) {
- return true;
+ synchronized (mLock) {
+ for (PackageRollbackInfo packageRollbackInfo : info.getPackages()) {
+ if (packageRollbackInfo.getPackageName().equals(packageName)) {
+ return true;
+ }
}
+ return false;
}
- return false;
}
/**
* Returns true if this rollback includes the package with the provided {@code packageName}
* with a <i>version rolled back from</i> that is not {@code versionCode}.
*/
- @GuardedBy("getLock")
boolean includesPackageWithDifferentVersion(String packageName, long versionCode) {
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- if (pkgRollbackInfo.getPackageName().equals(packageName)
- && pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()
- != versionCode) {
- return true;
+ synchronized (mLock) {
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ if (pkgRollbackInfo.getPackageName().equals(packageName)
+ && pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()
+ != versionCode) {
+ return true;
+ }
}
+ return false;
}
- return false;
}
/**
* Returns a list containing the names of all the packages included in this rollback.
*/
- @GuardedBy("getLock")
List<String> getPackageNames() {
- List<String> result = new ArrayList<>();
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- result.add(pkgRollbackInfo.getPackageName());
+ synchronized (mLock) {
+ List<String> result = new ArrayList<>();
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ result.add(pkgRollbackInfo.getPackageName());
+ }
+ return result;
}
- return result;
}
/**
* Returns a list containing the names of all the apex packages included in this rollback.
*/
- @GuardedBy("getLock")
List<String> getApexPackageNames() {
- List<String> result = new ArrayList<>();
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- if (pkgRollbackInfo.isApex()) {
- result.add(pkgRollbackInfo.getPackageName());
+ synchronized (mLock) {
+ List<String> result = new ArrayList<>();
+ for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+ if (pkgRollbackInfo.isApex()) {
+ result.add(pkgRollbackInfo.getPackageName());
+ }
}
+ return result;
+ }
+ }
+
+ int getPackageCount() {
+ synchronized (mLock) {
+ return info.getPackages().size();
}
- return result;
}
static String rollbackStateToString(@RollbackState int state) {
@@ -651,8 +677,39 @@ class Rollback {
throw new ParseException("Invalid rollback state: " + state, 0);
}
- @GuardedBy("getLock")
String getStateAsString() {
- return rollbackStateToString(mState);
+ synchronized (mLock) {
+ return rollbackStateToString(mState);
+ }
+ }
+
+ void dump(IndentingPrintWriter ipw) {
+ synchronized (mLock) {
+ ipw.println(info.getRollbackId() + ":");
+ ipw.increaseIndent();
+ ipw.println("-state: " + getStateAsString());
+ ipw.println("-timestamp: " + getTimestamp());
+ if (getStagedSessionId() != -1) {
+ ipw.println("-stagedSessionId: " + getStagedSessionId());
+ }
+ ipw.println("-packages:");
+ ipw.increaseIndent();
+ for (PackageRollbackInfo pkg : info.getPackages()) {
+ ipw.println(pkg.getPackageName()
+ + " " + pkg.getVersionRolledBackFrom().getLongVersionCode()
+ + " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
+ }
+ ipw.decreaseIndent();
+ if (isCommitted()) {
+ ipw.println("-causePackages:");
+ ipw.increaseIndent();
+ for (VersionedPackage cPkg : info.getCausePackages()) {
+ ipw.println(cPkg.getPackageName() + " " + cPkg.getLongVersionCode());
+ }
+ ipw.decreaseIndent();
+ ipw.println("-committedSessionId: " + info.getCommittedSessionId());
+ }
+ ipw.decreaseIndent();
+ }
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 2221dff79336..cd44f64ada4f 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -36,7 +36,6 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import android.content.rollback.IRollbackManager;
-import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.os.Binder;
@@ -215,7 +214,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
synchronized (mLock) {
for (NewRollback rollback : mNewRollbacks) {
if (rollback.hasToken(token)) {
- rollback.isCancelled = true;
+ rollback.setCancelled();
return;
}
}
@@ -278,10 +277,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- synchronized (rollback.getLock()) {
- if (rollback.isAvailable()) {
- rollbacks.add(rollback.info);
- }
+ if (rollback.isAvailable()) {
+ rollbacks.add(rollback.info);
}
}
return new ParceledListSlice<>(rollbacks);
@@ -296,10 +293,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- synchronized (rollback.getLock()) {
- if (rollback.isCommitted()) {
- rollbacks.add(rollback.info);
- }
+ if (rollback.isCommitted()) {
+ rollbacks.add(rollback.info);
}
}
return new ParceledListSlice<>(rollbacks);
@@ -332,11 +327,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- synchronized (rollback.getLock()) {
- rollback.setTimestamp(
- rollback.getTimestamp().plusMillis(timeDifference));
- RollbackStore.saveRollback(rollback);
- }
+ rollback.setTimestamp(
+ rollback.getTimestamp().plusMillis(timeDifference));
}
}
}
@@ -367,9 +359,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
"Rollback unavailable");
return;
}
- synchronized (rollback.getLock()) {
- rollback.commit(mContext, causePackages, callerPackageName, statusReceiver);
- }
+ rollback.commit(mContext, causePackages, callerPackageName, statusReceiver);
}
@Override
@@ -404,18 +394,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- synchronized (rollback.getLock()) {
- if (rollback.includesPackage(packageName)) {
- iter.remove();
- rollback.delete(mAppDataRollbackHelper);
- }
+ if (rollback.includesPackage(packageName)) {
+ iter.remove();
+ rollback.delete(mAppDataRollbackHelper);
}
}
for (NewRollback newRollback : mNewRollbacks) {
- synchronized (newRollback.rollback.getLock()) {
- if (newRollback.rollback.includesPackage(packageName)) {
- newRollback.isCancelled = true;
- }
+ if (newRollback.rollback.includesPackage(packageName)) {
+ newRollback.setCancelled();
}
}
}
@@ -448,12 +434,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
for (int i = 0; i < rollbacks.size(); i++) {
Rollback rollback = rollbacks.get(i);
- synchronized (rollback.getLock()) {
- if (mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser(
- userId, rollback)) {
- RollbackStore.saveRollback(rollback);
- }
- }
+ rollback.commitPendingBackupAndRestoreForUser(userId, mAppDataRollbackHelper);
}
latch.countDown();
@@ -489,48 +470,41 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
Set<String> apexPackageNames = new HashSet<>();
synchronized (mLock) {
for (Rollback rollback : mRollbacks) {
- synchronized (rollback.getLock()) {
- if (rollback.isStaged()) {
- if (rollback.isEnabling()) {
- enabling.add(rollback);
- } else if (rollback.isRestoreUserDataInProgress()) {
- restoreInProgress.add(rollback);
- }
-
- apexPackageNames.addAll(rollback.getApexPackageNames());
+ if (rollback.isStaged()) {
+ if (rollback.isEnabling()) {
+ enabling.add(rollback);
+ } else if (rollback.isRestoreUserDataInProgress()) {
+ restoreInProgress.add(rollback);
}
+
+ apexPackageNames.addAll(rollback.getApexPackageNames());
}
}
}
for (Rollback rollback : enabling) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
- synchronized (rollback.getLock()) {
- PackageInstaller.SessionInfo session =
- installer.getSessionInfo(rollback.getStagedSessionId());
- if (session == null || session.isStagedSessionFailed()) {
- // TODO: Do we need to remove this from
- // mRollbacks, or is it okay to leave as
- // unavailable until the next reboot when it will go
- // away on its own?
- rollback.delete(mAppDataRollbackHelper);
- } else if (session.isStagedSessionApplied()) {
- makeRollbackAvailable(rollback);
- }
+ PackageInstaller.SessionInfo session =
+ installer.getSessionInfo(rollback.getStagedSessionId());
+ if (session == null || session.isStagedSessionFailed()) {
+ // TODO: Do we need to remove this from
+ // mRollbacks, or is it okay to leave as
+ // unavailable until the next reboot when it will go
+ // away on its own?
+ rollback.delete(mAppDataRollbackHelper);
+ } else if (session.isStagedSessionApplied()) {
+ makeRollbackAvailable(rollback);
}
}
for (Rollback rollback : restoreInProgress) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
- synchronized (rollback.getLock()) {
- PackageInstaller.SessionInfo session =
- installer.getSessionInfo(rollback.getStagedSessionId());
- // TODO: What if session is null?
- if (session != null) {
- if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
- rollback.setRestoreUserDataInProgress(false);
- RollbackStore.saveRollback(rollback);
- }
+ PackageInstaller.SessionInfo session =
+ installer.getSessionInfo(rollback.getStagedSessionId());
+ // TODO: What if session is null?
+ if (session != null) {
+ if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
+ rollback.setRestoreUserDataInProgress(false);
}
}
}
@@ -565,14 +539,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- synchronized (rollback.getLock()) {
- // TODO: Should we remove rollbacks in the ENABLING state here?
- if ((rollback.isEnabling() || rollback.isAvailable())
- && rollback.includesPackageWithDifferentVersion(packageName,
- installedVersion)) {
- iter.remove();
- rollback.delete(mAppDataRollbackHelper);
- }
+ // TODO: Should we remove rollbacks in the ENABLING state here?
+ if ((rollback.isEnabling() || rollback.isAvailable())
+ && rollback.includesPackageWithDifferentVersion(packageName,
+ installedVersion)) {
+ iter.remove();
+ rollback.delete(mAppDataRollbackHelper);
}
}
}
@@ -615,18 +587,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- synchronized (rollback.getLock()) {
- if (!rollback.isAvailable()) {
- continue;
- }
- if (!now.isBefore(
- rollback.getTimestamp()
- .plusMillis(mRollbackLifetimeDurationInMillis))) {
- iter.remove();
- rollback.delete(mAppDataRollbackHelper);
- } else if (oldest == null || oldest.isAfter(rollback.getTimestamp())) {
- oldest = rollback.getTimestamp();
- }
+ if (!rollback.isAvailable()) {
+ continue;
+ }
+ Instant rollbackTimestamp = rollback.getTimestamp();
+ if (!now.isBefore(
+ rollbackTimestamp
+ .plusMillis(mRollbackLifetimeDurationInMillis))) {
+ iter.remove();
+ rollback.delete(mAppDataRollbackHelper);
+ } else if (oldest == null || oldest.isAfter(rollbackTimestamp)) {
+ oldest = rollbackTimestamp;
}
}
}
@@ -734,12 +705,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
synchronized (mLock) {
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- synchronized (rollback.getLock()) {
- if (rollback.getApkSessionId() == parentSession.getSessionId()) {
- // This is the apk session for a staged session with rollback enabled. We do
- // not need to create a new rollback for this session.
- return true;
- }
+ if (rollback.getApkSessionId() == parentSession.getSessionId()) {
+ // This is the apk session for a staged session with rollback enabled. We do
+ // not need to create a new rollback for this session.
+ return true;
}
}
}
@@ -829,11 +798,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
ApplicationInfo appInfo = pkgInfo.applicationInfo;
- synchronized (rollback.getLock()) {
- return rollback.enableForPackage(packageName, newPackage.versionCode,
- pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir,
- appInfo.splitSourceDirs);
- }
+ return rollback.enableForPackage(packageName, newPackage.versionCode,
+ pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir,
+ appInfo.splitSourceDirs);
}
@Override
@@ -858,16 +825,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
// staged installs
for (int i = 0; i < mRollbacks.size(); i++) {
Rollback rollback = mRollbacks.get(i);
- synchronized (rollback.getLock()) {
- rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper);
- }
+ rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper);
}
// non-staged installs
for (NewRollback rollback : mNewRollbacks) {
- synchronized (rollback.rollback.getLock()) {
- rollback.rollback.snapshotUserData(
- packageName, userIds, mAppDataRollbackHelper);
- }
+ rollback.rollback.snapshotUserData(
+ packageName, userIds, mAppDataRollbackHelper);
}
}
}
@@ -877,11 +840,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
synchronized (mLock) {
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- synchronized (rollback.getLock()) {
- if (rollback.restoreUserDataForPackageIfInProgress(
- packageName, userIds, appId, seInfo, mAppDataRollbackHelper)) {
- return;
- }
+ if (rollback.restoreUserDataForPackageIfInProgress(
+ packageName, userIds, appId, seInfo, mAppDataRollbackHelper)) {
+ return;
}
}
}
@@ -970,10 +931,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
if (rollback != null) {
- synchronized (rollback.getLock()) {
- rollback.setApkSessionId(apkSessionId);
- RollbackStore.saveRollback(rollback);
- }
+ rollback.setApkSessionId(apkSessionId);
}
});
}
@@ -1076,12 +1034,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
if (newRollback != null) {
Rollback rollback = completeEnableRollback(newRollback, success);
- if (rollback != null) {
- synchronized (rollback.getLock()) {
- if (!rollback.isStaged()) {
- makeRollbackAvailable(rollback);
- }
- }
+ if (rollback != null && !rollback.isStaged()) {
+ makeRollbackAvailable(rollback);
}
}
}
@@ -1091,34 +1045,30 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
* Add a rollback to the list of rollbacks. This should be called after rollback has been
* enabled for all packages in the rollback. It does not make the rollback available yet.
*
- * <p>Note that no rollback-specific locks should be held when this method is called.
- *
* @return the Rollback instance for a successfully enable-completed rollback,
* or null on error.
*/
private Rollback completeEnableRollback(NewRollback newRollback, boolean success) {
Rollback rollback = newRollback.rollback;
- synchronized (rollback.getLock()) {
- if (!success) {
- // The install session was aborted, clean up the pending install.
- rollback.delete(mAppDataRollbackHelper);
- return null;
- }
- if (newRollback.isCancelled) {
- Slog.e(TAG, "Rollback has been cancelled by PackageManager");
- rollback.delete(mAppDataRollbackHelper);
- return null;
- }
-
+ if (!success) {
+ // The install session was aborted, clean up the pending install.
+ rollback.delete(mAppDataRollbackHelper);
+ return null;
+ }
- if (rollback.info.getPackages().size() != newRollback.packageSessionIds.length) {
- Slog.e(TAG, "Failed to enable rollback for all packages in session.");
- rollback.delete(mAppDataRollbackHelper);
- return null;
- }
+ if (newRollback.isCancelled()) {
+ Slog.e(TAG, "Rollback has been cancelled by PackageManager");
+ rollback.delete(mAppDataRollbackHelper);
+ return null;
+ }
- RollbackStore.saveRollback(rollback);
+ if (rollback.getPackageCount() != newRollback.getPackageSessionIdCount()) {
+ Slog.e(TAG, "Failed to enable rollback for all packages in session.");
+ rollback.delete(mAppDataRollbackHelper);
+ return null;
}
+
+ rollback.saveRollback();
synchronized (mLock) {
// Note: There is a small window of time between when
// the session has been committed by the package
@@ -1186,34 +1136,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mLock) {
for (Rollback rollback : mRollbacks) {
- synchronized (rollback.getLock()) {
- RollbackInfo info = rollback.info;
- ipw.println(info.getRollbackId() + ":");
- ipw.increaseIndent();
- ipw.println("-state: " + rollback.getStateAsString());
- ipw.println("-timestamp: " + rollback.getTimestamp());
- if (rollback.getStagedSessionId() != -1) {
- ipw.println("-stagedSessionId: " + rollback.getStagedSessionId());
- }
- ipw.println("-packages:");
- ipw.increaseIndent();
- for (PackageRollbackInfo pkg : info.getPackages()) {
- ipw.println(pkg.getPackageName()
- + " " + pkg.getVersionRolledBackFrom().getLongVersionCode()
- + " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
- }
- ipw.decreaseIndent();
- if (rollback.isCommitted()) {
- ipw.println("-causePackages:");
- ipw.increaseIndent();
- for (VersionedPackage cPkg : info.getCausePackages()) {
- ipw.println(cPkg.getPackageName() + " " + cPkg.getLongVersionCode());
- }
- ipw.decreaseIndent();
- ipw.println("-committedSessionId: " + info.getCommittedSessionId());
- }
- ipw.decreaseIndent();
- }
+ rollback.dump(ipw);
}
}
}
@@ -1233,22 +1156,51 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
public final Rollback rollback;
/**
- * This array holds all of the rollback tokens associated with package sessions included
- * in this rollback. This is used to identify which rollback should be cancelled in case
- * {@link PackageManager} sends an {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent.
+ * This array holds all of the rollback tokens associated with package sessions included in
+ * this rollback.
*/
+ @GuardedBy("mNewRollbackLock")
private final IntArray mTokens = new IntArray();
/**
- * Session ids for all packages in the install.
- * For multi-package sessions, this is the list of child session ids.
- * For normal sessions, this list is a single element with the normal
+ * Session ids for all packages in the install. For multi-package sessions, this is the list
+ * of child session ids. For normal sessions, this list is a single element with the normal
* session id.
*/
- public final int[] packageSessionIds;
+ private final int[] mPackageSessionIds;
+
+ @GuardedBy("mNewRollbackLock")
+ private boolean mIsCancelled = false;
+
+ private final Object mNewRollbackLock = new Object();
+
+ NewRollback(Rollback rollback, int[] packageSessionIds) {
+ this.rollback = rollback;
+ this.mPackageSessionIds = packageSessionIds;
+ }
+
+ /**
+ * Adds a rollback token to be associated with this NewRollback. This may be used to
+ * identify which rollback should be cancelled in case {@link PackageManager} sends an
+ * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent.
+ */
+ void addToken(int token) {
+ synchronized (mNewRollbackLock) {
+ mTokens.add(token);
+ }
+ }
+
+ /**
+ * Returns true if this NewRollback is associated with the provided {@code token}.
+ */
+ boolean hasToken(int token) {
+ synchronized (mNewRollbackLock) {
+ return mTokens.indexOf(token) != -1;
+ }
+ }
/**
- * Flag to determine whether the rollback has been cancelled.
+ * Returns true if this NewRollback has been cancelled.
*
* <p>Rollback could be invalidated and cancelled if RollbackManager receives
* {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}.
@@ -1258,19 +1210,38 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
* {@link PackageInstaller.SessionCallback#onFinished(int, boolean)} before it broadcasts
* {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK}.
*/
- public boolean isCancelled = false;
+ boolean isCancelled() {
+ synchronized (mNewRollbackLock) {
+ return mIsCancelled;
+ }
+ }
- NewRollback(Rollback rollback, int[] packageSessionIds) {
- this.rollback = rollback;
- this.packageSessionIds = packageSessionIds;
+ /**
+ * Sets this NewRollback to be marked as cancelled.
+ */
+ void setCancelled() {
+ synchronized (mNewRollbackLock) {
+ mIsCancelled = true;
+ }
}
- public void addToken(int token) {
- mTokens.add(token);
+ /**
+ * Returns true if this NewRollback contains the provided {@code packageSessionId}.
+ */
+ boolean containsSessionId(int packageSessionId) {
+ for (int id : mPackageSessionIds) {
+ if (id == packageSessionId) {
+ return true;
+ }
+ }
+ return false;
}
- public boolean hasToken(int token) {
- return mTokens.indexOf(token) != -1;
+ /**
+ * Returns the number of package session ids in this NewRollback.
+ */
+ int getPackageSessionIdCount() {
+ return mPackageSessionIds.length;
}
}
@@ -1301,14 +1272,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
* Returns null if no NewRollback is found for the given package
* session.
*/
+ @GuardedBy("mLock")
NewRollback getNewRollbackForPackageSessionLocked(int packageSessionId) {
// We expect mNewRollbacks to be a very small list; linear search
// should be plenty fast.
for (NewRollback newRollback: mNewRollbacks) {
- for (int id : newRollback.packageSessionIds) {
- if (id == packageSessionId) {
- return newRollback;
- }
+ if (newRollback.containsSessionId(packageSessionId)) {
+ return newRollback;
}
}
return null;
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index a9331aa5648f..eadd09cf46ee 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -252,7 +252,7 @@ class RollbackStore {
/**
* Saves the given rollback to persistent storage.
*/
- @GuardedBy("rollback.getLock")
+ @GuardedBy("rollback.mLock")
static void saveRollback(Rollback rollback) {
try {
JSONObject dataJson = new JSONObject();