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

Commit 07205e38 authored by shafik's avatar shafik
Browse files

StagingManager: Support abandoning staged sessions

Add StagingManager and PackageInstallerSession functionality
for aborting an active staged session after being committed
but before reboot.

Also add abortActiveSession method to ApexManager.

Change-Id: Iba9ea29a2270df627b67fe27914793a442ee1a3d
Test: atest apex_e2e_tests
Bug: 124036308
parent c0c7f756
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -204,6 +204,21 @@ class ApexManager {
        return !mActivePackagesCache.isEmpty();
        return !mActivePackagesCache.isEmpty();
    }
    }


    /**
     * Abandons the (only) active session previously submitted.
     *
     * @return {@code true} upon success, {@code false} if any remote exception occurs
     */
    boolean abortActiveSession() {
        try {
            mApexService.abortActiveSession();
            return true;
        } catch (RemoteException re) {
            Slog.e(TAG, "Unable to contact apexservice", re);
            return false;
        }
    }

    /**
    /**
     * Dumps various state information to the provided {@link PrintWriter} object.
     * Dumps various state information to the provided {@link PrintWriter} object.
     *
     *
+9 −0
Original line number Original line Diff line number Diff line
@@ -1867,6 +1867,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            assertCallerIsOwnerOrRootLocked();
            assertCallerIsOwnerOrRootLocked();


            if (mCommitted && params.isStaged) {
                synchronized (mLock) {
                    mDestroyed = true;
                }
                mStagingManager.abortCommittedSession(this);

                //TODO(b/123624108): delete staging dir
            }

            if (mRelinquished) {
            if (mRelinquished) {
                Slog.d(TAG, "Ignoring abandon after commit relinquished control");
                Slog.d(TAG, "Ignoring abandon after commit relinquished control");
                return;
                return;
+22 −1
Original line number Original line Diff line number Diff line
@@ -445,11 +445,32 @@ public class StagingManager {


    void abortSession(@NonNull PackageInstallerSession session) {
    void abortSession(@NonNull PackageInstallerSession session) {
        synchronized (mStagedSessions) {
        synchronized (mStagedSessions) {
            updateStoredSession(session);
            mStagedSessions.remove(session.sessionId);
            mStagedSessions.remove(session.sessionId);
        }
        }
    }
    }


    void abortCommittedSession(@NonNull PackageInstallerSession session) {
        if (session.isStagedSessionApplied()) {
            Slog.w(TAG, "Cannot abort applied session!");
            return;
        }
        if (isStagedSessionFinalized(session.sessionId)) {
            Slog.w(TAG, "Cannot abort session because it is not active or APEXD is not reachable");
            return;
        }

        mApexManager.abortActiveSession();

        abortSession(session);
    }

    private boolean isStagedSessionFinalized(int sessionId) {
        ApexSessionInfo session = mApexManager.getStagedSessionInfo(sessionId);

        /* checking if the session is in a final state, i.e., not active anymore */
        return session.isUnknown || session.isActivationFailed || session.isSuccess;
    }

    @GuardedBy("mStagedSessions")
    @GuardedBy("mStagedSessions")
    private boolean isMultiPackageSessionComplete(@NonNull PackageInstallerSession session) {
    private boolean isMultiPackageSessionComplete(@NonNull PackageInstallerSession session) {
        // This method assumes that the argument is either a parent session of a multi-package
        // This method assumes that the argument is either a parent session of a multi-package