Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3fa0ce99 authored by JW Wang's avatar JW Wang
Browse files

Enable a new rollback only when all child sessions succeeded (1/n)

Don't enable a new rollback until all its child sessions are
notified with success by SessionCallback#onFinished.

This change allows us to delete/remove a new rollback if any of its
child sessions failed before enabling it.

Bug: 134652027
Test: atest RollbackTest

Change-Id: Ie7cee8b0998a1df381a83219988a3876629fbcbb
parent f73f94a8
Loading
Loading
Loading
Loading
+38 −10
Original line number Diff line number Diff line
@@ -1089,11 +1089,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            if (LOCAL_LOGV) {
                Slog.v(TAG, "SessionCallback.onFinished id=" + sessionId + " success=" + success);
            }

            if (success) {
                NewRollback newRollback;
                synchronized (mLock) {
                    newRollback = getNewRollbackForPackageSessionLocked(sessionId);
                if (newRollback != null) {
                    if (newRollback != null && newRollback.notifySessionWithSuccess()) {
                        mNewRollbacks.remove(newRollback);
                    } else {
                        // Not all child sessions finished with success.
                        // Don't enable the rollback yet.
                        newRollback = null;
                    }
                }

@@ -1103,6 +1109,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                        makeRollbackAvailable(rollback);
                    }
                }
            } else {
                // TODO: delete rollbacks for this failed session
            }

            // Clear the queue so it will never be leaked to next tests.
            mSleepDuration.clear();
@@ -1251,6 +1260,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 +1339,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")