diff options
3 files changed, 67 insertions, 62 deletions
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java index 73b8a48d9153..7ebeb212b64a 100644 --- a/core/java/android/content/rollback/RollbackManager.java +++ b/core/java/android/content/rollback/RollbackManager.java @@ -216,6 +216,10 @@ public final class RollbackManager { * across device reboot, by simulating what happens on reboot without * actually rebooting the device. * + * Note rollbacks in the process of enabling will be lost after calling + * this method since they are not persisted yet. Don't call this method + * in the middle of the install process. + * * @throws SecurityException if the caller does not have appropriate permissions. * * @hide diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java index 4d7af9cc0d44..b5da1c2ec58a 100644 --- a/services/core/java/com/android/server/rollback/Rollback.java +++ b/services/core/java/com/android/server/rollback/Rollback.java @@ -182,6 +182,15 @@ class Rollback { private int mNumPackageSessionsWithSuccess; /** + * A temp flag to facilitate merging of the 2 rollback collections managed by + * RollbackManagerServiceImpl. True if this rollback is in the process of enabling and was + * originally managed by RollbackManagerServiceImpl#mNewRollbacks. + * TODO: remove this flag when merge is completed. + */ + @GuardedBy("mLock") + private boolean mIsNewRollback = false; + + /** * Constructs a new, empty Rollback instance. * * @param rollbackId the id of the rollback. @@ -829,6 +838,18 @@ class Rollback { } } + void setIsNewRollback(boolean newRollback) { + synchronized (mLock) { + mIsNewRollback = newRollback; + } + } + + boolean isNewRollback() { + synchronized (mLock) { + return mIsNewRollback; + } + } + static String rollbackStateToString(@RollbackState int state) { switch (state) { case Rollback.ROLLBACK_STATE_ENABLING: return "enabling"; diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 8bd9533727d6..1421258c12f6 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 @@ 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; @@ -50,7 +51,6 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; -import android.util.ArraySet; import android.util.IntArray; import android.util.Log; import android.util.LongArrayQueue; @@ -121,10 +121,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @GuardedBy("mLock") private final SparseBooleanArray mAllocatedRollbackIds = new SparseBooleanArray(); - // Rollbacks we are in the process of enabling. - @GuardedBy("mLock") - private final Set<Rollback> mNewRollbacks = new ArraySet<>(); - // The list of all rollbacks, including available and committed rollbacks. @GuardedBy("mLock") private final List<Rollback> mRollbacks; @@ -240,17 +236,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { Slog.v(TAG, "broadcast=ACTION_CANCEL_ENABLE_ROLLBACK token=" + token); } synchronized (mLock) { - Rollback found = null; - for (Rollback newRollback : mNewRollbacks) { - if (newRollback.hasToken(token)) { - found = newRollback; + for (int i = 0; i < mRollbacks.size(); ++i) { + Rollback rollback = mRollbacks.get(i); + if (rollback.hasToken(token) && rollback.isEnabling()) { + mRollbacks.remove(i); + rollback.delete(mAppDataRollbackHelper); break; } } - if (found != null) { - mNewRollbacks.remove(found); - found.delete(mAppDataRollbackHelper); - } } } } @@ -442,15 +435,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { rollback.delete(mAppDataRollbackHelper); } } - Iterator<Rollback> iter2 = mNewRollbacks.iterator(); - while (iter2.hasNext()) { - Rollback newRollback = iter2.next(); - if (newRollback.includesPackage(packageName)) { - iter2.remove(); - newRollback.delete(mAppDataRollbackHelper); - } - - } } } @@ -810,7 +794,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { newRollback = getNewRollbackForPackageSessionLocked(packageSession.getSessionId()); if (newRollback == null) { newRollback = createNewRollbackLocked(parentSession); - mNewRollbacks.add(newRollback); + mRollbacks.add(newRollback); + newRollback.setIsNewRollback(true); } } newRollback.addToken(token); @@ -818,34 +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) { - Rollback newRollback = getNewRollbackForPackageSessionLocked(sessionId); - if (newRollback != null) { - Slog.w(TAG, "Delete new rollback id=" + newRollback.info.getRollbackId() - + " for session id=" + sessionId); - mNewRollbacks.remove(newRollback); - newRollback.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 @@ -966,15 +923,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { + " users=" + Arrays.toString(userIds)); } synchronized (mLock) { - // staged installs for (int i = 0; i < mRollbacks.size(); i++) { Rollback rollback = mRollbacks.get(i); rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper); } - // non-staged installs - for (Rollback rollback : mNewRollbacks) { - rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper); - } } } @@ -1200,7 +1152,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { synchronized (mLock) { newRollback = getNewRollbackForPackageSessionLocked(sessionId); if (newRollback != null && newRollback.notifySessionWithSuccess()) { - mNewRollbacks.remove(newRollback); + mRollbacks.remove(newRollback); + newRollback.setIsNewRollback(false); } else { // Not all child sessions finished with success. // Don't enable the rollback yet. @@ -1215,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); + } + } } } } @@ -1376,6 +1337,25 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } /** + * 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. @@ -1383,11 +1363,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @WorkerThread @GuardedBy("mLock") Rollback getNewRollbackForPackageSessionLocked(int packageSessionId) { - // We expect mNewRollbacks to be a very small list; linear search + // We expect mRollbacks to be a very small list; linear search // should be plenty fast. - for (Rollback newRollback: mNewRollbacks) { - if (newRollback.containsSessionId(packageSessionId)) { - return newRollback; + for (Rollback rollback: mRollbacks) { + if (rollback.isNewRollback() && rollback.containsSessionId(packageSessionId)) { + return rollback; } } return null; |