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

Commit 348096df authored by JW Wang's avatar JW Wang
Browse files

Split abandon() (3/n)

Since the flow of abandoning a staged session is quite different
from that of a non-staged session, splitting the method into 2 parts
increase readability.

In next CL, we will change abandonStaged() to fix a bug where an
abandoned staged session is not correctly cleaned up.

Bug: 163976510
Test: atest AtomicInstallTest StagedInstallTest
Change-Id: Iab1cd2bc25865224383a21e793cf58336bca18a8
parent b749aa9c
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -2734,23 +2734,27 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    @Override
    public void abandon() {
        if (hasParentSessionId()) {
            throw new IllegalStateException(
                    "Session " + sessionId + " is a child of multi-package session "
                            + getParentSessionId() +  " and may not be abandoned directly.");
    private void abandonNonStaged() {
        synchronized (mLock) {
            assertCallerIsOwnerOrRootLocked();
            if (mRelinquished) {
                if (LOGD) Slog.d(TAG, "Ignoring abandon after commit relinquished control");
                return;
            }
            destroyInternal();
        }
        dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
    }

    private void abandonStaged() {
        synchronized (mLock) {
            if (params.isStaged && mDestroyed) {
            if (mDestroyed) {
                // If a user abandons staged session in an unsafe state, then system will try to
                // abandon the destroyed staged session when it is safe on behalf of the user.
                assertCallerIsOwnerOrRootOrSystemLocked();
            } else {
                assertCallerIsOwnerOrRootLocked();
            }

            if (isStagedAndInTerminalState()) {
                // We keep the session in the database if it's in a finalized state. It will be
                // removed by PackageInstallerService when the last update time is old enough.
@@ -2758,7 +2762,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                // do it now.
                return;
            }
            if (mCommitted && params.isStaged) {
            if (mCommitted) {
                mDestroyed = true;
                if (!mStagingManager.abortCommittedSessionLocked(this)) {
                    // Do not clean up the staged session from system. It is not safe yet.
@@ -2767,16 +2771,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                }
                cleanStageDir(getChildSessionsLocked());
            }

            if (mRelinquished) {
                Slog.d(TAG, "Ignoring abandon after commit relinquished control");
                return;
            }
            destroyInternal();
        }
        dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
    }

    @Override
    public void abandon() {
        if (hasParentSessionId()) {
            throw new IllegalStateException(
                    "Session " + sessionId + " is a child of multi-package session "
                            + getParentSessionId() +  " and may not be abandoned directly.");
        }
        if (params.isStaged) {
            abandonStaged();
        } else {
            abandonNonStaged();
        }
    }

    @Override
    public boolean isMultiPackage() {
        return params.isMultiPackage;