Force-finish pending cancellation of the recents animation when process dies

- If the recents animation is cancelled, then we need to continue the
  deferred cancel when the process dies to ensure that the animation
  is cleaned up correctly (just calling cancel will no-op if the
  animation was already canceled and waiting for cleanupScreenshot()).

  This call to continue the deferred cancel is a no-op if there is no
  deferred cleanup.

Bug: 192564669
Test: atest RecentsAnimationControllerTest
Test: Defer cleanupScreenshot() and kill launcher process after canceling
Change-Id: I500b12dff2b3263e9e1529b4c094e4a422762d66
This commit is contained in:
Winson Chung
2021-07-12 14:17:46 -07:00
parent 224f71520f
commit 8bf6885893
2 changed files with 30 additions and 1 deletions

View File

@@ -1029,7 +1029,13 @@ public class RecentsAnimationController implements DeathRecipient {
@Override
public void binderDied() {
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
if (!mCanceled) {
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
} else {
// If we are already canceled but with a screenshot, and are waiting for the
// cleanupScreenshot() callback, then force-finish the animation now
continueDeferredCancelAnimation();
}
synchronized (mService.getWindowManagerLock()) {
// Clear associated input consumers on runner death

View File

@@ -306,6 +306,29 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
assertTrue(activity.shouldAnimate());
}
@Test
public void testBinderDiedAfterCancelWithDeferredScreenshot() throws Exception {
mWm.setRecentsAnimationController(mController);
final ActivityRecord homeActivity = createHomeActivity();
final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
activity.addWindow(win1);
initializeRecentsAnimationController(mController, homeActivity);
mController.setWillFinishToHome(true);
// Verify cancel is called with a snapshot and that we've created an overlay
spyOn(mWm.mTaskSnapshotController);
doReturn(mMockTaskSnapshot).when(mWm.mTaskSnapshotController).getSnapshot(anyInt(),
anyInt(), eq(false) /* restoreFromDisk */, eq(false) /* isLowResolution */);
mController.cancelAnimationWithScreenshot(true /* screenshot */);
verify(mMockRunner).onAnimationCanceled(any());
// Simulate process crashing and ensure the animation is still canceled
mController.binderDied();
verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, false);
}
@Test
public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
unblockDisplayRotation(mDefaultDisplay);