Loading core/java/android/content/pm/PackageManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -1389,6 +1389,14 @@ public abstract class PackageManager { */ public static final int INSTALL_FAILED_BAD_SIGNATURE = -118; /** * Installation failed return code: a new staged session was attempted to be committed while * there is already one in-progress. * * @hide */ public static final int INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS = -119; /** @hide */ @IntDef(flag = true, prefix = { "DELETE_" }, value = { DELETE_KEEP_DATA, Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +14 −1 Original line number Diff line number Diff line Loading @@ -510,6 +510,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } /** {@hide} */ boolean isCommitted() { synchronized (mLock) { return mCommitted; } } @GuardedBy("mLock") private void assertPreparedAndNotSealedLocked(String cookie) { assertPreparedAndNotCommittedOrDestroyedLocked(cookie); Loading Loading @@ -1064,7 +1071,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private void handleCommit() { if (params.isStaged) { try { mStagingManager.commitSession(this); } catch (StagingManager.AlreadyInProgressStagedSessionException e) { dispatchSessionFinished( PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS, e.getMessage(), null); } destroyInternal(); dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null); return; Loading services/core/java/com/android/server/pm/StagingManager.java +43 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.apex.ApexInfo; import android.apex.ApexInfoList; import android.apex.ApexSessionInfo; Loading Loading @@ -479,11 +480,42 @@ public class StagingManager { return true; } void commitSession(@NonNull PackageInstallerSession session) { void commitSession(@NonNull PackageInstallerSession session) throws AlreadyInProgressStagedSessionException { PackageInstallerSession activeSession = getActiveSession(); boolean anotherSessionAlreadyInProgress = activeSession != null && session.sessionId != activeSession.sessionId; updateStoredSession(session); if (anotherSessionAlreadyInProgress) { session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "There is already in-progress committed staged session " + activeSession.sessionId); throw new AlreadyInProgressStagedSessionException(activeSession.sessionId); } mBgHandler.post(() -> preRebootVerification(session)); } @Nullable private PackageInstallerSession getActiveSession() { synchronized (mStagedSessions) { for (int i = 0; i < mStagedSessions.size(); i++) { final PackageInstallerSession session = mStagedSessions.valueAt(i); if (!session.isCommitted()) { continue; } if (session.hasParentSessionId()) { // Staging manager will finalize only parent session. Ignore child sessions // picking the active. continue; } if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) { return session; } } } return null; } void createSession(@NonNull PackageInstallerSession sessionInfo) { synchronized (mStagedSessions) { mStagedSessions.append(sessionInfo.sessionId, sessionInfo); Loading @@ -497,8 +529,8 @@ public class StagingManager { } void abortCommittedSession(@NonNull PackageInstallerSession session) { if (session.isStagedSessionApplied()) { Slog.w(TAG, "Cannot abort applied session!"); if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) { Slog.w(TAG, "Cannot abort already finalized session : " + session.sessionId); return; } abortSession(session); Loading Loading @@ -618,4 +650,12 @@ public class StagingManager { } } } static final class AlreadyInProgressStagedSessionException extends Exception { AlreadyInProgressStagedSessionException(int sessionId) { super("There is already in-progress committed staged session " + sessionId); } } } Loading
core/java/android/content/pm/PackageManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -1389,6 +1389,14 @@ public abstract class PackageManager { */ public static final int INSTALL_FAILED_BAD_SIGNATURE = -118; /** * Installation failed return code: a new staged session was attempted to be committed while * there is already one in-progress. * * @hide */ public static final int INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS = -119; /** @hide */ @IntDef(flag = true, prefix = { "DELETE_" }, value = { DELETE_KEEP_DATA, Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +14 −1 Original line number Diff line number Diff line Loading @@ -510,6 +510,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } /** {@hide} */ boolean isCommitted() { synchronized (mLock) { return mCommitted; } } @GuardedBy("mLock") private void assertPreparedAndNotSealedLocked(String cookie) { assertPreparedAndNotCommittedOrDestroyedLocked(cookie); Loading Loading @@ -1064,7 +1071,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private void handleCommit() { if (params.isStaged) { try { mStagingManager.commitSession(this); } catch (StagingManager.AlreadyInProgressStagedSessionException e) { dispatchSessionFinished( PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS, e.getMessage(), null); } destroyInternal(); dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null); return; Loading
services/core/java/com/android/server/pm/StagingManager.java +43 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.apex.ApexInfo; import android.apex.ApexInfoList; import android.apex.ApexSessionInfo; Loading Loading @@ -479,11 +480,42 @@ public class StagingManager { return true; } void commitSession(@NonNull PackageInstallerSession session) { void commitSession(@NonNull PackageInstallerSession session) throws AlreadyInProgressStagedSessionException { PackageInstallerSession activeSession = getActiveSession(); boolean anotherSessionAlreadyInProgress = activeSession != null && session.sessionId != activeSession.sessionId; updateStoredSession(session); if (anotherSessionAlreadyInProgress) { session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "There is already in-progress committed staged session " + activeSession.sessionId); throw new AlreadyInProgressStagedSessionException(activeSession.sessionId); } mBgHandler.post(() -> preRebootVerification(session)); } @Nullable private PackageInstallerSession getActiveSession() { synchronized (mStagedSessions) { for (int i = 0; i < mStagedSessions.size(); i++) { final PackageInstallerSession session = mStagedSessions.valueAt(i); if (!session.isCommitted()) { continue; } if (session.hasParentSessionId()) { // Staging manager will finalize only parent session. Ignore child sessions // picking the active. continue; } if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) { return session; } } } return null; } void createSession(@NonNull PackageInstallerSession sessionInfo) { synchronized (mStagedSessions) { mStagedSessions.append(sessionInfo.sessionId, sessionInfo); Loading @@ -497,8 +529,8 @@ public class StagingManager { } void abortCommittedSession(@NonNull PackageInstallerSession session) { if (session.isStagedSessionApplied()) { Slog.w(TAG, "Cannot abort applied session!"); if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) { Slog.w(TAG, "Cannot abort already finalized session : " + session.sessionId); return; } abortSession(session); Loading Loading @@ -618,4 +650,12 @@ public class StagingManager { } } } static final class AlreadyInProgressStagedSessionException extends Exception { AlreadyInProgressStagedSessionException(int sessionId) { super("There is already in-progress committed staged session " + sessionId); } } }