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

Commit 1fc8b36c authored by Rhed Jao's avatar Rhed Jao
Browse files

Fixed NPE in package installer session.

We updated staged sessions to activation failed state when they
aren't in terminal state, and device received ota and reboot. This
happend before the StagingManager resumes the sessions when
the whole set of parent+child sessions have been restored.
A parent session probably cannot find the child session, and a null
exception could happen.

In this change, we do not destroy child sessions before we destroy
the parent session. We only destroy a child session directly if we
are sure that its parent session doesn't exist.

Bug: 147651771
Test: StagedInstallTest
Change-Id: Iac6489a04df35f851aa18a91e1dde2d73928b8ec
parent 805b26ac
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -259,11 +259,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        // atomic install which needs to query sessions, which requires lock on mSessions.
        boolean isDeviceUpgrading = mPm.isDeviceUpgrading();
        for (PackageInstallerSession session : stagedSessionsToRestore) {
            if (isDeviceUpgrading && !session.isStagedAndInTerminalState()) {
            if (!session.isStagedAndInTerminalState() && session.hasParentSessionId()
                    && getSession(session.getParentSessionId()) == null) {
                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        "Build fingerprint has changed");
                        "An orphan staged session " + session.sessionId + " is found, "
                                + "parent " + session.getParentSessionId() + " is missing");
            }
            mStagingManager.restoreSession(session);
            mStagingManager.restoreSession(session, isDeviceUpgrading);
        }
        // Broadcasts are not sent while we restore sessions on boot, since no processes would be
        // ready to listen to them. From now on, we greedily assume that broadcasts requests are
+8 −1
Original line number Diff line number Diff line
@@ -889,7 +889,7 @@ public class StagingManager {
        return false;
    }

    void restoreSession(@NonNull PackageInstallerSession session) {
    void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) {
        PackageInstallerSession sessionToResume = session;
        synchronized (mStagedSessions) {
            mStagedSessions.append(session.sessionId, session);
@@ -906,6 +906,13 @@ public class StagingManager {
                }
            }
        }
        // The preconditions used during pre-reboot verification might have changed when device
        // is upgrading. Updated staged sessions to activation failed before we resume the session.
        if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) {
            sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        "Build fingerprint has changed");
            return;
        }
        checkStateAndResume(sessionToResume);
    }