Loading services/core/java/com/android/server/pm/StagingManager.java +21 −14 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading @@ -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 Loading services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; } Loading Loading
services/core/java/com/android/server/pm/StagingManager.java +21 −14 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading @@ -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 Loading
services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; } Loading