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

Commit 57be2f60 authored by Ben Lin's avatar Ben Lin Committed by Automerger Merge Worker
Browse files

Merge "PiP: Update menu state AFTER animation is done for show/hide/resize."...

Merge "PiP: Update menu state AFTER animation is done for show/hide/resize." into sc-dev am: 4c21ac8f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14421938

Change-Id: I3c0f7f4d2f3a9a0ba6aecc8b078ecc3efdd9ae84
parents b98d7c98 4c21ac8f
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -207,6 +207,24 @@ public class PipAnimationController {
        public void onPipAnimationCancel(TaskInfo taskInfo, PipTransitionAnimator animator) {}
    }

    /**
     * A handler class that could register itself to apply the transaction instead of the
     * animation controller doing it. For example, the menu controller can be one such handler.
     */
    public static class PipTransactionHandler {

        /**
         * Called when the animation controller is about to apply a transaction. Allow a registered
         * handler to apply the transaction instead.
         *
         * @return true if handled by the handler, false otherwise.
         */
        public boolean handlePipTransaction(SurfaceControl leash, SurfaceControl.Transaction tx,
                Rect destinationBounds) {
            return false;
        }
    }

    /**
     * Animator for PiP transition animation which supports both alpha and bounds animation.
     * @param <T> Type of property to animate, either alpha (float) or bounds (Rect)
@@ -225,6 +243,7 @@ public class PipAnimationController {
        private T mEndValue;
        private float mStartingAngle;
        private PipAnimationCallback mPipAnimationCallback;
        private PipTransactionHandler mPipTransactionHandler;
        private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
                mSurfaceControlTransactionFactory;
        private PipSurfaceTransactionHelper mSurfaceTransactionHelper;
@@ -293,6 +312,20 @@ public class PipAnimationController {
            mPipAnimationCallback = callback;
            return this;
        }

        PipTransitionAnimator<T> setPipTransactionHandler(PipTransactionHandler handler) {
            mPipTransactionHandler = handler;
            return this;
        }

        boolean handlePipTransaction(SurfaceControl leash, SurfaceControl.Transaction tx,
                Rect destinationBounds) {
            if (mPipTransactionHandler != null) {
                return mPipTransactionHandler.handlePipTransaction(leash, tx, destinationBounds);
            }
            return false;
        }

        @VisibleForTesting
        @TransitionDirection public int getTransitionDirection() {
            return mTransitionDirection;
@@ -499,8 +532,10 @@ public class PipAnimationController {
                        getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
                                initialSourceValue, bounds, insets);
                    }
                    if (!handlePipTransaction(leash, tx, bounds)) {
                        tx.apply();
                    }
                }

                private void applyRotation(SurfaceControl.Transaction tx, SurfaceControl leash,
                        float fraction, Rect start, Rect end) {
+19 −1
Original line number Diff line number Diff line
@@ -200,6 +200,19 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }
    };

    private final PipAnimationController.PipTransactionHandler mPipTransactionHandler =
            new PipAnimationController.PipTransactionHandler() {
                @Override
                public boolean handlePipTransaction(SurfaceControl leash,
                        SurfaceControl.Transaction tx, Rect destinationBounds) {
                    if (mPipMenuController.isMenuVisible()) {
                        mPipMenuController.movePipMenu(leash, tx, destinationBounds);
                        return true;
                    }
                    return false;
                }
            };

    private ActivityManager.RunningTaskInfo mTaskInfo;
    // To handle the edge case that onTaskInfoChanged callback is received during the entering
    // PiP transition, where we do not want to intercept the transition but still want to apply the
@@ -433,8 +446,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,

        // removePipImmediately is expected when the following animation finishes.
        ValueAnimator animator = mPipAnimationController
                .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(), 1f, 0f)
                .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(),
                        1f /* alphaStart */, 0f /* alphaEnd */)
                .setTransitionDirection(TRANSITION_DIRECTION_REMOVE_STACK)
                .setPipTransactionHandler(mPipTransactionHandler)
                .setPipAnimationCallback(mPipAnimationCallback);
        animator.setDuration(mExitAnimationDuration);
        animator.setInterpolator(Interpolators.ALPHA_OUT);
@@ -573,6 +588,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                    .getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)
                    .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                    .setPipAnimationCallback(mPipAnimationCallback)
                    .setPipTransactionHandler(mPipTransactionHandler)
                    .setDuration(durationMs)
                    .start();
            // mState is set right after the animation is kicked off to block any resize
@@ -749,6 +765,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mPipAnimationController
                .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(), alphaStart, alphaEnd)
                .setTransitionDirection(TRANSITION_DIRECTION_SAME)
                .setPipTransactionHandler(mPipTransactionHandler)
                .setDuration(show ? mEnterAnimationDuration : mExitAnimationDuration)
                .start();
        mHasFadeOut = !show;
@@ -1226,6 +1243,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                        sourceHintRect, direction, startingAngle, rotationDelta);
        animator.setTransitionDirection(direction)
                .setPipAnimationCallback(mPipAnimationCallback)
                .setPipTransactionHandler(mPipTransactionHandler)
                .setDuration(durationMs)
                .start();
        if (rotationDelta != Surface.ROTATION_0 && direction == TRANSITION_DIRECTION_TO_PIP) {
+5 −5
Original line number Diff line number Diff line
@@ -111,14 +111,14 @@ public class PipTransition extends PipTransitionController {
            final Rect sourceHintRect =
                    PipBoundsAlgorithm.getValidSourceHintRect(
                            taskInfo.pictureInPictureParams, currentBounds);
            animator = mPipAnimationController.getAnimator(taskInfo, leash,
                    currentBounds, currentBounds, destinationBounds, sourceHintRect,
                    TRANSITION_DIRECTION_TO_PIP, 0 /* startingAngle */, Surface.ROTATION_0);
            animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
                    currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
                    0 /* startingAngle */, Surface.ROTATION_0);
        } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
            t.setAlpha(leash, 0f);
            t.apply();
            animator = mPipAnimationController.getAnimator(taskInfo, leash,
                    destinationBounds, 0f, 1f);
            animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
                    0f, 1f);
            mOneShotAnimationType = ANIM_TYPE_BOUNDS;
        } else {
            throw new RuntimeException("Unrecognized animation type: "
+19 −6
Original line number Diff line number Diff line
@@ -70,12 +70,19 @@ public class PhonePipMenuController implements PipMenuController {
     */
    public interface Listener {
        /**
         * Called when the PIP menu visibility changes.
         * Called when the PIP menu visibility change has started.
         *
         * @param menuState the current state of the menu
         * @param menuState the new, about-to-change state of the menu
         * @param resize whether or not to resize the PiP with the state change
         */
        void onPipMenuStateChanged(int menuState, boolean resize, Runnable callback);
        void onPipMenuStateChangeStart(int menuState, boolean resize, Runnable callback);

        /**
         * Called when the PIP menu state has finished changing/animating.
         *
         * @param menuState the new state of the menu.
         */
        void onPipMenuStateChangeFinish(int menuState);

        /**
         * Called when the PIP requested to be expanded.
@@ -485,15 +492,15 @@ public class PhonePipMenuController implements PipMenuController {
    /**
     * Handles changes in menu visibility.
     */
    void onMenuStateChanged(int menuState, boolean resize, Runnable callback) {
    void onMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
        if (DEBUG) {
            Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
            Log.d(TAG, "onMenuStateChangeStart() mMenuState=" + mMenuState
                    + " menuState=" + menuState + " resize=" + resize
                    + " callers=\n" + Debug.getCallers(5, "    "));
        }

        if (menuState != mMenuState) {
            mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize, callback));
            mListeners.forEach(l -> l.onPipMenuStateChangeStart(menuState, resize, callback));
            if (menuState == MENU_STATE_FULL) {
                // Once visible, start listening for media action changes. This call will trigger
                // the menu actions to be updated again.
@@ -511,6 +518,12 @@ public class PhonePipMenuController implements PipMenuController {
                Log.e(TAG, "Unable to update focus as menu appears/disappears", e);
            }
        }
    }

    void onMenuStateChangeFinish(int menuState) {
        if (menuState != mMenuState) {
            mListeners.forEach(l -> l.onPipMenuStateChangeFinish(menuState));
        }
        mMenuState = menuState;
    }

+24 −16
Original line number Diff line number Diff line
@@ -276,17 +276,18 @@ public class PipMenuView extends FrameLayout {
            }
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
            mMenuContainerAnimator.setDuration(ANIMATION_HIDE_DURATION_MS);
            if (allowMenuTimeout) {
            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    notifyMenuStateChangeFinish(menuState);
                    if (allowMenuTimeout) {
                        repostDelayedHide(INITIAL_DISMISS_DELAY);
                    }
                });
                }
            });
            if (withDelay) {
                // starts the menu container animation after window expansion is completed
                notifyMenuStateChange(menuState, resizeMenuOnShow, () -> {
                notifyMenuStateChangeStart(menuState, resizeMenuOnShow, () -> {
                    if (mMenuContainerAnimator == null) {
                        return;
                    }
@@ -295,11 +296,11 @@ public class PipMenuView extends FrameLayout {
                    mMenuContainerAnimator.start();
                });
            } else {
                notifyMenuStateChange(menuState, resizeMenuOnShow, null);
                notifyMenuStateChangeStart(menuState, resizeMenuOnShow, null);
                setVisibility(VISIBLE);
                mMenuContainerAnimator.start();
            }
            updateActionViews(stackBounds);
            updateActionViews(menuState, stackBounds);
        } else {
            // If we are already visible, then just start the delayed dismiss and unregister any
            // existing input consumers from the previous drag
@@ -352,7 +353,7 @@ public class PipMenuView extends FrameLayout {
        if (mMenuState != MENU_STATE_NONE) {
            cancelDelayedHide();
            if (notifyMenuVisibility) {
                notifyMenuStateChange(MENU_STATE_NONE, resize, null);
                notifyMenuStateChangeStart(MENU_STATE_NONE, resize, null);
            }
            mMenuContainerAnimator = new AnimatorSet();
            ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
@@ -371,6 +372,9 @@ public class PipMenuView extends FrameLayout {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(GONE);
                    if (notifyMenuVisibility) {
                        notifyMenuStateChangeFinish(MENU_STATE_NONE);
                    }
                    if (animationFinishedRunnable != null) {
                        animationFinishedRunnable.run();
                    }
@@ -399,11 +403,11 @@ public class PipMenuView extends FrameLayout {
        mActions.clear();
        mActions.addAll(actions);
        if (mMenuState == MENU_STATE_FULL) {
            updateActionViews(stackBounds);
            updateActionViews(mMenuState, stackBounds);
        }
    }

    private void updateActionViews(Rect stackBounds) {
    private void updateActionViews(int menuState, Rect stackBounds) {
        ViewGroup expandContainer = findViewById(R.id.expand_container);
        ViewGroup actionsContainer = findViewById(R.id.actions_container);
        actionsContainer.setOnTouchListener((v, ev) -> {
@@ -412,13 +416,13 @@ public class PipMenuView extends FrameLayout {
        });

        // Update the expand button only if it should show with the menu
        expandContainer.setVisibility(mMenuState == MENU_STATE_FULL
        expandContainer.setVisibility(menuState == MENU_STATE_FULL
                ? View.VISIBLE
                : View.INVISIBLE);

        FrameLayout.LayoutParams expandedLp =
                (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
        if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE || mMenuState == MENU_STATE_NONE) {
        if (mActions.isEmpty() || menuState == MENU_STATE_CLOSE || menuState == MENU_STATE_NONE) {
            actionsContainer.setVisibility(View.INVISIBLE);

            // Update the expand container margin to adjust the center of the expand button to
@@ -488,9 +492,13 @@ public class PipMenuView extends FrameLayout {
        expandContainer.requestLayout();
    }

    private void notifyMenuStateChange(int menuState, boolean resize, Runnable callback) {
    private void notifyMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
        mController.onMenuStateChangeStart(menuState, resize, callback);
    }

    private void notifyMenuStateChangeFinish(int menuState) {
        mMenuState = menuState;
        mController.onMenuStateChanged(menuState, resize, callback);
        mController.onMenuStateChangeFinish(menuState);
    }

    private void expandPip() {
Loading