Prevent exceptions in pre-reboot verification from crashing system server am: fdf525f512

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

Change-Id: I0e9e1a1bfb8061e9543943bed4342bbacd7ece82
This commit is contained in:
Mohammad Samiul Islam
2020-11-03 21:28:20 +00:00
committed by Automerger Merge Worker

View File

@@ -1077,6 +1077,26 @@ public class StagingManager {
return true; return true;
} }
/**
* Ensure that there is no active apex session staged in apexd for the given session.
*
* @return returns true if it is ensured that there is no active apex session, otherwise false
*/
private boolean ensureActiveApexSessionIsAborted(PackageInstallerSession session) {
if (!sessionContainsApex(session)) {
return true;
}
final ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId);
if (apexSession == null || isApexSessionFinalized(apexSession)) {
return true;
}
try {
return mApexManager.abortStagedSession(session.sessionId);
} catch (PackageManagerException ignore) {
return false;
}
}
private boolean isApexSessionFinalized(ApexSessionInfo session) { private boolean isApexSessionFinalized(ApexSessionInfo session) {
/* checking if the session is in a final state, i.e., not active anymore */ /* checking if the session is in a final state, i.e., not active anymore */
return session.isUnknown || session.isActivationFailed || session.isSuccess return session.isUnknown || session.isActivationFailed || session.isSuccess
@@ -1308,19 +1328,26 @@ public class StagingManager {
onPreRebootVerificationComplete(sessionId); onPreRebootVerificationComplete(sessionId);
return; return;
} }
switch (msg.what) { try {
case MSG_PRE_REBOOT_VERIFICATION_START: switch (msg.what) {
handlePreRebootVerification_Start(session); case MSG_PRE_REBOOT_VERIFICATION_START:
break; handlePreRebootVerification_Start(session);
case MSG_PRE_REBOOT_VERIFICATION_APEX: break;
handlePreRebootVerification_Apex(session); case MSG_PRE_REBOOT_VERIFICATION_APEX:
break; handlePreRebootVerification_Apex(session);
case MSG_PRE_REBOOT_VERIFICATION_APK: break;
handlePreRebootVerification_Apk(session); case MSG_PRE_REBOOT_VERIFICATION_APK:
break; handlePreRebootVerification_Apk(session);
case MSG_PRE_REBOOT_VERIFICATION_END: break;
handlePreRebootVerification_End(session); case MSG_PRE_REBOOT_VERIFICATION_END:
break; handlePreRebootVerification_End(session);
break;
}
} catch (Exception e) {
Slog.e(TAG, "Pre-reboot verification failed due to unhandled exception", e);
onPreRebootVerificationFailure(session,
SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
"Pre-reboot verification failed due to unhandled exception: " + e);
} }
} }
@@ -1357,6 +1384,17 @@ public class StagingManager {
obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget(); obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget();
} }
private void onPreRebootVerificationFailure(PackageInstallerSession session,
@SessionInfo.StagedSessionErrorCode int errorCode, String errorMessage) {
if (!ensureActiveApexSessionIsAborted(session)) {
Slog.e(TAG, "Failed to abort apex session " + session.sessionId);
// Safe to ignore active apex session abortion failure since session will be marked
// failed on next step and staging directory for session will be deleted.
}
session.setStagedSessionFailed(errorCode, errorMessage);
onPreRebootVerificationComplete(session.sessionId);
}
// Things to do when pre-reboot verification completes for a particular sessionId // Things to do when pre-reboot verification completes for a particular sessionId
private void onPreRebootVerificationComplete(int sessionId) { private void onPreRebootVerificationComplete(int sessionId) {
// Remove it from mVerificationRunning so that verification is considered complete // Remove it from mVerificationRunning so that verification is considered complete