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
This commit is contained in:
Tiger Huang
2020-08-13 22:43:52 +08:00
parent f8175d1a5b
commit 23c75281ef
2 changed files with 20 additions and 3 deletions

View File

@@ -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() {

View File

@@ -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));
});
}