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

Commit a8bf4800 authored by Jorge Gil's avatar Jorge Gil Committed by Automerger Merge Worker
Browse files

Merge "Synchronize PIP menu fade out with task dismiss" into sc-dev am: 83c75ac7 am: c60faca8

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

Change-Id: I8830e03721112a9f03a18c56a64df9c781e75e69
parents 46492d73 c60faca8
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.wm.shell.pip.phone;


import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;


import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_HIDE;

import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.RemoteAction;
import android.app.RemoteAction;
import android.content.Context;
import android.content.Context;
@@ -397,26 +399,26 @@ public class PhonePipMenuController implements PipMenuController {
     * Hides the menu view.
     * Hides the menu view.
     */
     */
    public void hideMenu() {
    public void hideMenu() {
        hideMenu(true /* animate */, true /* resize */);
        hideMenu(ANIM_TYPE_HIDE, true /* resize */);
    }
    }


    /**
    /**
     * Hides the menu view.
     * Hides the menu view.
     *
     *
     * @param animate whether to animate the menu fadeout
     * @param animationType the animation type to use upon hiding the menu
     * @param resize whether or not to resize the PiP with the state change
     * @param resize whether or not to resize the PiP with the state change
     */
     */
    public void hideMenu(boolean animate, boolean resize) {
    public void hideMenu(@PipMenuView.AnimationType int animationType, boolean resize) {
        final boolean isMenuVisible = isMenuVisible();
        final boolean isMenuVisible = isMenuVisible();
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "hideMenu() state=" + mMenuState
            Log.d(TAG, "hideMenu() state=" + mMenuState
                    + " isMenuVisible=" + isMenuVisible
                    + " isMenuVisible=" + isMenuVisible
                    + " animate=" + animate
                    + " animationType=" + animationType
                    + " resize=" + resize
                    + " resize=" + resize
                    + " callers=\n" + Debug.getCallers(5, "    "));
                    + " callers=\n" + Debug.getCallers(5, "    "));
        }
        }
        if (isMenuVisible) {
        if (isMenuVisible) {
            mPipMenuView.hideMenu(animate, resize);
            mPipMenuView.hideMenu(resize, animationType);
        }
        }
    }
    }


+55 −20
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.app.PendingIntent.CanceledException;
import android.app.PendingIntent.CanceledException;
import android.app.RemoteAction;
import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.ComponentName;
@@ -64,6 +65,8 @@ import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.pip.PipUtils;


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;


@@ -74,9 +77,26 @@ public class PipMenuView extends FrameLayout {


    private static final String TAG = "PipMenuView";
    private static final String TAG = "PipMenuView";


    private static final int ANIMATION_NONE_DURATION_MS = 0;
    private static final int ANIMATION_HIDE_DURATION_MS = 125;

    /** No animation performed during menu hide. */
    public static final int ANIM_TYPE_NONE = 0;
    /** Fade out the menu until it's invisible. Used when the PIP window remains visible.  */
    public static final int ANIM_TYPE_HIDE = 1;
    /** Fade out the menu in sync with the PIP window. */
    public static final int ANIM_TYPE_DISMISS = 2;

    @IntDef(prefix = { "ANIM_TYPE_" }, value = {
            ANIM_TYPE_NONE,
            ANIM_TYPE_HIDE,
            ANIM_TYPE_DISMISS
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AnimationType {}

    private static final int INITIAL_DISMISS_DELAY = 3500;
    private static final int INITIAL_DISMISS_DELAY = 3500;
    private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
    private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
    private static final long MENU_FADE_DURATION = 125;
    private static final long MENU_SHOW_ON_EXPAND_START_DELAY = 30;
    private static final long MENU_SHOW_ON_EXPAND_START_DELAY = 30;


    private static final float MENU_BACKGROUND_ALPHA = 0.3f;
    private static final float MENU_BACKGROUND_ALPHA = 0.3f;
@@ -87,6 +107,7 @@ public class PipMenuView extends FrameLayout {
    private int mMenuState;
    private int mMenuState;
    private boolean mAllowMenuTimeout = true;
    private boolean mAllowMenuTimeout = true;
    private boolean mAllowTouches = true;
    private boolean mAllowTouches = true;
    private int mDismissFadeOutDurationMs;


    private final List<RemoteAction> mActions = new ArrayList<>();
    private final List<RemoteAction> mActions = new ArrayList<>();


@@ -167,6 +188,8 @@ public class PipMenuView extends FrameLayout {
        mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(mContext);
        mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(mContext);
        mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
        mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
                mResizeHandle, mSettingsButton, mDismissButton);
                mResizeHandle, mSettingsButton, mDismissButton);
        mDismissFadeOutDurationMs = context.getResources()
                .getInteger(R.integer.config_pipExitAnimationDuration);


        initAccessibility();
        initAccessibility();
    }
    }
@@ -258,7 +281,7 @@ public class PipMenuView extends FrameLayout {
                mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
                mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
            }
            }
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
            mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
            mMenuContainerAnimator.setDuration(ANIMATION_HIDE_DURATION_MS);
            if (allowMenuTimeout) {
            if (allowMenuTimeout) {
                mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    @Override
@@ -320,17 +343,18 @@ public class PipMenuView extends FrameLayout {
        hideMenu(null);
        hideMenu(null);
    }
    }


    void hideMenu(boolean animate, boolean resize) {
    void hideMenu(Runnable animationEndCallback) {
        hideMenu(null, true /* notifyMenuVisibility */, animate, resize);
        hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* resize */,
                ANIM_TYPE_HIDE);
    }
    }


    void hideMenu(Runnable animationEndCallback) {
    void hideMenu(boolean resize, @AnimationType int animationType) {
        hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* animate */,
        hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */, resize,
                true /* resize */);
                animationType);
    }
    }


    private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
    void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
            boolean animate, boolean resize) {
            boolean resize, @AnimationType int animationType) {
        if (mMenuState != MENU_STATE_NONE) {
        if (mMenuState != MENU_STATE_NONE) {
            cancelDelayedHide();
            cancelDelayedHide();
            if (notifyMenuVisibility) {
            if (notifyMenuVisibility) {
@@ -348,7 +372,7 @@ public class PipMenuView extends FrameLayout {
                    mResizeHandle.getAlpha(), 0f);
                    mResizeHandle.getAlpha(), 0f);
            mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim);
            mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim);
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
            mMenuContainerAnimator.setDuration(animate ? MENU_FADE_DURATION : 0);
            mMenuContainerAnimator.setDuration(getFadeOutDuration(animationType));
            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                @Override
                public void onAnimationEnd(Animator animation) {
                public void onAnimationEnd(Animator animation) {
@@ -478,19 +502,17 @@ public class PipMenuView extends FrameLayout {
    private void expandPip() {
    private void expandPip() {
        // Do not notify menu visibility when hiding the menu, the controller will do this when it
        // Do not notify menu visibility when hiding the menu, the controller will do this when it
        // handles the message
        // handles the message
        hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* animate */,
        hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* resize */,
                true /* resize */);
                ANIM_TYPE_HIDE);
    }
    }


    private void dismissPip() {
    private void dismissPip() {
        // Since tapping on the close-button invokes a double-tap wait callback in PipTouchHandler,
        if (mMenuState != MENU_STATE_NONE) {
        // we want to disable animating the fadeout animation of the buttons in order to call on
            // Do not call hideMenu() directly. Instead, let the menu controller handle it just as
        // PipTouchHandler#onPipDismiss fast enough.
            // any other dismissal that will update the touch state and fade out the PIP task
        final boolean animate = mMenuState != MENU_STATE_CLOSE;
            // and the menu view at the same time.
        // Do not notify menu visibility when hiding the menu, the controller will do this when it
            mController.onPipDismiss();
        // handles the message
        }
        hideMenu(mController::onPipDismiss, false /* notifyMenuVisibility */, animate,
                true /* resize */);
    }
    }


    private void showSettings() {
    private void showSettings() {
@@ -514,4 +536,17 @@ public class PipMenuView extends FrameLayout {
        mMainExecutor.removeCallbacks(mHideMenuRunnable);
        mMainExecutor.removeCallbacks(mHideMenuRunnable);
        mMainExecutor.executeDelayed(mHideMenuRunnable, recommendedTimeout);
        mMainExecutor.executeDelayed(mHideMenuRunnable, recommendedTimeout);
    }
    }

    private long getFadeOutDuration(@AnimationType int animationType) {
        switch (animationType) {
            case ANIM_TYPE_NONE:
                return ANIMATION_NONE_DURATION_MS;
            case ANIM_TYPE_HIDE:
                return ANIMATION_HIDE_DURATION_MS;
            case ANIM_TYPE_DISMISS:
                return mDismissFadeOutDurationMs;
            default:
                throw new IllegalStateException("Invalid animation type " + animationType);
        }
    }
}
}
+4 −2
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;


import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND;
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE;
import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_DISMISS;
import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
@@ -336,7 +338,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
                    + " callers=\n" + Debug.getCallers(5, "    "));
                    + " callers=\n" + Debug.getCallers(5, "    "));
        }
        }
        cancelPhysicsAnimation();
        cancelPhysicsAnimation();
        mMenuController.hideMenu(false /* animate */, false /* resize */);
        mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
        mPipTaskOrganizer.exitPip(skipAnimation ? 0 : LEAVE_PIP_DURATION);
        mPipTaskOrganizer.exitPip(skipAnimation ? 0 : LEAVE_PIP_DURATION);
    }
    }


@@ -349,7 +351,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
            Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
            Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
        }
        }
        cancelPhysicsAnimation();
        cancelPhysicsAnimation();
        mMenuController.hideMenu(true /* animate*/, false /* resize */);
        mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
        mPipTaskOrganizer.removePip();
        mPipTaskOrganizer.removePip();
    }
    }


+2 −1
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP;
import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE;


import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
@@ -471,7 +472,7 @@ public class PipResizeGestureHandler {
                    }
                    }
                    if (mThresholdCrossed) {
                    if (mThresholdCrossed) {
                        if (mPhonePipMenuController.isMenuVisible()) {
                        if (mPhonePipMenuController.isMenuVisible()) {
                            mPhonePipMenuController.hideMenu(false /* animate */,
                            mPhonePipMenuController.hideMenu(ANIM_TYPE_NONE,
                                    false /* resize */);
                                    false /* resize */);
                        }
                        }
                        final Rect currentPipBounds = mPipBoundsState.getBounds();
                        final Rect currentPipBounds = mPipBoundsState.getBounds();
+2 −1
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_CLOSE;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_CLOSE;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE;
import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE;
import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SuppressLint;
@@ -881,7 +882,7 @@ public class PipTouchHandler {
                            && mPipBoundsState.getBounds().height()
                            && mPipBoundsState.getBounds().height()
                            < mPipBoundsState.getMaxSize().y;
                            < mPipBoundsState.getMaxSize().y;
                    if (mMenuController.isMenuVisible()) {
                    if (mMenuController.isMenuVisible()) {
                        mMenuController.hideMenu(false /* animate */, false /* resize */);
                        mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
                    }
                    }
                    if (toExpand) {
                    if (toExpand) {
                        mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
                        mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());