From c1e8f1f8230debaf9c3d4f5a8671bc74e4d39713 Mon Sep 17 00:00:00 2001 From: Oli Lan Date: Tue, 29 Jun 2021 17:54:08 +0100 Subject: [PATCH] Abandon other staged sessions when a rollback is staged. This change causes all staged sessions that are not rollbacks to be abandoned (failed) when a rollback is staged. This will ensure that an SDK extension level dependency is not violated if a rollback causes the extension level to drop while at the same time an app is installed that depends on the higher extension level. Other rollbacks are not failed so that multiple rollbacks can be staged together. Bug: 163734200 Test: atest RollbackManagerHostTest Change-Id: Iffb50d2a05f6ab0b6691fc84ffc273c2faecb88b --- .../com/android/server/pm/StagingManager.java | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index c842ff1b11a58..cb78636065aac 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -737,31 +737,31 @@ public class StagingManager { continue; } - // New session cannot have same package name as one of the active sessions - if (stagedSession.sessionContains(s -> s.getPackageName().equals(packageName))) { - if (isRollback) { - // If the new session is a rollback, then it gets priority. The existing - // session is failed to unblock rollback. - final StagedSession root = stagedSession; - if (!ensureActiveApexSessionIsAborted(root)) { - Slog.e(TAG, "Failed to abort apex session " + root.sessionId()); - // Safe to ignore active apex session abort failure since session - // will be marked failed on next step and staging directory for session - // will be deleted. - } - root.setSessionFailed( - SessionInfo.STAGED_SESSION_CONFLICT, - "Session was blocking rollback session: " + session.sessionId()); - Slog.i(TAG, "Session " + root.sessionId() + " is marked failed due to " - + "blocking rollback session: " + session.sessionId()); - } else { - throw new PackageManagerException( - SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, - "Package: " + session.getPackageName() + " in session: " - + session.sessionId() - + " has been staged already by session: " - + stagedSession.sessionId(), null); + if (isRollback && !isRollback(stagedSession)) { + // If the new session is a rollback, then it gets priority. The existing + // session is failed to reduce risk and avoid an SDK extension dependency + // violation. + final StagedSession root = stagedSession; + if (!ensureActiveApexSessionIsAborted(root)) { + Slog.e(TAG, "Failed to abort apex session " + root.sessionId()); + // Safe to ignore active apex session abort failure since session + // will be marked failed on next step and staging directory for session + // will be deleted. } + root.setSessionFailed( + SessionInfo.STAGED_SESSION_CONFLICT, + "Session was failed by rollback session: " + session.sessionId()); + Slog.i(TAG, "Session " + root.sessionId() + " is marked failed due to " + + "rollback session: " + session.sessionId()); + } else if (stagedSession.sessionContains( + s -> s.getPackageName().equals(packageName))) { + // New session cannot have same package name as one of the active sessions + throw new PackageManagerException( + SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, + "Package: " + session.getPackageName() + " in session: " + + session.sessionId() + + " has been staged already by session: " + + stagedSession.sessionId(), null); } // Staging multiple root sessions is not allowed if device doesn't support