diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 553b4fe531155..9da69170654c1 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -426,9 +426,13 @@ public class RecentsAnimationController implements DeathRecipient { removeAnimation(taskAdapter); } + // Clear any pending failsafe runnables + mService.mH.removeCallbacks(mFailsafeRunnable); + // Clear references to the runner unlinkToDeathOfRunner(); mRunner = null; + mCanceled = true; // Clear associated input consumers mService.mInputMonitor.updateInputWindowsLw(true /*force*/); diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java index fbf6691f5bd28..a2af9b80fe363 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -19,6 +19,9 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; @@ -82,6 +85,25 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { verifyNoMoreInteractionsExceptAsBinder(mMockRunner); } + @Test + public void testCancelAfterRemove_expectIgnored() throws Exception { + final AppWindowToken appWindow = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(), + false /* isRecentTaskInvisible */); + adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback); + + // Remove the app window so that the animation target can not be created + appWindow.removeImmediately(); + mController.startAnimation(); + mController.cleanupAnimation(REORDER_KEEP_IN_PLACE); + try { + mController.cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "test"); + } catch (Exception e) { + fail("Unexpected failure when canceling animation after finishing it"); + } + } + private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { verify(binder, atLeast(0)).asBinder(); verifyNoMoreInteractions(binder);