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
This commit is contained in:
JW Wang
2020-02-07 15:52:36 +08:00
parent dc1f92192a
commit 1ac3d11862

View File

@@ -19,6 +19,7 @@ package com.android.server.rollback;
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 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
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 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
}
} 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);
}
}
}
}
}
@@ -1349,6 +1336,25 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
return rollback;
}
/**
* 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