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

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

Merge "Handle taps on the animating bubble" into main

parents 46776af4 a87abece
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -153,6 +153,16 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
                context.deviceProfile.widthPx,
                windowLayoutParams.height
            )

            // if there's an animating bubble add it to the touch region so that it's clickable
            val animatingBubbleBounds =
                controllers.bubbleControllers
                    .getOrNull()
                    ?.bubbleBarViewController
                    ?.animatingBubbleBounds
            if (animatingBubbleBounds != null) {
                defaultTouchableRegion.op(animatingBubbleBounds, Region.Op.UNION)
            }
        }

        // Pre-calculate insets for different providers across different rotations for this gravity
+32 −1
Original line number Diff line number Diff line
@@ -104,6 +104,8 @@ public class BubbleBarView extends FrameLayout {
     * updates the bounds and accounts for translation.
     */
    private final Rect mBubbleBarBounds = new Rect();
    /** The bounds of the animating bubble in the coordinate space of the BubbleBarView. */
    private final Rect mAnimatingBubbleBounds = new Rect();
    // The amount the bubbles overlap when they are stacked in the bubble bar
    private final float mIconOverlapAmount;
    // The spacing between the bubbles when bubble bar is expanded
@@ -460,6 +462,30 @@ public class BubbleBarView extends FrameLayout {
        return mBubbleBarBounds;
    }

    /** Returns the bounds of the animating bubble, or {@code null} if no bubble is animating. */
    @Nullable
    public Rect getAnimatingBubbleBounds() {
        if (mIsAnimatingNewBubble) {
            return mAnimatingBubbleBounds;
        }
        return null;
    }

    /**
     * Updates the animating bubble bounds. This should be called when the bubble is fully animated
     * in so that we can include it in taskbar touchable region.
     *
     * <p>The bounds are adjusted to the coordinate space of BubbleBarView so that it can be used
     * by taskbar.
     */
    public void updateAnimatingBubbleBounds(int left, int top, int width, int height) {
        Rect bubbleBarBounds = getBubbleBarBounds();
        mAnimatingBubbleBounds.left = bubbleBarBounds.left + left;
        mAnimatingBubbleBounds.top = bubbleBarBounds.top + top;
        mAnimatingBubbleBounds.right = mAnimatingBubbleBounds.left + width;
        mAnimatingBubbleBounds.bottom = mAnimatingBubbleBounds.top + height;
    }

    /**
     * Set bubble bar relative pivot value for X and Y, applied as a fraction of view width/height
     * respectively. If the value is not in range of 0 to 1 it will be normalized.
@@ -852,10 +878,15 @@ public class BubbleBarView extends FrameLayout {

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (!mIsBarExpanded) {
        if (!mIsBarExpanded && !mIsAnimatingNewBubble) {
            // When the bar is collapsed, all taps on it should expand it.
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

    /** Whether a new bubble is currently animating. */
    public boolean isAnimatingNewBubble() {
        return mIsAnimatingNewBubble;
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -138,6 +138,15 @@ public class BubbleBarViewController {
        if (bubble == null) {
            Log.e(TAG, "bubble click listener, bubble was null");
        }

        if (mBarView.isAnimatingNewBubble()) {
            mBubbleBarViewAnimator.onBubbleClickedWhileAnimating();
            mBubbleStashController.showBubbleBarImmediate();
            setExpanded(true);
            mBubbleBarController.showAndSelectBubble(bubble);
            return;
        }

        final String currentlySelected = mBubbleBarController.getSelectedBubbleKey();
        if (mBarView.isExpanded() && Objects.equals(bubble.getKey(), currentlySelected)) {
            // Tapping the currently selected bubble while expanded collapses the view.
@@ -213,6 +222,12 @@ public class BubbleBarViewController {
        return mBarView.getBubbleBarBounds();
    }

    /** The bounds of the animating bubble, or {@code null} if no bubble is animating. */
    @Nullable
    public Rect getAnimatingBubbleBounds() {
        return mBarView.getAnimatingBubbleBounds();
    }

    /** The horizontal margin of the bubble bar from the edge of the screen. */
    public int getHorizontalMargin() {
        return mBarView.getHorizontalMargin();
+16 −1
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ public class BubbleStashController {
                hotseatCellHeight - mUnstashedHeight) / 2;
    }

    float getBubbleBarTranslationY() {
    public float getBubbleBarTranslationY() {
        // If we're on home, adjust the translation so the bubble bar aligns with hotseat.
        // Otherwise we're either showing in an app or in overview. In either case adjust it so
        // the bubble bar aligns with the taskbar.
@@ -374,4 +374,19 @@ public class BubbleStashController {
    public PhysicsAnimator<View> getStashedHandlePhysicsAnimator() {
        return mHandleViewController.getPhysicsAnimator();
    }

    /** Notifies taskbar that it should update its touchable region. */
    public void updateTaskbarTouchRegion() {
        mTaskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
    }

    /** Shows the bubble bar immediately without animation. */
    public void showBubbleBarImmediate() {
        mHandleViewController.setTranslationYForSwipe(0);
        mIconTranslationYForStash.updateValue(getBubbleBarTranslationY());
        mIconAlphaForStash.setValue(1);
        mIconScaleForStash.updateValue(1);
        mIsStashed = false;
        onIsStashedChanged();
    }
}
+44 −7
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ constructor(
    private val scheduler: Scheduler = HandlerScheduler(bubbleBarView)
) {

    private var animatingBubble: AnimatingBubble? = null

    private companion object {
        /** The time to show the flyout. */
        const val FLYOUT_DELAY_MS: Long = 2500
@@ -54,26 +56,40 @@ constructor(
        const val BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y = -20f
    }

    /** Wrapper around the animating bubble with its show and hide animations. */
    private data class AnimatingBubble(
        val bubbleView: BubbleView,
        val showAnimation: Runnable,
        val hideAnimation: Runnable
    )

    /** An interface for scheduling jobs. */
    interface Scheduler {

        /** Schedule the given [block] to run. */
        fun post(block: () -> Unit)
        fun post(block: Runnable)

        /** Schedule the given [block] to start with a delay of [delayMillis]. */
        fun postDelayed(delayMillis: Long, block: () -> Unit)
        fun postDelayed(delayMillis: Long, block: Runnable)

        /** Cancel the given [block] if it hasn't started yet. */
        fun cancel(block: Runnable)
    }

    /** A [Scheduler] that uses a Handler to run jobs. */
    private class HandlerScheduler(private val view: View) : Scheduler {

        override fun post(block: () -> Unit) {
        override fun post(block: Runnable) {
            view.post(block)
        }

        override fun postDelayed(delayMillis: Long, block: () -> Unit) {
        override fun postDelayed(delayMillis: Long, block: Runnable) {
            view.postDelayed(block, delayMillis)
        }

        override fun cancel(block: Runnable) {
            view.removeCallbacks(block)
        }
    }

    private val springConfig =
@@ -91,6 +107,7 @@ constructor(
        // and the second part hides it after a delay.
        val showAnimation = buildShowAnimation(bubbleView, b.key)
        val hideAnimation = buildHideAnimation(bubbleView)
        animatingBubble = AnimatingBubble(bubbleView, showAnimation, hideAnimation)
        scheduler.post(showAnimation)
        scheduler.postDelayed(FLYOUT_DELAY_MS, hideAnimation)
    }
@@ -113,7 +130,7 @@ constructor(
    private fun buildShowAnimation(
        bubbleView: BubbleView,
        key: String,
    ): () -> Unit = {
    ) = Runnable {
        bubbleBarView.prepareForAnimatingBubbleWhileStashed(key)
        // calculate the initial translation x the bubble should have in order to align it with the
        // stash handle.
@@ -140,7 +157,7 @@ constructor(

                    // map the path [0, BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y] to [0,1]
                    val fraction = ty / BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
                    target.alpha = 1 - fraction / 2
                    target.alpha = 1 - fraction
                }
                ty >= totalTranslationY -> {
                    // this is the second leg of the animation. the handle should be completely
@@ -173,6 +190,16 @@ constructor(
                }
            }
        }
        animator.addEndListener { _, _, _, _, _, _, _ ->
            // the bubble is now fully settled in. make it touchable
            bubbleBarView.updateAnimatingBubbleBounds(
                bubbleView.left,
                bubbleView.top,
                bubbleView.width,
                bubbleView.height
            )
            bubbleStashController.updateTaskbarTouchRegion()
        }
        animator.start()
    }

@@ -189,7 +216,7 @@ constructor(
     * 1. In the second part the bubble is fully hidden and the handle animates in.
     * 1. The third part is the overshoot. The handle is made fully visible.
     */
    private fun buildHideAnimation(bubbleView: BubbleView): () -> Unit = {
    private fun buildHideAnimation(bubbleView: BubbleView) = Runnable {
        // this is the total distance that both the stashed handle and the bubble will be traveling
        val totalTranslationY =
            BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y + BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
@@ -230,6 +257,7 @@ constructor(
            }
        }
        animator.addEndListener { _, _, _, _, _, _, _ ->
            animatingBubble = null
            bubbleView.alpha = 0f
            bubbleView.translationY = 0f
            bubbleView.scaleY = 1f
@@ -237,9 +265,18 @@ constructor(
                bubbleBarView.alpha = 0f
            }
            bubbleBarView.onAnimatingBubbleCompleted()
            bubbleStashController.updateTaskbarTouchRegion()
        }
        animator.start()
    }

    /** Handles clicking on the animating bubble while the animation is still playing. */
    fun onBubbleClickedWhileAnimating() {
        val hideAnimation = animatingBubble?.hideAnimation ?: return
        scheduler.cancel(hideAnimation)
        bubbleBarView.onAnimatingBubbleCompleted()
        animatingBubble = null
    }
}

/** The X position in screen coordinates of the center of the bubble. */
Loading