diff options
author | Tiger Huang <tigerhuang@google.com> | 2020-08-13 22:43:52 +0800 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-08-20 16:24:56 +0000 |
commit | bc03ee7cddeb4ead5d4df6b1b645f01241971599 (patch) | |
tree | a05eec4f14790a0b8eca85d3336856f46dd379a7 | |
parent | 45f74d0b5eb6ec674aa52aa574dc46bd55de13fa (diff) | |
download | base-bc03ee7cddeb4ead5d4df6b1b645f01241971599.tar.gz |
Update requested state after applying pending frames
When there is an insets animation, we will stop updating insets source
frames until the animation is done. The previous logic didn't update the
frames within the requested state while the animation is done. And the
frames was relied by InsetsPolicy while playing transient bar animation.
If the frames don't match the display, the insets would be wrong, and
the animation wouldn't be played correctly.
Fix: 161134197
Test: atest InsetsControllerTest
Merged-In: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81
Change-Id: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81
(cherry picked from commit 23c75281ef0de8fb2b44fb93d8cf36ecf86454c7)
-rw-r--r-- | core/java/android/view/InsetsController.java | 9 | ||||
-rw-r--r-- | core/tests/coretests/src/android/view/InsetsControllerTest.java | 14 |
2 files changed, 20 insertions, 3 deletions
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index e9b7695e7b71..403ac3ab29c0 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -1138,15 +1138,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (invokeCallback) { control.cancel(); } + boolean stateChanged = false; for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); if (runningAnimation.runner == control) { mRunningAnimations.remove(i); ArraySet<Integer> types = toInternalType(control.getTypes()); for (int j = types.size() - 1; j >= 0; j--) { - if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) { - mHost.notifyInsetsChanged(); - } + stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished(); } if (invokeCallback && runningAnimation.startDispatched) { dispatchAnimationEnd(runningAnimation.runner.getAnimation()); @@ -1154,6 +1153,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; } } + if (stateChanged) { + mHost.notifyInsetsChanged(); + updateRequestedState(); + } } private void applyLocalVisibilityOverride() { diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index af02b7bdbd90..de128ad6d78e 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -746,6 +746,20 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); + + // The modified frames cannot be updated if there is an animation. + mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR)); + mController.hide(navigationBars()); + newState = new InsetsState(mController.getState(), true /* copySource */); + newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--; + mController.onStateChanged(newState); + assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); + + // The modified frames can be updated while the animation is done. + mController.cancelExistingAnimations(); + assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); }); } |