diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index dac4b6ff39c30..e12d1dc927144 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -166,6 +166,27 @@ class ApexManager { } } + /** + * Marks a staged session as successful. + * + *
Only activated session can be marked as successful. + * + * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as + * successful. + */ + void markStagedSessionSuccessful(int sessionId) { + try { + mApexService.markStagedSessionSuccessful(sessionId); + } catch (RemoteException re) { + Slog.e(TAG, "Unable to contact apexservice", re); + throw new RuntimeException(re); + } catch (Exception e) { + // It is fine to just log an exception in this case. APEXd will be able to recover in + // case markStagedSessionSuccessful fails. + Slog.e(TAG, "Failed to mark session " + sessionId + " as successful", e); + } + } + /** * Dumps various state information to the provided {@link PrintWriter} object. * @@ -196,7 +217,7 @@ class ApexManager { ipw.increaseIndent(); final ApexSessionInfo[] sessions = mApexService.getSessions(); for (ApexSessionInfo si : sessions) { - ipw.println("Session ID: " + Integer.toString(si.sessionId)); + ipw.println("Session ID: " + si.sessionId); ipw.increaseIndent(); if (si.isUnknown) { ipw.println("State: UNKNOWN"); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 6c212d63d77c4..d1ebc9400e4d1 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -247,7 +247,8 @@ public class StagingManager { } private void resumeSession(@NonNull PackageInstallerSession session) { - if (sessionContainsApex(session)) { + boolean hasApex = sessionContainsApex(session); + if (hasApex) { // Check with apexservice whether the apex packages have been activated. ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId); if (apexSessionInfo == null) { @@ -271,7 +272,7 @@ public class StagingManager { mBgHandler.post(() -> preRebootVerification(session)); return; } - if (!apexSessionInfo.isActivated) { + if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) { // In all the remaining cases apexd will try to apply the session again at next // boot. Nothing to do here for now. Slog.w(TAG, "Staged session " + session.sessionId + " scheduled to be applied " @@ -287,7 +288,11 @@ public class StagingManager { + "more information."); return; } + session.setStagedSessionApplied(); + if (hasApex) { + mApexManager.markStagedSessionSuccessful(session.sessionId); + } } private String findFirstAPKInDir(File stageDir) {