Rewrite handling of failed sessions (2/n)
We want to delete rollbacks for failed sessions as long as parent or
child session id matches. For the sake of defensive programming, we
check #isEnabling to ensure we won't delete rollbacks that are already
made available or committed.
Bug: 149069841
Test: atest RollbackTest StagedRollbackTest
Change-Id: Ie95789c9c87f91d2cca84fede621bd17a6a9da18
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 1188a34..1421258 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.AnyThread;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.AppOpsManager;
@@ -802,28 +803,6 @@
return enableRollbackForPackageSession(newRollback, packageSession);
}
- @WorkerThread
- private void removeRollbackForPackageSessionId(int sessionId) {
- if (LOCAL_LOGV) {
- Slog.v(TAG, "removeRollbackForPackageSessionId=" + sessionId);
- }
-
- synchronized (mLock) {
- Iterator<Rollback> iter = mRollbacks.iterator();
- while (iter.hasNext()) {
- Rollback rollback = iter.next();
- if (rollback.getStagedSessionId() == sessionId
- || (rollback.isNewRollback() && rollback.containsSessionId(sessionId))) {
- Slog.w(TAG, "Delete rollback id=" + rollback.info.getRollbackId()
- + " for session id=" + sessionId);
- iter.remove();
- rollback.delete(mAppDataRollbackHelper);
- break;
- }
- }
- }
- }
-
/**
* Do code and userdata backups to enable rollback of the given session.
* In case of multiPackage sessions, <code>session</code> should be one of
@@ -1189,7 +1168,15 @@
}
}
} else {
- removeRollbackForPackageSessionId(sessionId);
+ synchronized (mLock) {
+ Rollback rollback = getRollbackForSessionLocked(sessionId);
+ if (rollback != null && rollback.isEnabling()) {
+ Slog.w(TAG, "Delete rollback id=" + rollback.info.getRollbackId()
+ + " for failed session id=" + sessionId);
+ mRollbacks.remove(rollback);
+ rollback.delete(mAppDataRollbackHelper);
+ }
+ }
}
}
}
@@ -1350,6 +1337,25 @@
}
/**
+ * Returns the Rollback associated with the given session if parent or child session id matches.
+ * Returns null if not found.
+ */
+ @WorkerThread
+ @GuardedBy("mLock")
+ @Nullable
+ private Rollback getRollbackForSessionLocked(int sessionId) {
+ // We expect mRollbacks to be a very small list; linear search should be plenty fast.
+ for (int i = 0; i < mRollbacks.size(); ++i) {
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.getStagedSessionId() == sessionId
+ || rollback.containsSessionId(sessionId)) {
+ return rollback;
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the NewRollback associated with the given package session.
* Returns null if no NewRollback is found for the given package
* session.