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

Commit 5e6a3f32 authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Animate task to bubble immediately during transition" into main

parents f9f88c9c d0272fd3
Loading
Loading
Loading
Loading
+56 −15
Original line number Original line Diff line number Diff line
@@ -189,14 +189,16 @@ public class BubbleTransitions {
     *
     *
     * 1. Start inflating the bubble view
     * 1. Start inflating the bubble view
     * 2. Once inflated (but not-yet visible), tell WM to do the shell-transition.
     * 2. Once inflated (but not-yet visible), tell WM to do the shell-transition.
     * 3. Transition becomes ready, so notify Launcher
     * 3. When the transition becomes ready, notify Launcher in parallel
     * 4. Launcher responds with showExpandedView which calls continueExpand() to make view visible
     * 4. Wait for surface to be created
     * 5. Surface is created which kicks off actual animation
     * 5. Once surface is ready, animate the task to a bubble
     *
     *
     * So, constructor -> onInflated -> startAnimation -> continueExpand -> surfaceCreated.
     * While the animation is pending, we keep a reference to the pending transition in the bubble.
     * This allows us to check in other parts of the code that this bubble will be shown via the
     * transition animation.
     *
     *
     * continueExpand and surfaceCreated are set-up to happen in either order, though, to support
     * startAnimation, continueExpand and surfaceCreated are set-up to happen in either order,
     * UX/timing adjustments.
     * to support UX/timing adjustments.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    class ConvertToBubble implements Transitions.TransitionHandler, BubbleTransition {
    class ConvertToBubble implements Transitions.TransitionHandler, BubbleTransition {
@@ -209,9 +211,9 @@ public class BubbleTransitions {
        final Rect mStartBounds = new Rect();
        final Rect mStartBounds = new Rect();
        SurfaceControl mSnapshot = null;
        SurfaceControl mSnapshot = null;
        TaskInfo mTaskInfo;
        TaskInfo mTaskInfo;
        boolean mFinishedExpand = false;
        BubbleViewProvider mPriorBubble = null;
        BubbleViewProvider mPriorBubble = null;


        private final TransitionProgress mTransitionProgress = new TransitionProgress();
        private SurfaceControl.Transaction mFinishT;
        private SurfaceControl.Transaction mFinishT;
        private SurfaceControl mTaskLeash;
        private SurfaceControl mTaskLeash;


@@ -359,12 +361,12 @@ public class BubbleTransitions {
            startTransaction.apply();
            startTransaction.apply();


            mTaskViewTransitions.onExternalDone(transition);
            mTaskViewTransitions.onExternalDone(transition);
            mTransitionProgress.setTransitionReady();
            startExpandAnim();
            return true;
            return true;
        }
        }


        @Override
        private void startExpandAnim() {
        public void continueExpand() {
            mFinishedExpand = true;
            final boolean animate = mLayerView.canExpandView(mBubble);
            final boolean animate = mLayerView.canExpandView(mBubble);
            if (animate) {
            if (animate) {
                mPriorBubble = mLayerView.prepareConvertedView(mBubble);
                mPriorBubble = mLayerView.prepareConvertedView(mBubble);
@@ -375,19 +377,25 @@ public class BubbleTransitions {
                mLayerView.removeView(priorView);
                mLayerView.removeView(priorView);
                mPriorBubble = null;
                mPriorBubble = null;
            }
            }
            if (!animate || mBubble.getTaskView().getSurfaceControl() != null) {
            if (!animate || mTransitionProgress.isReadyToAnimate()) {
                playAnimation(animate);
                playAnimation(animate);
            }
            }
        }
        }


        @Override
        public void continueExpand() {
            mTransitionProgress.setReadyToExpand();
        }

        @Override
        @Override
        public void surfaceCreated() {
        public void surfaceCreated() {
            mTransitionProgress.setSurfaceReady();
            mMainExecutor.execute(() -> {
            mMainExecutor.execute(() -> {
                final TaskViewTaskController tvc = mBubble.getTaskView().getController();
                final TaskViewTaskController tvc = mBubble.getTaskView().getController();
                final TaskViewRepository.TaskViewState state = mRepository.byTaskView(tvc);
                final TaskViewRepository.TaskViewState state = mRepository.byTaskView(tvc);
                if (state == null) return;
                if (state == null) return;
                state.mVisible = true;
                state.mVisible = true;
                if (mFinishedExpand) {
                if (mTransitionProgress.isReadyToAnimate()) {
                    playAnimation(true /* animate */);
                    playAnimation(true /* animate */);
                }
                }
            });
            });
@@ -403,9 +411,6 @@ public class BubbleTransitions {
                mFinishWct = null;
                mFinishWct = null;
            }
            }


            // Preparation is complete.
            mBubble.setPreparingTransition(null);

            if (animate) {
            if (animate) {
                mLayerView.animateConvert(startT, mStartBounds, mSnapshot, mTaskLeash, () -> {
                mLayerView.animateConvert(startT, mStartBounds, mSnapshot, mTaskLeash, () -> {
                    mFinishCb.onTransitionFinished(mFinishWct);
                    mFinishCb.onTransitionFinished(mFinishWct);
@@ -417,6 +422,42 @@ public class BubbleTransitions {
                mFinishCb = null;
                mFinishCb = null;
            }
            }
        }
        }

        /**
         * Keeps track of internal state of different steps of this BubbleTransition.
         */
        private class TransitionProgress {
            private boolean mTransitionReady;
            private boolean mReadyToExpand;
            private boolean mSurfaceReady;

            void setTransitionReady() {
                mTransitionReady = true;
                onUpdate();
            }

            void setReadyToExpand() {
                mReadyToExpand = true;
                onUpdate();
            }

            void setSurfaceReady() {
                mSurfaceReady = true;
                onUpdate();
            }

            boolean isReadyToAnimate() {
                // Animation only depends on transition and surface state
                return mTransitionReady && mSurfaceReady;
            }

            private void onUpdate() {
                if (mTransitionReady && mReadyToExpand && mSurfaceReady) {
                    // Clear the transition from bubble when all the steps are ready
                    mBubble.setPreparingTransition(null);
                }
            }
        }
    }
    }


    /**
    /**
+7 −2
Original line number Original line Diff line number Diff line
@@ -186,15 +186,20 @@ public class BubbleTransitionsTest extends ShellTestCase {
        verify(startT).setPosition(any(), eq(0f), eq(0f));
        verify(startT).setPosition(any(), eq(0f), eq(0f));


        verify(mBubbleData).notificationEntryUpdated(eq(mBubble), anyBoolean(), anyBoolean());
        verify(mBubbleData).notificationEntryUpdated(eq(mBubble), anyBoolean(), anyBoolean());
        ctb.continueExpand();


        clearInvocations(mBubble);
        clearInvocations(mBubble);
        verify(mBubble, never()).setPreparingTransition(any());
        verify(mBubble, never()).setPreparingTransition(any());


        ctb.surfaceCreated();
        ctb.surfaceCreated();
        verify(mBubble).setPreparingTransition(isNull());
        // Check that preparing transition is not reset before continueExpand is called
        verify(mBubble, never()).setPreparingTransition(any());
        ArgumentCaptor<Runnable> animCb = ArgumentCaptor.forClass(Runnable.class);
        ArgumentCaptor<Runnable> animCb = ArgumentCaptor.forClass(Runnable.class);
        verify(mLayerView).animateConvert(any(), any(), any(), any(), animCb.capture());
        verify(mLayerView).animateConvert(any(), any(), any(), any(), animCb.capture());

        // continueExpand is now called, check that preparing transition is cleared
        ctb.continueExpand();
        verify(mBubble).setPreparingTransition(isNull());

        assertFalse(finishCalled[0]);
        assertFalse(finishCalled[0]);
        animCb.getValue().run();
        animCb.getValue().run();
        assertTrue(finishCalled[0]);
        assertTrue(finishCalled[0]);