Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9363a78 authored by JW Wang's avatar JW Wang Committed by Android (Google) Code Review
Browse files

Merge "Fail a staged session when a rollback is already staged (1/n)"

parents ec77302b de724db9
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -652,6 +652,7 @@ public class StagingManager {
     * </ul>
     * @throws PackageManagerException if session fails the check
     */
    // TODO(b/192625695): Rename this method which checks rollbacks in addition to overlapping
    @VisibleForTesting
    void checkNonOverlappingWithStagedSessions(@NonNull StagedSession session)
            throws PackageManagerException {
@@ -685,13 +686,6 @@ public class StagingManager {
                    continue;
                }

                if (stagedSession.getCommittedMillis() > session.getCommittedMillis()) {
                    // Ignore sessions that are committed after the provided session. When there are
                    // overlaps between sessions, we will fail the one committed later instead of
                    // the earlier one.
                    continue;
                }

                // From here on, stagedSession is a parent active staged session

                // Check if session is one of the active sessions
@@ -716,15 +710,28 @@ public class StagingManager {
                            "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 (!isRollback && isRollback(stagedSession)) {
                    throw new PackageManagerException(
                            SessionInfo.STAGED_SESSION_CONFLICT,
                            "Session was failed by rollback session: " + stagedSession.sessionId());
                } else if (stagedSession.sessionContains(
                        s -> s.getPackageName().equals(packageName))) {
                    // New session cannot have same package name as one of the active sessions
                    // Fail the session committed later when there are overlapping packages
                    if (stagedSession.getCommittedMillis() < session.getCommittedMillis()) {
                        throw new PackageManagerException(
                                SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                                "Package: " + session.getPackageName() + " in session: "
                                        + session.sessionId()
                                        + " has been staged already by session: "
                                        + stagedSession.sessionId(), null);
                    } else {
                        stagedSession.setSessionFailed(
                                SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                                "Package: " + packageName + " in session: "
                                        + stagedSession.sessionId()
                                        + " has been staged already by session: "
                                        + session.sessionId());
                    }
                }

                // Staging multiple root sessions is not allowed if device doesn't support
+11 −2
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package com.android.server.pm;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -123,9 +125,15 @@ public class StagingManagerTest {
        mStagingManager.createSession(session2);
        // Session1 should not fail in spite of the overlapping packages
        mStagingManager.checkNonOverlappingWithStagedSessions(session1);
        // Session2 should fail due to overlapping packages
        // setSessionFailed() should've been called when doing overlapping checks on session1
        verify(session2, times(1)).setSessionFailed(anyInt(), anyString());

        // Yet another session with overlapping packages
        StagingManager.StagedSession session3 = createSession(333, "com.foo", 3);
        mStagingManager.createSession(session3);
        assertThrows(PackageManagerException.class,
                () -> mStagingManager.checkNonOverlappingWithStagedSessions(session2));
                () -> mStagingManager.checkNonOverlappingWithStagedSessions(session3));
        verify(session3, never()).setSessionFailed(anyInt(), anyString());
    }

    @Test
@@ -505,6 +513,7 @@ public class StagingManagerTest {
            Predicate<StagingManager.StagedSession> filter = invocation.getArgument(0);
            return filter.test(stagedSession);
        }).when(stagedSession).sessionContains(any());
        doNothing().when(stagedSession).setSessionFailed(anyInt(), anyString());
        return stagedSession;
    }