From f103588cc1d6b783424f1ce73798258ec9b5af35 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Tue, 31 Mar 2020 22:47:12 +0200 Subject: [PATCH] Fix missing finish callback to fix running animation leak Make sure finish callback gets called when applyChangeInsets gets called synchronously from scheduleApplyChangeInsets Bug: 152071027 Test: InsetsAnimationControlImplTest Change-Id: I6808b3527f1d2e15de681c5260208d238dcf53e2 --- .../view/InsetsAnimationControlImpl.java | 10 ++++++++-- .../view/InsetsAnimationControlImplTest.java | 17 +++++++++++++++++ .../com/android/server/wm/InsetsPolicy.java | 1 - 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index 07b6cc1c22d26..abc4ee772e24e 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -136,7 +136,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll @Override public void setInsetsAndAlpha(Insets insets, float alpha, float fraction) { - if (mFinished) { + setInsetsAndAlpha(insets, alpha, fraction, false /* allowWhenFinished */); + } + + private void setInsetsAndAlpha(Insets insets, float alpha, float fraction, + boolean allowWhenFinished) { + if (!allowWhenFinished && mFinished) { throw new IllegalStateException( "Can't change insets on an animation that is finished."); } @@ -197,8 +202,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll return; } mShownOnFinish = shown; - setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */); mFinished = true; + setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */, + true /* allowWhenFinished */); mListener.onFinished(this); } diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java index d78746918e656..588f0adc162f1 100644 --- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -206,6 +207,22 @@ public class InsetsAnimationControlImplTest { mController.finish(true /* shown */); } + @Test + public void testFinish_immediately() { + when(mMockController.getState()).thenReturn(mInsetsState); + doAnswer(invocation -> { + mController.applyChangeInsets(mInsetsState); + return null; + }).when(mMockController).scheduleApplyChangeInsets(); + mController.finish(true /* shown */); + assertEquals(Insets.of(0, 100, 100, 0), mController.getCurrentInsets()); + verify(mMockController).notifyFinished(eq(mController), eq(true /* shown */)); + assertFalse(mController.isReady()); + assertTrue(mController.isFinished()); + assertFalse(mController.isCancelled()); + verify(mMockListener).onFinished(mController); + } + private void assertPosition(Matrix m, Rect original, Rect transformed) { RectF rect = new RectF(original); rect.offsetTo(0, 0); diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index b2f5988719cfb..9e954f29438c6 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -367,7 +367,6 @@ class InsetsPolicy { @Override protected void onAnimationFinish() { super.onAnimationFinish(); - mControlCallbacks.mAnimationControl.finish(mAnimatingShown); DisplayThread.getHandler().post(mFinishCallback); }