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

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

Merge "Wire up flyout to new bubble animation" into main

parents c1c1c873 12f77ba7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,4 +19,6 @@
    <item type="id" name="action_move_left" />
    <item type="id" name="action_move_right" />
    <item type="id" name="action_dismiss_all" />

    <item type="id" name="bubble_bar_flyout_view" />
</resources>
 No newline at end of file
+0 −2
Original line number Diff line number Diff line
@@ -377,8 +377,6 @@ public class BubbleBarController extends IBubblesListener.Stub {
            // Updates mean the dot state may have changed; any other changes were updated in
            // the populateBubble step.
            BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey());
            // If we're not stashed, we're visible so animate
            bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */);
            mBubbleBarViewController.animateBubbleNotification(
                    bb, /* isExpanding= */ false, /* isUpdate= */ true);
        }
+9 −4
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ public class BubbleBarViewController {
        mBubbleBarFlyoutController = new BubbleBarFlyoutController(
                mBubbleBarContainer, createFlyoutPositioner(), createFlyoutTopBoundaryListener());
        mBubbleBarViewAnimator = new BubbleBarViewAnimator(
                mBarView, mBubbleStashController, mBubbleBarController::showExpandedView);
                mBarView, mBubbleStashController, mBubbleBarFlyoutController,
                mBubbleBarController::showExpandedView);
        mTaskbarViewPropertiesProvider = taskbarViewPropertiesProvider;
        onBubbleBarConfigurationChanged(/* animate= */ false);
        mActivity.addOnDeviceProfileChangeListener(
@@ -781,6 +782,11 @@ public class BubbleBarViewController {
    /** Animates the bubble bar to notify the user about a bubble change. */
    public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding,
            boolean isUpdate) {
        // if we're expanded, don't animate the bubble bar. just show the notification dot.
        if (isExpanded()) {
            bubble.getView().updateDotVisibility(/* animate= */ true);
            return;
        }
        boolean isInApp = mTaskbarStashController.isInApp();
        // if this is the first bubble, animate to the initial state.
        if (mBarView.getBubbleChildCount() == 1 && !isUpdate) {
@@ -789,13 +795,12 @@ public class BubbleBarViewController {
        }
        boolean persistentTaskbarOrOnHome = mBubbleStashController.isBubblesShowingOnHome()
                || !mBubbleStashController.isTransientTaskBar();
        if (persistentTaskbarOrOnHome && !isExpanded()) {
        if (persistentTaskbarOrOnHome) {
            mBubbleBarViewAnimator.animateBubbleBarForCollapsed(bubble, isExpanding);
            return;
        }

        // only animate the new bubble if we're in an app, have handle view and not auto expanding
        if (isInApp && mBubbleStashController.getHasHandleView() && !isExpanded()) {
        if (isInApp && mBubbleStashController.getHasHandleView()) {
            mBubbleBarViewAnimator.animateBubbleInForStashed(bubble, isExpanding);
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -301,7 +301,7 @@ public class BubbleView extends ConstraintLayout {

    void updateDotVisibility(boolean animate) {
        if (mDotSuppressedForBubbleUpdate) {
            // if the dot is suppressed for
            // if the dot is suppressed for an update, there's nothing to do
            return;
        }
        final float targetScale = hasUnseenContent() ? 1f : 0f;
+63 −16
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import com.android.launcher3.R
import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleView
import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController
import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.wm.shell.shared.animation.PhysicsAnimator

@@ -36,8 +38,9 @@ class BubbleBarViewAnimator
constructor(
    private val bubbleBarView: BubbleBarView,
    private val bubbleStashController: BubbleStashController,
    private val bubbleBarFlyoutController: BubbleBarFlyoutController,
    private val onExpanded: Runnable,
    private val scheduler: Scheduler = HandlerScheduler(bubbleBarView)
    private val scheduler: Scheduler = HandlerScheduler(bubbleBarView),
) {

    private var animatingBubble: AnimatingBubble? = null
@@ -54,7 +57,7 @@ constructor(

    private companion object {
        /** The time to show the flyout. */
        const val FLYOUT_DELAY_MS: Long = 2500
        const val FLYOUT_DELAY_MS: Long = 3000
        /** The initial scale Y value that the new bubble is set to before the animation starts. */
        const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
        /** The minimum alpha value to make the bubble bar touchable. */
@@ -69,7 +72,7 @@ constructor(
        val showAnimation: Runnable,
        val hideAnimation: Runnable,
        val expand: Boolean,
        val state: State = State.CREATED
        val state: State = State.CREATED,
    ) {

        /**
@@ -91,7 +94,7 @@ constructor(
            /** The bubble notification is now fully showing and waiting to be hidden. */
            IN,
            /** The bubble notification is animating out. */
            ANIMATING_OUT
            ANIMATING_OUT,
        }
    }

@@ -127,7 +130,7 @@ constructor(
    private val springConfig =
        PhysicsAnimator.SpringConfig(
            stiffness = SpringForce.STIFFNESS_LOW,
            dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
            dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY,
        )

    /** Animates a bubble for the state where the bubble bar is stashed. */
@@ -137,8 +140,9 @@ constructor(
        val bubbleView = b.view
        val animator = PhysicsAnimator.getInstance(bubbleView)
        if (animator.isRunning()) animator.cancel()
        // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
        // and the second part hides it after a delay.
        // the animation of a new bubble is divided into 2 parts. The first part transforms the
        // handle to the bubble bar and then shows the flyout. The second part hides the flyout and
        // transforms the bubble bar back to the handle.
        val showAnimation = buildHandleToBubbleBarAnimation()
        val hideAnimation = if (isExpanding) Runnable {} else buildBubbleBarToHandleAnimation()
        animatingBubble =
@@ -243,7 +247,8 @@ constructor(
                cancelHideAnimation()
                return@addEndListener
            }
            moveToState(AnimatingBubble.State.IN)
            setupAndShowFlyout()

            // the bubble bar is now fully settled in. update taskbar touch region so it's touchable
            bubbleStashController.updateTaskbarTouchRegion()
        }
@@ -316,8 +321,18 @@ constructor(
            bubbleBarView.scaleY = 1f
            bubbleStashController.updateTaskbarTouchRegion()
        }

        val bubble = animatingBubble?.bubbleView?.bubble as? BubbleBarBubble
        val flyout = bubble?.flyoutMessage
        if (flyout != null) {
            bubbleBarFlyoutController.collapseFlyout {
                onFlyoutRemoved(bubble.view)
                animator.start()
            }
        } else {
            animator.start()
        }
    }

    /** Animates to the initial state of the bubble bar, when there are no previous bubbles. */
    fun animateToInitialState(b: BubbleBarBubble, isInApp: Boolean, isExpanding: Boolean) {
@@ -326,16 +341,16 @@ constructor(
        val bubbleView = b.view
        val animator = PhysicsAnimator.getInstance(bubbleView)
        if (animator.isRunning()) animator.cancel()
        // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
        // and the second part hides it after a delay if we are in an app.
        // the animation of a new bubble is divided into 2 parts. The first part slides in the
        // bubble bar and shows the flyout. The second part hides the flyout and transforms the
        // bubble bar to the handle if we're in an app.
        val showAnimation = buildBubbleBarSpringInAnimation()
        val hideAnimation =
            if (isInApp && !isExpanding) {
                buildBubbleBarToHandleAnimation()
            } else {
                // in this case the bubble bar remains visible so not much to do. once we implement
                // the flyout we'll update this runnable to hide it.
                Runnable {
                    bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
                    animatingBubble = null
                    bubbleStashController.showBubbleBarImmediate()
                    bubbleStashController.updateTaskbarTouchRegion()
@@ -370,7 +385,7 @@ constructor(
            if (animatingBubble?.expand == true) {
                cancelHideAnimation()
            } else {
                moveToState(AnimatingBubble.State.IN)
                setupAndShowFlyout()
            }
            // the bubble bar is now fully settled in. update taskbar touch region so it's touchable
            bubbleStashController.updateTaskbarTouchRegion()
@@ -384,8 +399,10 @@ constructor(
        val bubbleView = b.view
        val animator = PhysicsAnimator.getInstance(bubbleView)
        if (animator.isRunning()) animator.cancel()
        // first bounce the bubble bar and show the flyout. Then hide the flyout.
        val showAnimation = buildBubbleBarBounceAnimation()
        val hideAnimation = Runnable {
            bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
            animatingBubble = null
            bubbleStashController.showBubbleBarImmediate()
            bubbleStashController.updateTaskbarTouchRegion()
@@ -413,7 +430,7 @@ constructor(
                expandBubbleBar()
                cancelHideAnimation()
            } else {
                moveToState(AnimatingBubble.State.IN)
                setupAndShowFlyout()
            }
        }

@@ -427,10 +444,38 @@ constructor(
            .start()
    }

    private fun setupAndShowFlyout() {
        val bubbleView = animatingBubble?.bubbleView
        val bubble = bubbleView?.bubble as? BubbleBarBubble
        val flyout = bubble?.flyoutMessage
        if (flyout != null) {
            bubbleView.suppressDotForBubbleUpdate(true)
            bubbleBarFlyoutController.setUpAndShowFlyout(
                BubbleBarFlyoutMessage(flyout.icon, flyout.title, flyout.message)
            ) {
                moveToState(AnimatingBubble.State.IN)
                bubbleStashController.updateTaskbarTouchRegion()
            }
        } else {
            moveToState(AnimatingBubble.State.IN)
        }
    }

    private fun cancelFlyout() {
        val bubbleView = animatingBubble?.bubbleView
        bubbleBarFlyoutController.cancelFlyout { onFlyoutRemoved(bubbleView) }
    }

    private fun onFlyoutRemoved(bubbleView: BubbleView?) {
        bubbleView?.suppressDotForBubbleUpdate(false)
        bubbleStashController.updateTaskbarTouchRegion()
    }

    /** Handles touching the animating bubble bar. */
    fun onBubbleBarTouchedWhileAnimating() {
        PhysicsAnimator.getInstance(bubbleBarView).cancelIfRunning()
        bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
        cancelFlyout()
        val hideAnimation = animatingBubble?.hideAnimation ?: return
        scheduler.cancel(hideAnimation)
        bubbleBarView.relativePivotY = 1f
@@ -439,6 +484,7 @@ constructor(

    /** Notifies the animator that the taskbar area was touched during an animation. */
    fun onStashStateChangingWhileAnimating() {
        cancelFlyout()
        val hideAnimation = animatingBubble?.hideAnimation ?: return
        scheduler.cancel(hideAnimation)
        animatingBubble = null
@@ -446,7 +492,7 @@ constructor(
        bubbleBarView.relativePivotY = 1f
        bubbleStashController.onNewBubbleAnimationInterrupted(
            /* isStashed= */ bubbleBarView.alpha == 0f,
            bubbleBarView.translationY
            bubbleBarView.translationY,
        )
    }

@@ -455,6 +501,7 @@ constructor(
        this.animatingBubble = animatingBubble.copy(expand = true)
        // if we're fully in and waiting to hide, cancel the hide animation and clean up
        if (animatingBubble.state == AnimatingBubble.State.IN) {
            cancelFlyout()
            expandBubbleBar()
            cancelHideAnimation()
        }
Loading