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

Commit 77b6225d authored by Ats Jenk's avatar Ats Jenk
Browse files

Animate bubble bar location changes

When it is not the initial bubble data, animate bubble bar location
change.

Bug: 313661121
Flag: ACONFIG com.android.wm.shell.enable_bubble_bar DEVELOPMENT
Test: manual, move expanded view from one side to the other, observe the
  location change animates

Change-Id: I52117a31d02e7160ca1d3dc3e724bda2e38f6cbf
parent cd0f3538
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -156,6 +156,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
     * {@link BubbleBarBubble}s so that it can be used to update the views.
     * {@link BubbleBarBubble}s so that it can be used to update the views.
     */
     */
    private static class BubbleBarViewUpdate {
    private static class BubbleBarViewUpdate {
        final boolean initialState;
        boolean expandedChanged;
        boolean expandedChanged;
        boolean expanded;
        boolean expanded;
        boolean shouldShowEducation;
        boolean shouldShowEducation;
@@ -172,6 +173,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
        List<BubbleBarBubble> currentBubbles;
        List<BubbleBarBubble> currentBubbles;


        BubbleBarViewUpdate(BubbleBarUpdate update) {
        BubbleBarViewUpdate(BubbleBarUpdate update) {
            initialState = update.initialState;
            expandedChanged = update.expandedChanged;
            expandedChanged = update.expandedChanged;
            expanded = update.expanded;
            expanded = update.expanded;
            shouldShowEducation = update.shouldShowEducation;
            shouldShowEducation = update.shouldShowEducation;
@@ -405,7 +407,9 @@ public class BubbleBarController extends IBubblesListener.Stub {
        }
        }
        if (update.bubbleBarLocation != null) {
        if (update.bubbleBarLocation != null) {
            if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) {
            if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) {
                mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation);
                // Animate when receiving updates. Skip it if we received the initial state.
                boolean animate = !update.initialState;
                mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation, animate);
                mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation);
                mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation);
            }
            }
        }
        }
+98 −1
Original line number Original line Diff line number Diff line
@@ -15,7 +15,13 @@
 */
 */
package com.android.launcher3.taskbar.bubbles;
package com.android.launcher3.taskbar.bubbles;


import static com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;

import android.animation.Animator;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
@@ -29,7 +35,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.FrameLayout;


import androidx.dynamicanimation.animation.SpringForce;

import com.android.launcher3.R;
import com.android.launcher3.R;
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ActivityContext;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
@@ -73,6 +82,18 @@ public class BubbleBarView extends FrameLayout {
    private static final int ARROW_POSITION_ANIMATION_DURATION_MS = 200;
    private static final int ARROW_POSITION_ANIMATION_DURATION_MS = 200;
    private static final int WIDTH_ANIMATION_DURATION_MS = 200;
    private static final int WIDTH_ANIMATION_DURATION_MS = 200;


    private static final long FADE_OUT_ANIM_ALPHA_DURATION_MS = 50L;
    private static final long FADE_OUT_ANIM_ALPHA_DELAY_MS = 50L;
    private static final long FADE_OUT_ANIM_POSITION_DURATION_MS = 100L;
    // During fade out animation we shift the bubble bar 1/80th of the screen width
    private static final float FADE_OUT_ANIM_POSITION_SHIFT = 1 / 80f;

    private static final long FADE_IN_ANIM_ALPHA_DURATION_MS = 100L;
    // Use STIFFNESS_MEDIUMLOW which is not defined in the API constants
    private static final float FADE_IN_ANIM_POSITION_SPRING_STIFFNESS = 400f;
    // During fade in animation we shift the bubble bar 1/60th of the screen width
    private static final float FADE_IN_ANIM_POSITION_SHIFT = 1 / 60f;

    private final BubbleBarBackground mBubbleBarBackground;
    private final BubbleBarBackground mBubbleBarBackground;


    /**
    /**
@@ -106,6 +127,9 @@ public class BubbleBarView extends FrameLayout {
    // collapsed state and 1 to the fully expanded state.
    // collapsed state and 1 to the fully expanded state.
    private final ValueAnimator mWidthAnimator = ValueAnimator.ofFloat(0, 1);
    private final ValueAnimator mWidthAnimator = ValueAnimator.ofFloat(0, 1);


    @Nullable
    private Animator mBubbleBarLocationAnimator = null;

    // We don't reorder the bubbles when they are expanded as it could be jarring for the user
    // We don't reorder the bubbles when they are expanded as it could be jarring for the user
    // this runnable will be populated with any reordering of the bubbles that should be applied
    // this runnable will be populated with any reordering of the bubbles that should be applied
    // once they are collapsed.
    // once they are collapsed.
@@ -236,13 +260,86 @@ public class BubbleBarView extends FrameLayout {
    /**
    /**
     * Update {@link BubbleBarLocation}
     * Update {@link BubbleBarLocation}
     */
     */
    public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
    public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
        if (animate) {
            animateToBubbleBarLocation(bubbleBarLocation);
        } else {
            setBubbleBarLocationInternal(bubbleBarLocation);
        }
    }

    private void setBubbleBarLocationInternal(BubbleBarLocation bubbleBarLocation) {
        if (bubbleBarLocation != mBubbleBarLocation) {
        if (bubbleBarLocation != mBubbleBarLocation) {
            mBubbleBarLocation = bubbleBarLocation;
            mBubbleBarLocation = bubbleBarLocation;
            onBubbleBarLocationChanged();
            onBubbleBarLocationChanged();
        }
        }
    }
    }


    private void animateToBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
        if (bubbleBarLocation == mBubbleBarLocation) {
            // nothing to do, already at expected location
            return;
        }
        if (mBubbleBarLocationAnimator != null && mBubbleBarLocationAnimator.isRunning()) {
            mBubbleBarLocationAnimator.cancel();
        }

        // Location animation uses two separate animators.
        // First animator hides the bar.
        // After it completes, location update is sent to layout the bar in the new location.
        // Second animator is started to show the bar.
        mBubbleBarLocationAnimator = getLocationUpdateFadeOutAnimator();
        mBubbleBarLocationAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // Bubble bar is not visible, update the location
                setBubbleBarLocationInternal(bubbleBarLocation);
                // Animate it in
                mBubbleBarLocationAnimator = getLocationUpdateFadeInAnimator();
                mBubbleBarLocationAnimator.start();
            }
        });
        mBubbleBarLocationAnimator.start();
    }

    private AnimatorSet getLocationUpdateFadeOutAnimator() {
        final float shift =
                getResources().getDisplayMetrics().widthPixels * FADE_OUT_ANIM_POSITION_SHIFT;
        final float tx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;

        ObjectAnimator positionAnim = ObjectAnimator.ofFloat(this, TRANSLATION_X, tx)
                .setDuration(FADE_OUT_ANIM_POSITION_DURATION_MS);
        positionAnim.setInterpolator(EMPHASIZED_ACCELERATE);

        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(this, ALPHA, 0f)
                .setDuration(FADE_OUT_ANIM_ALPHA_DURATION_MS);
        alphaAnim.setStartDelay(FADE_OUT_ANIM_ALPHA_DELAY_MS);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(positionAnim, alphaAnim);
        return animatorSet;
    }

    private Animator getLocationUpdateFadeInAnimator() {
        final float shift =
                getResources().getDisplayMetrics().widthPixels * FADE_IN_ANIM_POSITION_SHIFT;
        final float startTx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;

        ValueAnimator positionAnim = new SpringAnimationBuilder(getContext())
                .setStartValue(startTx)
                .setEndValue(0)
                .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
                .setStiffness(FADE_IN_ANIM_POSITION_SPRING_STIFFNESS)
                .build(this, VIEW_TRANSLATE_X);

        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(this, ALPHA, 1f)
                .setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(positionAnim, alphaAnim);
        return animatorSet;
    }

    /**
    /**
     * Updates the bounds with translation that may have been applied and returns the result.
     * Updates the bounds with translation that may have been applied and returns the result.
     */
     */
+2 −2
Original line number Original line Diff line number Diff line
@@ -179,8 +179,8 @@ public class BubbleBarViewController {
    /**
    /**
     * Update bar {@link BubbleBarLocation}
     * Update bar {@link BubbleBarLocation}
     */
     */
    public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
    public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
        mBarView.setBubbleBarLocation(bubbleBarLocation);
        mBarView.setBubbleBarLocation(bubbleBarLocation, animate);
    }
    }


    /**
    /**