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

Commit 77ccd9ec authored by JW Wang's avatar JW Wang
Browse files

Apply READY/FAILED to non-staged sessions (12/n)

* Merge PackageSessionVerifier#VerifyNonStaged and
  PackageSessionVerifier#VerifyStaged. Now we have a single entry
  point, PackageSessionVerifier#verify to do verificaiton for both
  staged and non-staged sessions in one call.
* PackageSessionVerifier will change session states (either READY or
  FAILED) when verification is completed.

Bug: 210359798
Test: atest StagingManagerTest \
            CtsAtomicInstallTestCases \
            GtsStagedInstallHostTestCases \
            CtsRootPackageInstallerHostTestCases \
            CtsStagedInstallHostTestCases \
            CtsInstallHostTestCases \
            StagedInstallInternalTest

Change-Id: I8c00b817b86d8287704139b9f0769bb05d53d3c7
parent 2482ac1b
Loading
Loading
Loading
Loading
+10 −27
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
import static android.content.pm.PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
@@ -1968,16 +1967,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }

    private void onSessionVerificationFailure(int error, String msg) {
        final String msgWithErrorCode = PackageManager.installStatusToString(error, msg);
        Slog.e(TAG, "Failed to verify session " + sessionId + " [" + msgWithErrorCode + "]");
        Slog.e(TAG, "Failed to verify session " + sessionId);
        if (isStaged()) {
            // This will clean up the session when it reaches the terminal state
            mStagedSession.setSessionFailed(
                    SessionInfo.SESSION_VERIFICATION_FAILED, msgWithErrorCode);
            mStagedSession.notifyEndPreRebootVerification();
        } else {
            // Session is sealed and committed but could not be verified, we need to destroy it.
            destroy();
        }
        // Dispatch message to remove session from PackageInstallerService.
        dispatchSessionFinished(error, msg, null);
@@ -2198,7 +2190,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            verifyNonStaged();
        } catch (PackageManagerException e) {
            final String completeMsg = ExceptionUtils.getCompleteMessage(e);
            onSessionVerificationFailure(e.error, completeMsg);
            final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg);
            setSessionFailed(e.error, errorMsg);
            onSessionVerificationFailure(e.error, errorMsg);
        }
    }

@@ -2341,7 +2335,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            // the flag.
            mStageDirInUse = true;
        }
        mSessionProvider.getSessionVerifier().verifyNonStaged(this, (error, msg) -> {
        mSessionProvider.getSessionVerifier().verify(this, (error, msg) -> {
            mHandler.post(() -> {
                if (error == INSTALL_SUCCEEDED) {
                    onVerificationComplete();
@@ -2431,23 +2425,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

    @WorkerThread
    private void onVerificationComplete() {
        // APK verification is done. Continue the installation depending on whether it is a
        // staged session or not. For a staged session, we will hand it over to the staging
        // manager to complete the installation.
        if (isStaged()) {
            mSessionProvider.getSessionVerifier().verifyStaged(mStagedSession, (error, msg) -> {
            mStagedSession.notifyEndPreRebootVerification();
                if (error == SessionInfo.SESSION_NO_ERROR) {
            mStagingManager.commitSession(mStagedSession);
            sendUpdateToRemoteStatusReceiver(INSTALL_SUCCEEDED, "Session staged", null);
                } else {
                    dispatchSessionFinished(INSTALL_FAILED_VERIFICATION_FAILURE, msg, null);
                    maybeFinishChildSessions(INSTALL_FAILED_VERIFICATION_FAILURE, msg);
                }
            });
            return;
        }

        install();
    }

@@ -4055,7 +4038,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    private void setSessionReady() {
    void setSessionReady() {
        synchronized (mLock) {
            // Do not allow destroyed/failed session to change state
            if (mDestroyed || mSessionFailed) return;
@@ -4068,7 +4051,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mCallback.onSessionChanged(this);
    }

    private void setSessionFailed(int errorCode, String errorMessage) {
    void setSessionFailed(int errorCode, String errorMessage) {
        synchronized (mLock) {
            // Do not allow destroyed/failed session to change state
            if (mDestroyed || mSessionFailed) return;
+19 −5
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ final class PackageSessionVerifier {
    /**
     * Runs verifications that are common to both staged and non-staged sessions.
     */
    public void verifyNonStaged(PackageInstallerSession session, Callback callback) {
    public void verify(PackageInstallerSession session, Callback callback) {
        mHandler.post(() -> {
            try {
                storeSession(session.mStagedSession);
@@ -109,6 +109,8 @@ final class PackageSessionVerifier {
                }
                verifyAPK(session, callback);
            } catch (PackageManagerException e) {
                String errorMessage = PackageManager.installStatusToString(e.error, e.getMessage());
                session.setSessionFailed(SessionInfo.SESSION_VERIFICATION_FAILED, errorMessage);
                callback.onResult(e.error, e.getMessage());
            }
        });
@@ -128,7 +130,19 @@ final class PackageSessionVerifier {
            @Override
            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
                    Bundle extras) {
                if (session.isStaged() && returnCode == PackageManager.INSTALL_SUCCEEDED) {
                    // Continue verification for staged sessions
                    verifyStaged(session.mStagedSession, callback);
                    return;
                }
                if (returnCode != PackageManager.INSTALL_SUCCEEDED) {
                    String errorMessage = PackageManager.installStatusToString(returnCode, msg);
                    session.setSessionFailed(SessionInfo.SESSION_VERIFICATION_FAILED, errorMessage);
                    callback.onResult(returnCode, msg);
                } else {
                    session.setSessionReady();
                    callback.onResult(PackageManager.INSTALL_SUCCEEDED, null);
                }
            }
        };
        final VerificationParams verifyingSession = makeVerificationParams(session, observer);
@@ -171,7 +185,7 @@ final class PackageSessionVerifier {
     * Note it is the responsibility of the caller to ensure the staging files remain unchanged
     * while the verification is in progress.
     */
    void verifyStaged(StagingManager.StagedSession session, Callback callback) {
    private void verifyStaged(StagingManager.StagedSession session, Callback callback) {
        Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId());
        mHandler.post(() -> {
            try {
@@ -202,7 +216,7 @@ final class PackageSessionVerifier {
    }

    private void onVerificationSuccess(StagingManager.StagedSession session, Callback callback) {
        callback.onResult(SessionInfo.SESSION_NO_ERROR, null);
        callback.onResult(PackageManager.INSTALL_SUCCEEDED, null);
    }

    private void onVerificationFailure(StagingManager.StagedSession session, Callback callback,
@@ -213,7 +227,7 @@ final class PackageSessionVerifier {
            // failed on next step and staging directory for session will be deleted.
        }
        session.setSessionFailed(errorCode, errorMessage);
        callback.onResult(errorCode, errorMessage);
        callback.onResult(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMessage);
    }

    private void dispatchVerifyApex(StagingManager.StagedSession session, Callback callback) {