Merge "Apply timeout of one-shot pip animation type for shell transition" into udc-dev
This commit is contained in:
@@ -30,14 +30,17 @@ import android.app.TaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.os.SystemClock;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TaskSnapshot;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.wm.shell.animation.Interpolators;
|
||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -61,6 +64,14 @@ public class PipAnimationController {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AnimationType {}
|
||||
|
||||
/**
|
||||
* The alpha type is set for swiping to home. But the swiped task may not enter PiP. And if
|
||||
* another task enters PiP by non-swipe ways, e.g. call API in foreground or switch to 3-button
|
||||
* navigation, then the alpha type is unexpected. So use a timeout to avoid applying wrong
|
||||
* animation style to an unrelated task.
|
||||
*/
|
||||
private static final int ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS = 800;
|
||||
|
||||
public static final int TRANSITION_DIRECTION_NONE = 0;
|
||||
public static final int TRANSITION_DIRECTION_SAME = 1;
|
||||
public static final int TRANSITION_DIRECTION_TO_PIP = 2;
|
||||
@@ -109,6 +120,9 @@ public class PipAnimationController {
|
||||
});
|
||||
|
||||
private PipTransitionAnimator mCurrentAnimator;
|
||||
@AnimationType
|
||||
private int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
private long mLastOneShotAlphaAnimationTime;
|
||||
|
||||
public PipAnimationController(PipSurfaceTransactionHelper helper) {
|
||||
mSurfaceTransactionHelper = helper;
|
||||
@@ -221,6 +235,37 @@ public class PipAnimationController {
|
||||
animator.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred enter animation type for one time. This is typically used to set the
|
||||
* animation type to {@link PipAnimationController#ANIM_TYPE_ALPHA}.
|
||||
* <p>
|
||||
* For example, gesture navigation would first fade out the PiP activity, and the transition
|
||||
* should be responsible to animate in (such as fade in) the PiP.
|
||||
*/
|
||||
public void setOneShotEnterAnimationType(@AnimationType int animationType) {
|
||||
mOneShotAnimationType = animationType;
|
||||
if (animationType == ANIM_TYPE_ALPHA) {
|
||||
mLastOneShotAlphaAnimationTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the preferred animation type and consumes the one-shot type if needed. */
|
||||
@AnimationType
|
||||
public int takeOneShotEnterAnimationType() {
|
||||
final int type = mOneShotAnimationType;
|
||||
if (type == ANIM_TYPE_ALPHA) {
|
||||
// Restore to default type.
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
if (SystemClock.uptimeMillis() - mLastOneShotAlphaAnimationTime
|
||||
> ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
|
||||
"Alpha animation is expired. Use bounds animation.");
|
||||
return ANIM_TYPE_BOUNDS;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional callback interface for PiP animation
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
import android.view.Choreographer;
|
||||
@@ -111,12 +110,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
DisplayController.OnDisplaysChangedListener, ShellTaskOrganizer.FocusListener {
|
||||
private static final String TAG = PipTaskOrganizer.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
/**
|
||||
* The alpha type is set for swiping to home. But the swiped task may not enter PiP. And if
|
||||
* another task enters PiP by non-swipe ways, e.g. call API in foreground or switch to 3-button
|
||||
* navigation, then the alpha type is unexpected.
|
||||
*/
|
||||
private static final int ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS = 1000;
|
||||
|
||||
/**
|
||||
* The fixed start delay in ms when fading out the content overlay from bounds animation.
|
||||
@@ -301,8 +294,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
private WindowContainerToken mToken;
|
||||
private SurfaceControl mLeash;
|
||||
protected PipTransitionState mPipTransitionState;
|
||||
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
private long mLastOneShotAlphaAnimationTime;
|
||||
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
|
||||
mSurfaceControlTransactionFactory;
|
||||
protected PictureInPictureParams mPictureInPictureParams;
|
||||
@@ -421,18 +412,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
mOnDisplayIdChangeCallback = onDisplayIdChangeCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred animation type for one time.
|
||||
* This is typically used to set the animation type to
|
||||
* {@link PipAnimationController#ANIM_TYPE_ALPHA}.
|
||||
*/
|
||||
public void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) {
|
||||
mOneShotAnimationType = animationType;
|
||||
if (animationType == ANIM_TYPE_ALPHA) {
|
||||
mLastOneShotAlphaAnimationTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override if the PiP should always use a fade-in animation during PiP entry.
|
||||
*
|
||||
@@ -733,26 +712,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOneShotAnimationType == ANIM_TYPE_ALPHA
|
||||
&& SystemClock.uptimeMillis() - mLastOneShotAlphaAnimationTime
|
||||
> ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
|
||||
"%s: Alpha animation is expired. Use bounds animation.", TAG);
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
}
|
||||
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
// For Shell transition, we will animate the window in PipTransition#startAnimation
|
||||
// instead of #onTaskAppeared.
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldAlwaysFadeIn()) {
|
||||
mOneShotAnimationType = ANIM_TYPE_ALPHA;
|
||||
}
|
||||
|
||||
final int animationType = shouldAlwaysFadeIn()
|
||||
? ANIM_TYPE_ALPHA
|
||||
: mPipAnimationController.takeOneShotEnterAnimationType();
|
||||
if (mWaitForFixedRotation) {
|
||||
onTaskAppearedWithFixedRotation();
|
||||
onTaskAppearedWithFixedRotation(animationType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -763,7 +733,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
|
||||
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
|
||||
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
||||
if (animationType == ANIM_TYPE_BOUNDS) {
|
||||
if (!shouldAttachMenuEarly()) {
|
||||
mPipMenuController.attach(mLeash);
|
||||
}
|
||||
@@ -773,16 +743,15 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration,
|
||||
null /* updateBoundsCallback */);
|
||||
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
} else if (animationType == ANIM_TYPE_ALPHA) {
|
||||
enterPipWithAlphaAnimation(destinationBounds, mEnterAnimationDuration);
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
|
||||
throw new RuntimeException("Unrecognized animation type: " + animationType);
|
||||
}
|
||||
}
|
||||
|
||||
private void onTaskAppearedWithFixedRotation() {
|
||||
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
private void onTaskAppearedWithFixedRotation(int animationType) {
|
||||
if (animationType == ANIM_TYPE_ALPHA) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
|
||||
"%s: Defer entering PiP alpha animation, fixed rotation is ongoing", TAG);
|
||||
// If deferred, hside the surface till fixed rotation is completed.
|
||||
@@ -791,7 +760,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
tx.setAlpha(mLeash, 0f);
|
||||
tx.show(mLeash);
|
||||
tx.apply();
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
return;
|
||||
}
|
||||
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
@@ -1895,7 +1863,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
+ " binder=" + (mToken != null ? mToken.asBinder() : null));
|
||||
pw.println(innerPrefix + "mLeash=" + mLeash);
|
||||
pw.println(innerPrefix + "mState=" + mPipTransitionState.getTransitionState());
|
||||
pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
|
||||
pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class PipTransition extends PipTransitionController {
|
||||
private final int mEnterExitAnimationDuration;
|
||||
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
|
||||
private final Optional<SplitScreenController> mSplitScreenOptional;
|
||||
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
private @PipAnimationController.AnimationType int mEnterAnimationType = ANIM_TYPE_BOUNDS;
|
||||
private Transitions.TransitionFinishCallback mFinishCallback;
|
||||
private SurfaceControl.Transaction mFinishTransaction;
|
||||
private final Rect mExitDestinationBounds = new Rect();
|
||||
@@ -132,20 +132,6 @@ public class PipTransition extends PipTransitionController {
|
||||
mSplitScreenOptional = splitScreenOptional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsFullAnimation(boolean isFullAnimation) {
|
||||
setOneShotAnimationType(isFullAnimation ? ANIM_TYPE_BOUNDS : ANIM_TYPE_ALPHA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred animation type for one time.
|
||||
* This is typically used to set the animation type to
|
||||
* {@link PipAnimationController#ANIM_TYPE_ALPHA}.
|
||||
*/
|
||||
private void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) {
|
||||
mOneShotAnimationType = animationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startExitTransition(int type, WindowContainerTransaction out,
|
||||
@Nullable Rect destinationBounds) {
|
||||
@@ -288,7 +274,10 @@ public class PipTransition extends PipTransitionController {
|
||||
if (!requestHasPipEnter(request)) {
|
||||
throw new IllegalStateException("Called PiP augmentRequest when request has no PiP");
|
||||
}
|
||||
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
mEnterAnimationType = mPipOrganizer.shouldAlwaysFadeIn()
|
||||
? ANIM_TYPE_ALPHA
|
||||
: mPipAnimationController.takeOneShotEnterAnimationType();
|
||||
if (mEnterAnimationType == ANIM_TYPE_ALPHA) {
|
||||
mRequestedEnterTransition = transition;
|
||||
mRequestedEnterTask = request.getTriggerTask().token;
|
||||
outWCT.setActivityWindowingMode(request.getTriggerTask().token,
|
||||
@@ -308,7 +297,7 @@ public class PipTransition extends PipTransitionController {
|
||||
@Override
|
||||
public boolean handleRotateDisplay(int startRotation, int endRotation,
|
||||
WindowContainerTransaction wct) {
|
||||
if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
if (mRequestedEnterTransition != null && mEnterAnimationType == ANIM_TYPE_ALPHA) {
|
||||
// A fade-in was requested but not-yet started. In this case, just recalculate the
|
||||
// initial state under the new rotation.
|
||||
int rotationDelta = deltaRotation(startRotation, endRotation);
|
||||
@@ -760,7 +749,6 @@ public class PipTransition extends PipTransitionController {
|
||||
if (taskInfo.pictureInPictureParams != null
|
||||
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
|
||||
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mSwipePipToHomeOverlay;
|
||||
startTransaction.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
|
||||
.setPosition(leash, destinationBounds.left, destinationBounds.top)
|
||||
@@ -796,17 +784,16 @@ public class PipTransition extends PipTransitionController {
|
||||
startTransaction.setMatrix(leash, tmpTransform, new float[9]);
|
||||
}
|
||||
|
||||
if (mPipOrganizer.shouldAlwaysFadeIn()) {
|
||||
mOneShotAnimationType = ANIM_TYPE_ALPHA;
|
||||
}
|
||||
|
||||
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
final int enterAnimationType = mEnterAnimationType;
|
||||
if (enterAnimationType == ANIM_TYPE_ALPHA) {
|
||||
// Restore to default type.
|
||||
mEnterAnimationType = ANIM_TYPE_BOUNDS;
|
||||
startTransaction.setAlpha(leash, 0f);
|
||||
}
|
||||
startTransaction.apply();
|
||||
|
||||
PipAnimationController.PipTransitionAnimator animator;
|
||||
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
||||
if (enterAnimationType == ANIM_TYPE_BOUNDS) {
|
||||
animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
|
||||
currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
|
||||
0 /* startingAngle */, rotationDelta);
|
||||
@@ -829,13 +816,11 @@ public class PipTransition extends PipTransitionController {
|
||||
animator.setColorContentOverlay(mContext);
|
||||
}
|
||||
}
|
||||
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||
} else if (enterAnimationType == ANIM_TYPE_ALPHA) {
|
||||
animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
|
||||
0f, 1f);
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized animation type: "
|
||||
+ mOneShotAnimationType);
|
||||
throw new RuntimeException("Unrecognized animation type: " + enterAnimationType);
|
||||
}
|
||||
animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
|
||||
.setPipAnimationCallback(mPipAnimationCallback)
|
||||
|
||||
@@ -104,15 +104,6 @@ public abstract class PipTransitionController implements Transitions.TransitionH
|
||||
SurfaceControl.Transaction tx) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to inform the transition that the animation should start with the assumption that
|
||||
* PiP is not animating from its original bounds, but rather a continuation of another
|
||||
* animation. For example, gesture navigation would first fade out the PiP activity, and the
|
||||
* transition should be responsible to animate in (such as fade in) the PiP.
|
||||
*/
|
||||
public void setIsFullAnimation(boolean isFullAnimation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Shell wants to start an exit Pip transition/animation.
|
||||
*/
|
||||
|
||||
@@ -968,12 +968,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
mPipBoundsState.setShelfVisibility(visible, shelfHeight);
|
||||
}
|
||||
|
||||
private void setPinnedStackAnimationType(int animationType) {
|
||||
mPipTaskOrganizer.setOneShotAnimationType(animationType);
|
||||
mPipTransitionController.setIsFullAnimation(
|
||||
animationType == PipAnimationController.ANIM_TYPE_BOUNDS);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPinnedStackAnimationListener(PipAnimationListener callback) {
|
||||
mPinnedStackAnimationRecentsCallback = callback;
|
||||
@@ -1337,7 +1331,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
@Override
|
||||
public void setPipAnimationTypeToAlpha() {
|
||||
executeRemoteCallWithTaskPermission(mController, "setPipAnimationTypeToAlpha",
|
||||
(controller) -> controller.setPinnedStackAnimationType(ANIM_TYPE_ALPHA));
|
||||
(controller) -> controller.mPipAnimationController.setOneShotEnterAnimationType(
|
||||
ANIM_TYPE_ALPHA));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +262,8 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
||||
DisplayLayout layout = new DisplayLayout(info,
|
||||
mContext.getResources(), true, true);
|
||||
mPipDisplayLayoutState.setDisplayLayout(layout);
|
||||
mPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
|
||||
doReturn(PipAnimationController.ANIM_TYPE_ALPHA).when(mMockPipAnimationController)
|
||||
.takeOneShotEnterAnimationType();
|
||||
mPipTaskOrganizer.setSurfaceControlTransactionFactory(
|
||||
MockSurfaceControlHelper::createMockSurfaceControlTransaction);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user