Merge "Synchronize PIP menu fade out with task dismiss" into sc-dev

This commit is contained in:
Jorge Gil
2021-04-30 15:53:32 +00:00
committed by Android (Google) Code Review
5 changed files with 71 additions and 30 deletions

View File

@@ -18,6 +18,8 @@ package com.android.wm.shell.pip.phone;
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.app.RemoteAction;
import android.content.Context;
@@ -397,26 +399,26 @@ public class PhonePipMenuController implements PipMenuController {
* Hides the menu view.
*/
public void hideMenu() {
hideMenu(true /* animate */, true /* resize */);
hideMenu(ANIM_TYPE_HIDE, true /* resize */);
}
/**
* 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
*/
public void hideMenu(boolean animate, boolean resize) {
public void hideMenu(@PipMenuView.AnimationType int animationType, boolean resize) {
final boolean isMenuVisible = isMenuVisible();
if (DEBUG) {
Log.d(TAG, "hideMenu() state=" + mMenuState
+ " isMenuVisible=" + isMenuVisible
+ " animate=" + animate
+ " animationType=" + animationType
+ " resize=" + resize
+ " callers=\n" + Debug.getCallers(5, " "));
}
if (isMenuVisible) {
mPipMenuView.hideMenu(animate, resize);
mPipMenuView.hideMenu(resize, animationType);
}
}

View File

@@ -32,6 +32,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.app.PendingIntent.CanceledException;
import android.app.RemoteAction;
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.pip.PipUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -74,9 +77,26 @@ public class PipMenuView extends FrameLayout {
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 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 float MENU_BACKGROUND_ALPHA = 0.3f;
@@ -87,6 +107,7 @@ public class PipMenuView extends FrameLayout {
private int mMenuState;
private boolean mAllowMenuTimeout = true;
private boolean mAllowTouches = true;
private int mDismissFadeOutDurationMs;
private final List<RemoteAction> mActions = new ArrayList<>();
@@ -167,6 +188,8 @@ public class PipMenuView extends FrameLayout {
mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(mContext);
mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
mResizeHandle, mSettingsButton, mDismissButton);
mDismissFadeOutDurationMs = context.getResources()
.getInteger(R.integer.config_pipExitAnimationDuration);
initAccessibility();
}
@@ -258,7 +281,7 @@ public class PipMenuView extends FrameLayout {
mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
}
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
mMenuContainerAnimator.setDuration(ANIMATION_HIDE_DURATION_MS);
if (allowMenuTimeout) {
mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -320,17 +343,18 @@ public class PipMenuView extends FrameLayout {
hideMenu(null);
}
void hideMenu(boolean animate, boolean resize) {
hideMenu(null, true /* notifyMenuVisibility */, animate, resize);
}
void hideMenu(Runnable animationEndCallback) {
hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* animate */,
true /* resize */);
hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* resize */,
ANIM_TYPE_HIDE);
}
private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
boolean animate, boolean resize) {
void hideMenu(boolean resize, @AnimationType int animationType) {
hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */, resize,
animationType);
}
void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
boolean resize, @AnimationType int animationType) {
if (mMenuState != MENU_STATE_NONE) {
cancelDelayedHide();
if (notifyMenuVisibility) {
@@ -348,7 +372,7 @@ public class PipMenuView extends FrameLayout {
mResizeHandle.getAlpha(), 0f);
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mMenuContainerAnimator.setDuration(animate ? MENU_FADE_DURATION : 0);
mMenuContainerAnimator.setDuration(getFadeOutDuration(animationType));
mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -478,19 +502,17 @@ public class PipMenuView extends FrameLayout {
private void expandPip() {
// Do not notify menu visibility when hiding the menu, the controller will do this when it
// handles the message
hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* animate */,
true /* resize */);
hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* resize */,
ANIM_TYPE_HIDE);
}
private void dismissPip() {
// Since tapping on the close-button invokes a double-tap wait callback in PipTouchHandler,
// we want to disable animating the fadeout animation of the buttons in order to call on
// PipTouchHandler#onPipDismiss fast enough.
final boolean animate = mMenuState != MENU_STATE_CLOSE;
// Do not notify menu visibility when hiding the menu, the controller will do this when it
// handles the message
hideMenu(mController::onPipDismiss, false /* notifyMenuVisibility */, animate,
true /* resize */);
if (mMenuState != MENU_STATE_NONE) {
// Do not call hideMenu() directly. Instead, let the menu controller handle it just as
// any other dismissal that will update the touch state and fade out the PIP task
// and the menu view at the same time.
mController.onPipDismiss();
}
}
private void showSettings() {
@@ -514,4 +536,17 @@ public class PipMenuView extends FrameLayout {
mMainExecutor.removeCallbacks(mHideMenuRunnable);
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);
}
}
}

View File

@@ -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.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.Nullable;
@@ -336,7 +338,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
+ " callers=\n" + Debug.getCallers(5, " "));
}
cancelPhysicsAnimation();
mMenuController.hideMenu(false /* animate */, false /* resize */);
mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
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, " "));
}
cancelPhysicsAnimation();
mMenuController.hideMenu(true /* animate*/, false /* resize */);
mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
mPipTaskOrganizer.removePip();
}

View File

@@ -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_RIGHT;
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.res.Resources;
@@ -471,7 +472,7 @@ public class PipResizeGestureHandler {
}
if (mThresholdCrossed) {
if (mPhonePipMenuController.isMenuVisible()) {
mPhonePipMenuController.hideMenu(false /* animate */,
mPhonePipMenuController.hideMenu(ANIM_TYPE_NONE,
false /* resize */);
}
final Rect currentPipBounds = mPipBoundsState.getBounds();

View File

@@ -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_FULL;
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.SuppressLint;
@@ -881,7 +882,7 @@ public class PipTouchHandler {
&& mPipBoundsState.getBounds().height()
< mPipBoundsState.getMaxSize().y;
if (mMenuController.isMenuVisible()) {
mMenuController.hideMenu(false /* animate */, false /* resize */);
mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
}
if (toExpand) {
mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());