Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d091b427 authored by Liran Binyamin's avatar Liran Binyamin Committed by Android (Google) Code Review
Browse files

Merge "Interrupt bubble animation when IME is visible" into main

parents c4020486 05eaeb29
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -115,7 +115,6 @@ public class BubbleBarController extends IBubblesListener.Stub {
    private BubbleBarItem mSelectedBubble;

    private TaskbarSharedState mSharedState;
    private ImeVisibilityChecker mImeVisibilityChecker;
    private BubbleBarViewController mBubbleBarViewController;
    private BubbleStashController mBubbleStashController;
    private Optional<BubbleStashedHandleViewController> mBubbleStashedHandleViewController;
@@ -126,6 +125,8 @@ public class BubbleBarController extends IBubblesListener.Stub {
    // Cache last sent top coordinate to avoid sending duplicate updates to shell
    private int mLastSentBubbleBarTop;

    private boolean mIsImeVisible = false;

    /**
     * Similar to {@link BubbleBarUpdate} but rather than {@link BubbleInfo}s it uses
     * {@link BubbleBarBubble}s so that it can be used to update the views.
@@ -192,10 +193,8 @@ public class BubbleBarController extends IBubblesListener.Stub {
    /** Initializes controllers. */
    public void init(BubbleControllers bubbleControllers,
            BubbleBarLocationListener bubbleBarLocationListener,
            ImeVisibilityChecker imeVisibilityChecker,
            TaskbarSharedState sharedState) {
        mSharedState = sharedState;
        mImeVisibilityChecker = imeVisibilityChecker;
        mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
        mBubbleStashController = bubbleControllers.bubbleStashController;
        mBubbleStashedHandleViewController = bubbleControllers.bubbleStashedHandleViewController;
@@ -234,6 +233,10 @@ public class BubbleBarController extends IBubblesListener.Stub {

        boolean sysuiLocked = (flags & MASK_SYSUI_LOCKED) != 0;
        mBubbleStashController.setSysuiLocked(sysuiLocked);
        mIsImeVisible = (flags & SYSUI_STATE_IME_SHOWING) != 0;
        if (mIsImeVisible) {
            mBubbleBarViewController.onImeVisible();
        }
    }

    //
@@ -309,8 +312,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
        // enabling gesture nav. also suppress animation if the bubble bar is hidden for sysui e.g.
        // the shade is open, or we're locked.
        final boolean suppressAnimation =
                update.initialState || mBubbleBarViewController.isHiddenForSysui()
                        || mImeVisibilityChecker.isImeVisible();
                update.initialState || mBubbleBarViewController.isHiddenForSysui() || mIsImeVisible;

        if (update.initialState && mSharedState.hasSavedBubbles()) {
            // clear restored state
@@ -572,12 +574,6 @@ public class BubbleBarController extends IBubblesListener.Stub {
        mBubbleBarViewController.addBubble(bubble, isExpanding, suppressAnimation);
    }

    /** Interface for checking whether the IME is visible. */
    public interface ImeVisibilityChecker {
        /** Whether the IME is visible. */
        boolean isImeVisible();
    }

    /** Listener of {@link BubbleBarLocation} updates. */
    public interface BubbleBarLocationListener {

+7 −0
Original line number Diff line number Diff line
@@ -391,6 +391,13 @@ public class BubbleBarViewController {
        }
    }

    /** Notifies that the IME became visible. */
    public void onImeVisible() {
        if (isAnimatingNewBubble()) {
            mBubbleBarViewAnimator.interruptForIme();
        }
    }

    //
    // The below animators are exposed to BubbleStashController so it can manage the stashing
    // animation.
+0 −1
Original line number Diff line number Diff line
@@ -89,7 +89,6 @@ public class BubbleControllers {
                );
        bubbleBarController.init(this,
                bubbleBarLocationListeners,
                taskbarControllers.navbarButtonsViewController::isImeVisible,
                taskbarSharedState);
        bubbleStashedHandleViewController.ifPresent(
                controller -> controller.init(/* bubbleControllers = */ this));
+15 −0
Original line number Diff line number Diff line
@@ -532,6 +532,21 @@ constructor(
        )
    }

    /** Interrupts the animation due to the IME becoming visible. */
    fun interruptForIme() {
        cancelFlyout()
        val hideAnimation = animatingBubble?.hideAnimation ?: return
        scheduler.cancel(hideAnimation)
        animatingBubble = null
        bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
        bubbleBarView.relativePivotY = 1f
        // stash the bubble bar since the IME is now visible
        bubbleStashController.onNewBubbleAnimationInterrupted(
            /* isStashed= */ true,
            bubbleBarView.translationY,
        )
    }

    fun expandedWhileAnimating() {
        val animatingBubble = animatingBubble ?: return
        this.animatingBubble = animatingBubble.copy(expand = true)
+45 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.atLeastOnce
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -1266,6 +1267,50 @@ class BubbleBarViewAnimatorTest {
        verify(bubbleStashController).stashBubbleBarImmediate()
    }

    @Test
    fun interruptForIme() {
        setUpBubbleBar()
        setUpBubbleStashController()

        val handle = View(context)
        val handleAnimator = PhysicsAnimator.getInstance(handle)
        whenever(bubbleStashController.getStashedHandlePhysicsAnimator()).thenReturn(handleAnimator)

        val animator =
            BubbleBarViewAnimator(
                bubbleBarView,
                bubbleStashController,
                flyoutController,
                onExpandedNoOp,
                animatorScheduler,
            )

        InstrumentationRegistry.getInstrumentation().runOnMainSync {
            animator.animateBubbleInForStashed(bubble, isExpanding = false)
        }

        // wait for the animation to start
        InstrumentationRegistry.getInstrumentation().runOnMainSync {}
        PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(handleAnimator) { true }

        handleAnimator.assertIsRunning()
        assertThat(animator.isAnimating).isTrue()
        // verify the hide bubble animation is pending
        assertThat(animatorScheduler.delayedBlock).isNotNull()

        InstrumentationRegistry.getInstrumentation().runOnMainSync { animator.interruptForIme() }

        // verify that the hide animation was canceled
        assertThat(animatorScheduler.delayedBlock).isNull()
        assertThat(animator.isAnimating).isFalse()
        verify(bubbleStashController).onNewBubbleAnimationInterrupted(eq(true), any())

        // PhysicsAnimatorTestUtils posts the cancellation to the main thread so we need to wait
        // again
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        handleAnimator.assertIsNotRunning()
    }

    private fun setUpBubbleBar() {
        bubbleBarView = BubbleBarView(context)
        InstrumentationRegistry.getInstrumentation().runOnMainSync {