summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java87
1 files changed, 68 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 9a65ae6dba4d..1475ab9df37b 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -780,6 +780,33 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
return enableRollbackForPackageSession(newRollback.rollback, packageSession);
}
+ private void removeRollbackForPackageSessionId(int sessionId) {
+ if (LOCAL_LOGV) {
+ Slog.v(TAG, "removeRollbackForPackageSessionId=" + sessionId);
+ }
+
+ synchronized (mLock) {
+ NewRollback newRollback = getNewRollbackForPackageSessionLocked(sessionId);
+ if (newRollback != null) {
+ Slog.w(TAG, "Delete new rollback id=" + newRollback.rollback.info.getRollbackId()
+ + " for session id=" + sessionId);
+ mNewRollbacks.remove(newRollback);
+ newRollback.rollback.delete(mAppDataRollbackHelper);
+ }
+ Iterator<Rollback> iter = mRollbacks.iterator();
+ while (iter.hasNext()) {
+ Rollback rollback = iter.next();
+ if (rollback.getStagedSessionId() == 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
@@ -944,7 +971,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
}
- Rollback rollback = completeEnableRollback(newRollback, true);
+ Rollback rollback = completeEnableRollback(newRollback);
if (rollback == null) {
result.offer(-1);
} else {
@@ -1089,19 +1116,28 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
if (LOCAL_LOGV) {
Slog.v(TAG, "SessionCallback.onFinished id=" + sessionId + " success=" + success);
}
- NewRollback newRollback;
- synchronized (mLock) {
- newRollback = getNewRollbackForPackageSessionLocked(sessionId);
- if (newRollback != null) {
- mNewRollbacks.remove(newRollback);
+
+ if (success) {
+ NewRollback newRollback;
+ synchronized (mLock) {
+ newRollback = getNewRollbackForPackageSessionLocked(sessionId);
+ if (newRollback != null && newRollback.notifySessionWithSuccess()) {
+ mNewRollbacks.remove(newRollback);
+ } else {
+ // Not all child sessions finished with success.
+ // Don't enable the rollback yet.
+ newRollback = null;
+ }
}
- }
- if (newRollback != null) {
- Rollback rollback = completeEnableRollback(newRollback, success);
- if (rollback != null && !rollback.isStaged()) {
- makeRollbackAvailable(rollback);
+ if (newRollback != null) {
+ Rollback rollback = completeEnableRollback(newRollback);
+ if (rollback != null && !rollback.isStaged()) {
+ makeRollbackAvailable(rollback);
+ }
}
+ } else {
+ removeRollbackForPackageSessionId(sessionId);
}
// Clear the queue so it will never be leaked to next tests.
@@ -1116,16 +1152,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
* @return the Rollback instance for a successfully enable-completed rollback,
* or null on error.
*/
- private Rollback completeEnableRollback(NewRollback newRollback, boolean success) {
+ private Rollback completeEnableRollback(NewRollback newRollback) {
Rollback rollback = newRollback.rollback;
if (LOCAL_LOGV) {
- Slog.v(TAG, "completeEnableRollback id="
- + rollback.info.getRollbackId() + " success=" + success);
- }
- if (!success) {
- // The install session was aborted, clean up the pending install.
- rollback.delete(mAppDataRollbackHelper);
- return null;
+ Slog.v(TAG, "completeEnableRollback id=" + rollback.info.getRollbackId());
}
if (newRollback.isCancelled()) {
@@ -1251,6 +1281,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
@GuardedBy("mNewRollbackLock")
private boolean mIsCancelled = false;
+ /**
+ * The number of sessions in the install which are notified with success by
+ * {@link PackageInstaller.SessionCallback#onFinished(int, boolean)}.
+ * This NewRollback will be enabled only after all child sessions finished with success.
+ */
+ @GuardedBy("mNewRollbackLock")
+ private int mNumPackageSessionsWithSuccess;
+
private final Object mNewRollbackLock = new Object();
NewRollback(Rollback rollback, int[] packageSessionIds) {
@@ -1322,6 +1360,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
int getPackageSessionIdCount() {
return mPackageSessionIds.length;
}
+
+ /**
+ * Called when a child session finished with success.
+ * Returns true when all child sessions are notified with success. This NewRollback will be
+ * enabled only after all child sessions finished with success.
+ */
+ boolean notifySessionWithSuccess() {
+ synchronized (mNewRollbackLock) {
+ return ++mNumPackageSessionsWithSuccess == mPackageSessionIds.length;
+ }
+ }
}
@GuardedBy("mLock")