Loading core/java/android/view/InsetsController.java +4 −4 Original line number Diff line number Diff line Loading @@ -1292,18 +1292,18 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation continue; } final boolean isImeAnimation = type == ime(); @AnimationType final int animationType = getAnimationType(type); if (isImeAnimation) { // When the IME is requested to be hidden, but already hidden, we don't show // an animation again (mRequestedVisibleTypes are reported at the end of the IME // hide animation but set at the beginning) if ((mRequestedVisibleTypes & ime()) == 0) { if ((mRequestedVisibleTypes & ime()) == 0 && animationType != ANIMATION_TYPE_USER) { ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); continue; } } @AnimationType final int animationType = getAnimationType(type); final boolean requestedVisible = (type & mRequestedVisibleTypes) != 0; if (mPendingImeControlRequest != null && !requestedVisible) { // Remove the hide insets type from the pending show request. Loading @@ -1313,7 +1313,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } if (!requestedVisible && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_HIDE || (animationType || animationType == ANIMATION_TYPE_HIDE || (isImeAnimation && animationType == ANIMATION_TYPE_USER && mIsPredictiveBackImeHideAnimInProgress)) { // no-op: already hidden or animating out (because window visibility is // applied before starting animation). Loading core/tests/coretests/src/android/view/InsetsControllerTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -1073,6 +1073,32 @@ public class InsetsControllerTest { }); } @Test public void testImeHideRequestExecutedDuringPredictiveBackPreCommitAnim() { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state mController.show(ime(), ImeTracker.Token.empty()); mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); // start control request (for predictive back animation) WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); mController.controlWindowInsetsAnimation(ime(), /*cancellationSignal*/ null, listener, /*duration*/ -1, /*interpolator*/ null, ANIMATION_TYPE_USER, /*fromPredictiveBack*/ true); // verify that controller has ANIMATION_TYPE_USER set for ime() assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify hide request is executed during pre commit phase of predictive back anim mController.hide(ime(), null /* statsToken */); assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(ime())); }); } @Test public void testPredictiveBackControlRequestCancelledDuringImeHideAnim() { prepareControls(); Loading Loading
core/java/android/view/InsetsController.java +4 −4 Original line number Diff line number Diff line Loading @@ -1292,18 +1292,18 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation continue; } final boolean isImeAnimation = type == ime(); @AnimationType final int animationType = getAnimationType(type); if (isImeAnimation) { // When the IME is requested to be hidden, but already hidden, we don't show // an animation again (mRequestedVisibleTypes are reported at the end of the IME // hide animation but set at the beginning) if ((mRequestedVisibleTypes & ime()) == 0) { if ((mRequestedVisibleTypes & ime()) == 0 && animationType != ANIMATION_TYPE_USER) { ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); continue; } } @AnimationType final int animationType = getAnimationType(type); final boolean requestedVisible = (type & mRequestedVisibleTypes) != 0; if (mPendingImeControlRequest != null && !requestedVisible) { // Remove the hide insets type from the pending show request. Loading @@ -1313,7 +1313,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } if (!requestedVisible && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_HIDE || (animationType || animationType == ANIMATION_TYPE_HIDE || (isImeAnimation && animationType == ANIMATION_TYPE_USER && mIsPredictiveBackImeHideAnimInProgress)) { // no-op: already hidden or animating out (because window visibility is // applied before starting animation). Loading
core/tests/coretests/src/android/view/InsetsControllerTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -1073,6 +1073,32 @@ public class InsetsControllerTest { }); } @Test public void testImeHideRequestExecutedDuringPredictiveBackPreCommitAnim() { prepareControls(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // show ime as initial state mController.show(ime(), ImeTracker.Token.empty()); mController.cancelExistingAnimations(); // fast forward show animation mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw(); assertTrue(mController.getState().peekSource(ID_IME).isVisible()); // start control request (for predictive back animation) WindowInsetsAnimationControlListener listener = mock(WindowInsetsAnimationControlListener.class); mController.controlWindowInsetsAnimation(ime(), /*cancellationSignal*/ null, listener, /*duration*/ -1, /*interpolator*/ null, ANIMATION_TYPE_USER, /*fromPredictiveBack*/ true); // verify that controller has ANIMATION_TYPE_USER set for ime() assertEquals(ANIMATION_TYPE_USER, mController.getAnimationType(ime())); // verify hide request is executed during pre commit phase of predictive back anim mController.hide(ime(), null /* statsToken */); assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(ime())); }); } @Test public void testPredictiveBackControlRequestCancelledDuringImeHideAnim() { prepareControls(); Loading