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

Commit 6d93334f authored by Ats Jenk's avatar Ats Jenk
Browse files

Add task scale to the convert to bubble animation

When a task is dragged to a bubble, the task is scaled down.
Add the initial scale to the size change animation and include another
animator in the set to scale the task up from the drag scale to 1x
scale.
Apply the dragged task scale to the snapshot while it is not under the
task container and while the task is being moved to the bubble task view.
Pass along full task bounds along with a scale to the size change animation.
This way the size change animation will be animating from start bounds
with intial scale to end bounds.
Update to emphasized interpolator for the size change animation.

Bug: 396449031
Test: atest BubbleTransitionsTest
Test: manual, drag a task to bubble
Flag: com.android.wm.shell.enable_bubble_to_fullscreen
Change-Id: I192c97aebe2632e6519d75ea9739e0037ca5484b
parent fd356738
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -83,7 +83,11 @@ public class SizeChangeAnimation {
    private static final int ANIMATION_RESOLUTION = 1000;

    public SizeChangeAnimation(Rect startBounds, Rect endBounds) {
        mAnimation = buildContainerAnimation(startBounds, endBounds);
        this(startBounds, endBounds, 1f);
    }

    public SizeChangeAnimation(Rect startBounds, Rect endBounds, float initialScale) {
        mAnimation = buildContainerAnimation(startBounds, endBounds, initialScale);
        mSnapshotAnim = buildSnapshotAnimation(startBounds, endBounds);
    }

@@ -167,7 +171,8 @@ public class SizeChangeAnimation {
    }

    /** Animation for the whole container (snapshot is inside this container). */
    private static AnimationSet buildContainerAnimation(Rect startBounds, Rect endBounds) {
    private static AnimationSet buildContainerAnimation(Rect startBounds, Rect endBounds,
            float initialScale) {
        final long duration = ANIMATION_RESOLUTION;
        boolean growing = endBounds.width() - startBounds.width()
                + endBounds.height() - startBounds.height() >= 0;
@@ -180,15 +185,27 @@ public class SizeChangeAnimation {

        final Animation scaleAnim = new ScaleAnimation(startScaleX, 1, startScaleY, 1);
        scaleAnim.setDuration(scalePeriod);
        long scaleStartOffset = 0;
        if (!growing) {
            scaleAnim.setStartOffset(duration - scalePeriod);
            scaleStartOffset = duration - scalePeriod;
        }
        scaleAnim.setStartOffset(scaleStartOffset);
        animSet.addAnimation(scaleAnim);

        if (initialScale != 1f) {
            final Animation initialScaleAnim = new ScaleAnimation(initialScale, 1f, initialScale,
                    1f);
            initialScaleAnim.setDuration(scalePeriod);
            initialScaleAnim.setStartOffset(scaleStartOffset);
            animSet.addAnimation(initialScaleAnim);
        }

        final Animation translateAnim = new TranslateAnimation(startBounds.left,
                endBounds.left, startBounds.top, endBounds.top);
        translateAnim.setDuration(duration);
        animSet.addAnimation(translateAnim);
        Rect startClip = new Rect(startBounds);
        startClip.scale(initialScale);
        Rect endClip = new Rect(endBounds);
        startClip.offsetTo(0, 0);
        endClip.offsetTo(0, 0);
+41 −24
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.TaskInfo;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.Slog;
@@ -155,28 +156,23 @@ public class BubbleTransitions {
     * Information about the task when it is being dragged to a bubble
     */
    public static class DragData {
        private final Rect mBounds;
        private final WindowContainerTransaction mPendingWct;
        private final boolean mReleasedOnLeft;
        private final float mTaskScale;
        private final PointF mDragPosition;

        /**
         * @param bounds bounds of the dragged task when the drag was released
         * @param wct pending operations to be applied when finishing the drag
         * @param releasedOnLeft true if the bubble was released in the left drop target
         * @param taskScale      the scale of the task when it was dragged to bubble
         * @param dragPosition   the position of the task when it was dragged to bubble
         * @param wct            pending operations to be applied when finishing the drag
         */
        public DragData(@Nullable Rect bounds, @Nullable WindowContainerTransaction wct,
                boolean releasedOnLeft) {
            mBounds = bounds;
        public DragData(boolean releasedOnLeft, float taskScale, @Nullable PointF dragPosition,
                @Nullable WindowContainerTransaction wct) {
            mPendingWct = wct;
            mReleasedOnLeft = releasedOnLeft;
        }

        /**
         * @return bounds of the dragged task when the drag was released
         */
        @Nullable
        public Rect getBounds() {
            return mBounds;
            mTaskScale = taskScale;
            mDragPosition = dragPosition != null ? dragPosition : new PointF(0, 0);
        }

        /**
@@ -193,6 +189,20 @@ public class BubbleTransitions {
        public boolean isReleasedOnLeft() {
            return mReleasedOnLeft;
        }

        /**
         * @return the scale of the task when it was dragged to bubble
         */
        public float getTaskScale() {
            return mTaskScale;
        }

        /**
         * @return position of the task when it was dragged to bubble
         */
        public PointF getDragPosition() {
            return mDragPosition;
        }
    }

    /**
@@ -347,21 +357,24 @@ public class BubbleTransitions {
            }
            mFinishCb = finishCallback;

            if (mDragData != null && mDragData.getBounds() != null) {
                // Override start bounds with the dragged task bounds
                mStartBounds.set(mDragData.getBounds());
            if (mDragData != null) {
                mStartBounds.offsetTo((int) mDragData.getDragPosition().x,
                        (int) mDragData.getDragPosition().y);
                startTransaction.setScale(mSnapshot, mDragData.getTaskScale(),
                        mDragData.getTaskScale());
            }

            // Now update state (and talk to launcher) in parallel with snapshot stuff
            mBubbleData.notificationEntryUpdated(mBubble, /* suppressFlyout= */ true,
                    /* showInShade= */ false);

            final int left = mStartBounds.left - info.getRoot(0).getOffset().x;
            final int top = mStartBounds.top - info.getRoot(0).getOffset().y;
            startTransaction.setPosition(mTaskLeash, left, top);
            startTransaction.show(mSnapshot);
            // Move snapshot to root so that it remains visible while task is moved to taskview
            startTransaction.reparent(mSnapshot, info.getRoot(0).getLeash());
            startTransaction.setPosition(mSnapshot,
                    mStartBounds.left - info.getRoot(0).getOffset().x,
                    mStartBounds.top - info.getRoot(0).getOffset().y);
            startTransaction.setPosition(mSnapshot, left, top);
            startTransaction.setLayer(mSnapshot, Integer.MAX_VALUE);

            BubbleBarExpandedView bbev = mBubble.getBubbleBarExpandedView();
@@ -416,6 +429,8 @@ public class BubbleTransitions {
        private void playAnimation(boolean animate) {
            final TaskViewTaskController tv = mBubble.getTaskView().getController();
            final SurfaceControl.Transaction startT = new SurfaceControl.Transaction();
            // Set task position to 0,0 as it will be placed inside the TaskView
            startT.setPosition(mTaskLeash, 0, 0);
            mTaskViewTransitions.prepareOpenAnimation(tv, true /* new */, startT, mFinishT,
                    (ActivityManager.RunningTaskInfo) mTaskInfo, mTaskLeash, mFinishWct);

@@ -424,7 +439,9 @@ public class BubbleTransitions {
            }

            if (animate) {
                mLayerView.animateConvert(startT, mStartBounds, mSnapshot, mTaskLeash, () -> {
                float startScale = mDragData != null ? mDragData.getTaskScale() : 1f;
                mLayerView.animateConvert(startT, mStartBounds, startScale, mSnapshot, mTaskLeash,
                        () -> {
                            mFinishCb.onTransitionFinished(mFinishWct);
                            mFinishCb = null;
                        });
+3 −1
Original line number Diff line number Diff line
@@ -580,6 +580,7 @@ public class BubbleBarAnimationHelper {
    public void animateConvert(BubbleViewProvider expandedBubble,
            @NonNull SurfaceControl.Transaction startT,
            @NonNull Rect origBounds,
            float origScale,
            @NonNull SurfaceControl snapshot,
            @NonNull SurfaceControl taskLeash,
            @Nullable Runnable afterAnimation) {
@@ -599,7 +600,7 @@ public class BubbleBarAnimationHelper {
                new SizeChangeAnimation(
                        new Rect(origBounds.left - position.x, origBounds.top - position.y,
                                origBounds.right - position.x, origBounds.bottom - position.y),
                        new Rect(0, 0, size.getWidth(), size.getHeight()));
                        new Rect(0, 0, size.getWidth(), size.getHeight()), origScale);
        sca.initialize(bbev, taskLeash, snapshot, startT);

        Animator a = sca.buildViewAnimator(bbev, tvSf, snapshot, /* onFinish */ (va) -> {
@@ -614,6 +615,7 @@ public class BubbleBarAnimationHelper {

        bbev.setSurfaceZOrderedOnTop(true);
        a.setDuration(EXPANDED_VIEW_ANIMATE_TO_REST_DURATION);
        a.setInterpolator(Interpolators.EMPHASIZED);
        a.start();
    }

+4 −4
Original line number Diff line number Diff line
@@ -348,13 +348,13 @@ public class BubbleBarLayerView extends FrameLayout
     * @param startT A transaction with first-frame work. this *will* be applied here!
     */
    public void animateConvert(@NonNull SurfaceControl.Transaction startT,
            @NonNull Rect startBounds, @NonNull SurfaceControl snapshot, SurfaceControl taskLeash,
            Runnable animFinish) {
            @NonNull Rect startBounds, float startScale, @NonNull SurfaceControl snapshot,
            SurfaceControl taskLeash, Runnable animFinish) {
        if (!mIsExpanded || mExpandedBubble == null) {
            throw new IllegalStateException("Can't animateExpand without expanded state");
        }
        mAnimationHelper.animateConvert(mExpandedBubble, startT, startBounds, snapshot, taskLeash,
                animFinish);
        mAnimationHelper.animateConvert(mExpandedBubble, startT, startBounds, startScale, snapshot,
                taskLeash, animFinish);
    }

    /**
+7 −5
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ sealed class DragToDesktopTransitionHandler(
        val state = requireTransitionState()
        val taskInfo = state.draggedTaskChange?.taskInfo ?: error("Expected non-null taskInfo")
        val animatedTaskBounds = getAnimatedTaskBounds()
        state.dragAnimator.cancelAnimator()
        requestSplitSelect(wct, taskInfo, splitPosition, animatedTaskBounds)
    }

@@ -288,7 +289,6 @@ sealed class DragToDesktopTransitionHandler(
        val scaledWidth = taskBounds.width() * taskScale
        val scaledHeight = taskBounds.height() * taskScale
        val dragPosition = PointF(state.dragAnimator.position)
        state.dragAnimator.cancelAnimator()
        return Rect(
            dragPosition.x.toInt(),
            dragPosition.y.toInt(),
@@ -321,22 +321,24 @@ sealed class DragToDesktopTransitionHandler(
        // TODO(b/391928049): update density once we can drag from desktop to bubble
        val state = requireTransitionState()
        val taskInfo = state.draggedTaskChange?.taskInfo ?: error("Expected non-null taskInfo")
        val taskBounds = getAnimatedTaskBounds()
        val dragPosition = PointF(state.dragAnimator.position)
        val scale = state.dragAnimator.scale
        state.dragAnimator.cancelAnimator()
        requestBubble(wct, taskInfo, onLeft, taskBounds)
        requestBubble(wct, taskInfo, onLeft, scale, dragPosition)
    }

    private fun requestBubble(
        wct: WindowContainerTransaction,
        taskInfo: RunningTaskInfo,
        onLeft: Boolean,
        taskBounds: Rect = Rect(taskInfo.configuration.windowConfiguration.bounds),
        taskScale: Float = 1f,
        dragPosition: PointF = PointF(0f, 0f),
    ) {
        val controller =
            bubbleController.orElseThrow { IllegalStateException("BubbleController not set") }
        controller.expandStackAndSelectBubble(
            taskInfo,
            BubbleTransitions.DragData(taskBounds, wct, onLeft),
            BubbleTransitions.DragData(onLeft, taskScale, dragPosition, wct),
        )
    }

Loading