diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageInstallerSession.java | 37 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageSessionVerifier.java | 24 |
2 files changed, 29 insertions, 32 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 36a4b4391f14..d230004e6213 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -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); - } - }); + mStagedSession.notifyEndPreRebootVerification(); + mStagingManager.commitSession(mStagedSession); + sendUpdateToRemoteStatusReceiver(INSTALL_SUCCEEDED, "Session staged", null); 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; diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java index 9db215e9093c..6b57deba56b5 100644 --- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java +++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java @@ -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) { - callback.onResult(returnCode, msg); + 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) { |