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

Commit 580b4926 authored by Mohammad Samiul Islam's avatar Mohammad Samiul Islam Committed by Automerger Merge Worker
Browse files

Prevent exceptions during staged install from crashing system server am: ed2cd670

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12919795

Change-Id: Ie1dd97164aec8a6d68cd09d0c0cd0757095245b0
parents f9f22b63 ed2cd670
Loading
Loading
Loading
Loading
+45 −42
Original line number Diff line number Diff line
@@ -569,7 +569,8 @@ public class StagingManager {
        }
    }

    private void resumeSession(@NonNull PackageInstallerSession session) {
    private void resumeSession(@NonNull PackageInstallerSession session)
            throws PackageManagerException {
        Slog.d(TAG, "Resuming session " + session.sessionId);

        final boolean hasApex = sessionContainsApex(session);
@@ -633,10 +634,8 @@ public class StagingManager {
            if (apexSessionInfo == null) {
                final String errorMsg = "apexd did not know anything about a staged session "
                        + "supposed to be activated";
                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        errorMsg);
                abortCheckpoint(session.sessionId, errorMsg);
                return;
                throw new PackageManagerException(
                        SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg);
            }
            if (isApexSessionFailed(apexSessionInfo)) {
                String errorMsg = "APEX activation failed. Check logcat messages from apexd "
@@ -645,10 +644,8 @@ public class StagingManager {
                    errorMsg = "Session reverted due to crashing native process: "
                            + mNativeFailureReason;
                }
                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        errorMsg);
                abortCheckpoint(session.sessionId, errorMsg);
                return;
                throw new PackageManagerException(
                        SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg);
            }
            if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) {
                // Apexd did not apply the session for some unknown reason. There is no
@@ -656,14 +653,11 @@ public class StagingManager {
                // it as failed.
                final String errorMsg = "Staged session " + session.sessionId + "at boot "
                        + "didn't activate nor fail. Marking it as failed anyway.";
                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        errorMsg);
                abortCheckpoint(session.sessionId, errorMsg);
                return;
                throw new PackageManagerException(
                        SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg);
            }
        }
        // Handle apk and apk-in-apex installation
        try {
        if (hasApex) {
            checkInstallationOfApkInApexSuccessful(session);
            snapshotAndRestoreForApexSession(session);
@@ -673,25 +667,6 @@ public class StagingManager {
        // The APEX part of the session is activated, proceed with the installation of APKs.
        Slog.d(TAG, "Installing APK packages in session " + session.sessionId);
        installApksInSession(session);
        } catch (PackageManagerException e) {
            session.setStagedSessionFailed(e.error, e.getMessage());
            abortCheckpoint(session.sessionId, e.getMessage());

            // If checkpoint is not supported, we have to handle failure for one staged session.
            if (!hasApex) {
                return;
            }

            if (!mApexManager.revertActiveSessions()) {
                Slog.e(TAG, "Failed to abort APEXd session");
            } else {
                Slog.e(TAG,
                        "Successfully aborted apexd session. Rebooting device in order to revert "
                                + "to the previous state of APEXd.");
                mPowerManager.reboot(null);
            }
            return;
        }

        Slog.d(TAG, "Marking session " + session.sessionId + " as applied");
        session.setStagedSessionApplied();
@@ -727,6 +702,25 @@ public class StagingManager {
        return ret;
    }

    void onInstallationFailure(PackageInstallerSession session, PackageManagerException e) {
        session.setStagedSessionFailed(e.error, e.getMessage());
        abortCheckpoint(session.sessionId, e.getMessage());

        // If checkpoint is not supported, we have to handle failure for one staged session.
        if (!sessionContainsApex(session)) {
            return;
        }

        if (!mApexManager.revertActiveSessions()) {
            Slog.e(TAG, "Failed to abort APEXd session");
        } else {
            Slog.e(TAG,
                    "Successfully aborted apexd session. Rebooting device in order to revert "
                            + "to the previous state of APEXd.");
            mPowerManager.reboot(null);
        }
    }

    @NonNull
    private PackageInstallerSession createAndWriteApkSession(
            @NonNull PackageInstallerSession originalSession, boolean preReboot)
@@ -1190,7 +1184,16 @@ public class StagingManager {
        } else {
            // Session had already being marked ready. Start the checks to verify if there is any
            // follow-up work.
            try {
                resumeSession(session);
            } catch (PackageManagerException e) {
                onInstallationFailure(session, e);
            } catch (Exception e) {
                Slog.e(TAG, "Staged install failed due to unhandled exception", e);
                onInstallationFailure(session, new PackageManagerException(
                        SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        "Staged install failed due to unhandled exception: " + e));
            }
        }
    }