Merge "PiP: Introduce PipTransitionState." into sc-v2-dev am: e9d456b056
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14687499 Change-Id: Idb0e54f74fed6d6421a4d3d9578fed9f67ddb94e
This commit is contained in:
@@ -107,38 +107,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
*/
|
*/
|
||||||
private static final int ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS = 1000;
|
private static final int ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
// Not a complete set of states but serves what we want right now.
|
|
||||||
private enum State {
|
|
||||||
UNDEFINED(0),
|
|
||||||
TASK_APPEARED(1),
|
|
||||||
ENTRY_SCHEDULED(2),
|
|
||||||
ENTERING_PIP(3),
|
|
||||||
ENTERED_PIP(4),
|
|
||||||
EXITING_PIP(5);
|
|
||||||
|
|
||||||
private final int mStateValue;
|
|
||||||
|
|
||||||
State(int value) {
|
|
||||||
mStateValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInPip() {
|
|
||||||
return mStateValue >= TASK_APPEARED.mStateValue
|
|
||||||
&& mStateValue != EXITING_PIP.mStateValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize request can be initiated in other component, ignore if we are no longer in PIP,
|
|
||||||
* still waiting for animation or we're exiting from it.
|
|
||||||
*
|
|
||||||
* @return {@code true} if the resize request should be blocked/ignored.
|
|
||||||
*/
|
|
||||||
private boolean shouldBlockResizeRequest() {
|
|
||||||
return mStateValue < ENTERING_PIP.mStateValue
|
|
||||||
|| mStateValue == EXITING_PIP.mStateValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final SyncTransactionQueue mSyncTransactionQueue;
|
private final SyncTransactionQueue mSyncTransactionQueue;
|
||||||
private final PipBoundsState mPipBoundsState;
|
private final PipBoundsState mPipBoundsState;
|
||||||
@@ -190,7 +158,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
}
|
}
|
||||||
final boolean isExitPipDirection = isOutPipDirection(direction)
|
final boolean isExitPipDirection = isOutPipDirection(direction)
|
||||||
|| isRemovePipDirection(direction);
|
|| isRemovePipDirection(direction);
|
||||||
if (mState != State.EXITING_PIP || isExitPipDirection) {
|
if (mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP
|
||||||
|
|| isExitPipDirection) {
|
||||||
// Finish resize as long as we're not exiting PIP, or, if we are, only if this is
|
// Finish resize as long as we're not exiting PIP, or, if we are, only if this is
|
||||||
// the end of an exit PIP animation.
|
// the end of an exit PIP animation.
|
||||||
// This is necessary in case there was a resize animation ongoing when exit PIP
|
// This is necessary in case there was a resize animation ongoing when exit PIP
|
||||||
@@ -233,7 +202,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
private ActivityManager.RunningTaskInfo mDeferredTaskInfo;
|
private ActivityManager.RunningTaskInfo mDeferredTaskInfo;
|
||||||
private WindowContainerToken mToken;
|
private WindowContainerToken mToken;
|
||||||
private SurfaceControl mLeash;
|
private SurfaceControl mLeash;
|
||||||
private State mState = State.UNDEFINED;
|
private PipTransitionState mPipTransitionState;
|
||||||
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||||
private long mLastOneShotAlphaAnimationTime;
|
private long mLastOneShotAlphaAnimationTime;
|
||||||
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
|
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
|
||||||
@@ -278,6 +247,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
|
|
||||||
public PipTaskOrganizer(Context context,
|
public PipTaskOrganizer(Context context,
|
||||||
@NonNull SyncTransactionQueue syncTransactionQueue,
|
@NonNull SyncTransactionQueue syncTransactionQueue,
|
||||||
|
@NonNull PipTransitionState pipTransitionState,
|
||||||
@NonNull PipBoundsState pipBoundsState,
|
@NonNull PipBoundsState pipBoundsState,
|
||||||
@NonNull PipBoundsAlgorithm boundsHandler,
|
@NonNull PipBoundsAlgorithm boundsHandler,
|
||||||
@NonNull PipMenuController pipMenuController,
|
@NonNull PipMenuController pipMenuController,
|
||||||
@@ -291,6 +261,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSyncTransactionQueue = syncTransactionQueue;
|
mSyncTransactionQueue = syncTransactionQueue;
|
||||||
|
mPipTransitionState = pipTransitionState;
|
||||||
mPipBoundsState = pipBoundsState;
|
mPipBoundsState = pipBoundsState;
|
||||||
mPipBoundsAlgorithm = boundsHandler;
|
mPipBoundsAlgorithm = boundsHandler;
|
||||||
mPipMenuController = pipMenuController;
|
mPipMenuController = pipMenuController;
|
||||||
@@ -326,14 +297,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInPip() {
|
public boolean isInPip() {
|
||||||
return mState.isInPip();
|
return mPipTransitionState.isInPip();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the entry animation is waiting to be started.
|
* Returns whether the entry animation is waiting to be started.
|
||||||
*/
|
*/
|
||||||
public boolean isEntryScheduled() {
|
public boolean isEntryScheduled() {
|
||||||
return mState == State.ENTRY_SCHEDULED;
|
return mPipTransitionState.getTransitionState() == PipTransitionState.ENTRY_SCHEDULED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -401,9 +372,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
* @param animationDurationMs duration in millisecond for the exiting PiP transition
|
* @param animationDurationMs duration in millisecond for the exiting PiP transition
|
||||||
*/
|
*/
|
||||||
public void exitPip(int animationDurationMs) {
|
public void exitPip(int animationDurationMs) {
|
||||||
if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) {
|
if (!mPipTransitionState.isInPip()
|
||||||
|
|| mPipTransitionState.getTransitionState() == PipTransitionState.EXITING_PIP
|
||||||
|
|| mToken == null) {
|
||||||
Log.wtf(TAG, "Not allowed to exitPip in current state"
|
Log.wtf(TAG, "Not allowed to exitPip in current state"
|
||||||
+ " mState=" + mState + " mToken=" + mToken);
|
+ " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +400,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
wct.setBoundsChangeTransaction(mToken, tx);
|
wct.setBoundsChangeTransaction(mToken, tx);
|
||||||
// Set the exiting state first so if there is fixed rotation later, the running animation
|
// Set the exiting state first so if there is fixed rotation later, the running animation
|
||||||
// won't be interrupted by alpha animation for existing PiP.
|
// won't be interrupted by alpha animation for existing PiP.
|
||||||
mState = State.EXITING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);
|
||||||
|
|
||||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||||
mPipTransitionController.startTransition(destinationBounds, wct);
|
mPipTransitionController.startTransition(destinationBounds, wct);
|
||||||
@@ -470,9 +443,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
* Removes PiP immediately.
|
* Removes PiP immediately.
|
||||||
*/
|
*/
|
||||||
public void removePip() {
|
public void removePip() {
|
||||||
if (!mState.isInPip() || mToken == null) {
|
if (!mPipTransitionState.isInPip() || mToken == null) {
|
||||||
Log.wtf(TAG, "Not allowed to removePip in current state"
|
Log.wtf(TAG, "Not allowed to removePip in current state"
|
||||||
+ " mState=" + mState + " mToken=" + mToken);
|
+ " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +459,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
animator.setDuration(mExitAnimationDuration);
|
animator.setDuration(mExitAnimationDuration);
|
||||||
animator.setInterpolator(Interpolators.ALPHA_OUT);
|
animator.setInterpolator(Interpolators.ALPHA_OUT);
|
||||||
animator.start();
|
animator.start();
|
||||||
mState = State.EXITING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removePipImmediately() {
|
private void removePipImmediately() {
|
||||||
@@ -508,7 +481,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
Objects.requireNonNull(info, "Requires RunningTaskInfo");
|
Objects.requireNonNull(info, "Requires RunningTaskInfo");
|
||||||
mTaskInfo = info;
|
mTaskInfo = info;
|
||||||
mToken = mTaskInfo.token;
|
mToken = mTaskInfo.token;
|
||||||
mState = State.TASK_APPEARED;
|
mPipTransitionState.setTransitionState(PipTransitionState.TASK_APPEARED);
|
||||||
mLeash = leash;
|
mLeash = leash;
|
||||||
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
|
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
|
||||||
setBoundsStateForEntry(mTaskInfo.topActivity, mPictureInPictureParams,
|
setBoundsStateForEntry(mTaskInfo.topActivity, mPictureInPictureParams,
|
||||||
@@ -562,7 +535,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
scheduleAnimateResizePip(currentBounds, destinationBounds, 0 /* startingAngle */,
|
scheduleAnimateResizePip(currentBounds, destinationBounds, 0 /* startingAngle */,
|
||||||
sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration,
|
sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration,
|
||||||
null /* updateBoundsCallback */);
|
null /* updateBoundsCallback */);
|
||||||
mState = State.ENTERING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||||
enterPipWithAlphaAnimation(destinationBounds, mEnterAnimationDuration);
|
enterPipWithAlphaAnimation(destinationBounds, mEnterAnimationDuration);
|
||||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||||
@@ -589,7 +562,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
|
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
|
||||||
animateResizePip(currentBounds, destinationBounds, sourceHintRect,
|
animateResizePip(currentBounds, destinationBounds, sourceHintRect,
|
||||||
TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration, 0 /* startingAngle */);
|
TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration, 0 /* startingAngle */);
|
||||||
mState = State.ENTERING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -614,7 +587,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mSurfaceControlTransactionFactory.getTransaction();
|
mSurfaceControlTransactionFactory.getTransaction();
|
||||||
tx.setAlpha(mLeash, 0f);
|
tx.setAlpha(mLeash, 0f);
|
||||||
tx.apply();
|
tx.apply();
|
||||||
mState = State.ENTRY_SCHEDULED;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTRY_SCHEDULED);
|
||||||
applyEnterPipSyncTransaction(destinationBounds, () -> {
|
applyEnterPipSyncTransaction(destinationBounds, () -> {
|
||||||
mPipAnimationController
|
mPipAnimationController
|
||||||
.getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)
|
.getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)
|
||||||
@@ -625,7 +598,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
.start();
|
.start();
|
||||||
// mState is set right after the animation is kicked off to block any resize
|
// mState is set right after the animation is kicked off to block any resize
|
||||||
// requests such as offsetPip that may have been called prior to the transition.
|
// requests such as offsetPip that may have been called prior to the transition.
|
||||||
mState = State.ENTERING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
}, null /* boundsChangeTransaction */);
|
}, null /* boundsChangeTransaction */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +645,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
private void sendOnPipTransitionStarted(
|
private void sendOnPipTransitionStarted(
|
||||||
@PipAnimationController.TransitionDirection int direction) {
|
@PipAnimationController.TransitionDirection int direction) {
|
||||||
if (direction == TRANSITION_DIRECTION_TO_PIP) {
|
if (direction == TRANSITION_DIRECTION_TO_PIP) {
|
||||||
mState = State.ENTERING_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
}
|
}
|
||||||
mPipTransitionController.sendOnPipTransitionStarted(direction);
|
mPipTransitionController.sendOnPipTransitionStarted(direction);
|
||||||
}
|
}
|
||||||
@@ -681,7 +654,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
void sendOnPipTransitionFinished(
|
void sendOnPipTransitionFinished(
|
||||||
@PipAnimationController.TransitionDirection int direction) {
|
@PipAnimationController.TransitionDirection int direction) {
|
||||||
if (direction == TRANSITION_DIRECTION_TO_PIP) {
|
if (direction == TRANSITION_DIRECTION_TO_PIP) {
|
||||||
mState = State.ENTERED_PIP;
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP);
|
||||||
}
|
}
|
||||||
mPipTransitionController.sendOnPipTransitionFinished(direction);
|
mPipTransitionController.sendOnPipTransitionFinished(direction);
|
||||||
// Apply the deferred RunningTaskInfo if applicable after all proper callbacks are sent.
|
// Apply the deferred RunningTaskInfo if applicable after all proper callbacks are sent.
|
||||||
@@ -706,7 +679,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
|
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
|
||||||
if (mState == State.UNDEFINED) {
|
if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final WindowContainerToken token = info.token;
|
final WindowContainerToken token = info.token;
|
||||||
@@ -718,7 +691,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
clearWaitForFixedRotation();
|
clearWaitForFixedRotation();
|
||||||
mInSwipePipToHomeTransition = false;
|
mInSwipePipToHomeTransition = false;
|
||||||
mPictureInPictureParams = null;
|
mPictureInPictureParams = null;
|
||||||
mState = State.UNDEFINED;
|
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
|
||||||
// Re-set the PIP bounds to none.
|
// Re-set the PIP bounds to none.
|
||||||
mPipBoundsState.setBounds(new Rect());
|
mPipBoundsState.setBounds(new Rect());
|
||||||
mPipUiEventLoggerLogger.setTaskInfo(null);
|
mPipUiEventLoggerLogger.setTaskInfo(null);
|
||||||
@@ -732,8 +705,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
@Override
|
@Override
|
||||||
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
|
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
|
||||||
Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
|
Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
|
||||||
if (mState != State.ENTERED_PIP && mState != State.EXITING_PIP) {
|
if (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP
|
||||||
Log.d(TAG, "Defer onTaskInfoChange in current state: " + mState);
|
&& mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP) {
|
||||||
|
Log.d(TAG, "Defer onTaskInfoChange in current state: "
|
||||||
|
+ mPipTransitionState.getTransitionState());
|
||||||
// Defer applying PiP parameters if the task is entering PiP to avoid disturbing
|
// Defer applying PiP parameters if the task is entering PiP to avoid disturbing
|
||||||
// the animation.
|
// the animation.
|
||||||
mDeferredTaskInfo = info;
|
mDeferredTaskInfo = info;
|
||||||
@@ -766,7 +741,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mNextRotation = newRotation;
|
mNextRotation = newRotation;
|
||||||
mWaitForFixedRotation = true;
|
mWaitForFixedRotation = true;
|
||||||
|
|
||||||
if (mState.isInPip()) {
|
if (mPipTransitionState.isInPip()) {
|
||||||
// Fade out the existing PiP to avoid jump cut during seamless rotation.
|
// Fade out the existing PiP to avoid jump cut during seamless rotation.
|
||||||
fadeExistingPip(false /* show */);
|
fadeExistingPip(false /* show */);
|
||||||
}
|
}
|
||||||
@@ -777,7 +752,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
if (!mWaitForFixedRotation) {
|
if (!mWaitForFixedRotation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mState == State.TASK_APPEARED) {
|
if (mPipTransitionState.getTransitionState() == PipTransitionState.TASK_APPEARED) {
|
||||||
if (mInSwipePipToHomeTransition) {
|
if (mInSwipePipToHomeTransition) {
|
||||||
onEndOfSwipePipToHomeTransition();
|
onEndOfSwipePipToHomeTransition();
|
||||||
} else {
|
} else {
|
||||||
@@ -785,9 +760,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
enterPipWithAlphaAnimation(mPipBoundsAlgorithm.getEntryDestinationBounds(),
|
enterPipWithAlphaAnimation(mPipBoundsAlgorithm.getEntryDestinationBounds(),
|
||||||
mEnterAnimationDuration);
|
mEnterAnimationDuration);
|
||||||
}
|
}
|
||||||
} else if (mState == State.ENTERED_PIP && mHasFadeOut) {
|
} else if (mPipTransitionState.getTransitionState() == PipTransitionState.ENTERED_PIP
|
||||||
|
&& mHasFadeOut) {
|
||||||
fadeExistingPip(true /* show */);
|
fadeExistingPip(true /* show */);
|
||||||
} else if (mState == State.ENTERING_PIP && mDeferredAnimEndTransaction != null) {
|
} else if (mPipTransitionState.getTransitionState() == PipTransitionState.ENTERING_PIP
|
||||||
|
&& mDeferredAnimEndTransaction != null) {
|
||||||
final PipAnimationController.PipTransitionAnimator<?> animator =
|
final PipAnimationController.PipTransitionAnimator<?> animator =
|
||||||
mPipAnimationController.getCurrentAnimator();
|
mPipAnimationController.getCurrentAnimator();
|
||||||
final Rect destinationBounds = animator.getDestinationBounds();
|
final Rect destinationBounds = animator.getDestinationBounds();
|
||||||
@@ -848,7 +825,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mPipAnimationController.getCurrentAnimator();
|
mPipAnimationController.getCurrentAnimator();
|
||||||
if (animator == null || !animator.isRunning()
|
if (animator == null || !animator.isRunning()
|
||||||
|| animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) {
|
|| animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) {
|
||||||
final boolean rotatingPip = mState.isInPip() && fromRotation;
|
final boolean rotatingPip = mPipTransitionState.isInPip() && fromRotation;
|
||||||
if (rotatingPip && mWaitForFixedRotation && mHasFadeOut) {
|
if (rotatingPip && mWaitForFixedRotation && mHasFadeOut) {
|
||||||
// The position will be used by fade-in animation when the fixed rotation is done.
|
// The position will be used by fade-in animation when the fixed rotation is done.
|
||||||
mPipBoundsState.setBounds(destinationBoundsOut);
|
mPipBoundsState.setBounds(destinationBoundsOut);
|
||||||
@@ -981,7 +958,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
Rect currentBounds, Rect destinationBounds, float startingAngle, Rect sourceHintRect,
|
Rect currentBounds, Rect destinationBounds, float startingAngle, Rect sourceHintRect,
|
||||||
@PipAnimationController.TransitionDirection int direction, int durationMs,
|
@PipAnimationController.TransitionDirection int direction, int durationMs,
|
||||||
Consumer<Rect> updateBoundsCallback) {
|
Consumer<Rect> updateBoundsCallback) {
|
||||||
if (!mState.isInPip()) {
|
if (!mPipTransitionState.isInPip()) {
|
||||||
// TODO: tend to use shouldBlockResizeRequest here as well but need to consider
|
// TODO: tend to use shouldBlockResizeRequest here as well but need to consider
|
||||||
// the fact that when in exitPip, scheduleAnimateResizePip is executed in the window
|
// the fact that when in exitPip, scheduleAnimateResizePip is executed in the window
|
||||||
// container transaction callback and we want to set the mState immediately.
|
// container transaction callback and we want to set the mState immediately.
|
||||||
@@ -1011,7 +988,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
|
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
|
||||||
mSurfaceTransactionHelper
|
mSurfaceTransactionHelper
|
||||||
.crop(tx, mLeash, toBounds)
|
.crop(tx, mLeash, toBounds)
|
||||||
.round(tx, mLeash, mState.isInPip());
|
.round(tx, mLeash, mPipTransitionState.isInPip());
|
||||||
if (mPipMenuController.isMenuVisible()) {
|
if (mPipMenuController.isMenuVisible()) {
|
||||||
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
|
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
|
||||||
} else {
|
} else {
|
||||||
@@ -1089,7 +1066,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
public void scheduleFinishResizePip(Rect destinationBounds,
|
public void scheduleFinishResizePip(Rect destinationBounds,
|
||||||
@PipAnimationController.TransitionDirection int direction,
|
@PipAnimationController.TransitionDirection int direction,
|
||||||
Consumer<Rect> updateBoundsCallback) {
|
Consumer<Rect> updateBoundsCallback) {
|
||||||
if (mState.shouldBlockResizeRequest()) {
|
if (mPipTransitionState.shouldBlockResizeRequest()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1106,7 +1083,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mSurfaceTransactionHelper
|
mSurfaceTransactionHelper
|
||||||
.crop(tx, mLeash, destinationBounds)
|
.crop(tx, mLeash, destinationBounds)
|
||||||
.resetScale(tx, mLeash, destinationBounds)
|
.resetScale(tx, mLeash, destinationBounds)
|
||||||
.round(tx, mLeash, mState.isInPip());
|
.round(tx, mLeash, mPipTransitionState.isInPip());
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,7 +1092,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
*/
|
*/
|
||||||
public void scheduleOffsetPip(Rect originalBounds, int offset, int duration,
|
public void scheduleOffsetPip(Rect originalBounds, int offset, int duration,
|
||||||
Consumer<Rect> updateBoundsCallback) {
|
Consumer<Rect> updateBoundsCallback) {
|
||||||
if (mState.shouldBlockResizeRequest()) {
|
if (mPipTransitionState.shouldBlockResizeRequest()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mWaitForFixedRotation) {
|
if (mWaitForFixedRotation) {
|
||||||
@@ -1373,7 +1350,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
pw.println(innerPrefix + "mToken=" + mToken
|
pw.println(innerPrefix + "mToken=" + mToken
|
||||||
+ " binder=" + (mToken != null ? mToken.asBinder() : null));
|
+ " binder=" + (mToken != null ? mToken.asBinder() : null));
|
||||||
pw.println(innerPrefix + "mLeash=" + mLeash);
|
pw.println(innerPrefix + "mLeash=" + mLeash);
|
||||||
pw.println(innerPrefix + "mState=" + mState);
|
pw.println(innerPrefix + "mState=" + mPipTransitionState.getTransitionState());
|
||||||
pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
|
pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
|
||||||
pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
|
pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,19 +52,23 @@ import com.android.wm.shell.transition.Transitions;
|
|||||||
*/
|
*/
|
||||||
public class PipTransition extends PipTransitionController {
|
public class PipTransition extends PipTransitionController {
|
||||||
|
|
||||||
|
private final PipTransitionState mPipTransitionState;
|
||||||
private final int mEnterExitAnimationDuration;
|
private final int mEnterExitAnimationDuration;
|
||||||
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||||
private Transitions.TransitionFinishCallback mFinishCallback;
|
private Transitions.TransitionFinishCallback mFinishCallback;
|
||||||
private Rect mExitDestinationBounds = new Rect();
|
private Rect mExitDestinationBounds = new Rect();
|
||||||
|
|
||||||
public PipTransition(Context context,
|
public PipTransition(Context context,
|
||||||
PipBoundsState pipBoundsState, PipMenuController pipMenuController,
|
PipBoundsState pipBoundsState,
|
||||||
|
PipTransitionState pipTransitionState,
|
||||||
|
PipMenuController pipMenuController,
|
||||||
PipBoundsAlgorithm pipBoundsAlgorithm,
|
PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||||
PipAnimationController pipAnimationController,
|
PipAnimationController pipAnimationController,
|
||||||
Transitions transitions,
|
Transitions transitions,
|
||||||
@NonNull ShellTaskOrganizer shellTaskOrganizer) {
|
@NonNull ShellTaskOrganizer shellTaskOrganizer) {
|
||||||
super(pipBoundsState, pipMenuController, pipBoundsAlgorithm,
|
super(pipBoundsState, pipMenuController, pipBoundsAlgorithm,
|
||||||
pipAnimationController, transitions, shellTaskOrganizer);
|
pipAnimationController, transitions, shellTaskOrganizer);
|
||||||
|
mPipTransitionState = pipTransitionState;
|
||||||
mEnterExitAnimationDuration = context.getResources()
|
mEnterExitAnimationDuration = context.getResources()
|
||||||
.getInteger(R.integer.config_pipResizeAnimationDuration);
|
.getInteger(R.integer.config_pipResizeAnimationDuration);
|
||||||
}
|
}
|
||||||
@@ -85,6 +89,7 @@ public class PipTransition extends PipTransitionController {
|
|||||||
if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) {
|
if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) {
|
||||||
final TransitionInfo.Change change = info.getChanges().get(0);
|
final TransitionInfo.Change change = info.getChanges().get(0);
|
||||||
mFinishCallback = finishCallback;
|
mFinishCallback = finishCallback;
|
||||||
|
startTransaction.apply();
|
||||||
boolean success = startExpandAnimation(change.getTaskInfo(), change.getLeash(),
|
boolean success = startExpandAnimation(change.getTaskInfo(), change.getLeash(),
|
||||||
new Rect(mExitDestinationBounds));
|
new Rect(mExitDestinationBounds));
|
||||||
mExitDestinationBounds.setEmpty();
|
mExitDestinationBounds.setEmpty();
|
||||||
@@ -114,6 +119,7 @@ public class PipTransition extends PipTransitionController {
|
|||||||
startTransaction.setAlpha(wallpaper.getLeash(), 1.f);
|
startTransaction.setAlpha(wallpaper.getLeash(), 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
mFinishCallback = finishCallback;
|
mFinishCallback = finishCallback;
|
||||||
return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
|
return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
|
||||||
startTransaction, finishTransaction);
|
startTransaction, finishTransaction);
|
||||||
@@ -130,6 +136,9 @@ public class PipTransition extends PipTransitionController {
|
|||||||
public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
|
public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
|
||||||
@PipAnimationController.TransitionDirection int direction,
|
@PipAnimationController.TransitionDirection int direction,
|
||||||
SurfaceControl.Transaction tx) {
|
SurfaceControl.Transaction tx) {
|
||||||
|
if (isInPipDirection(direction)) {
|
||||||
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP);
|
||||||
|
}
|
||||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
prepareFinishResizeTransaction(taskInfo, destinationBounds,
|
prepareFinishResizeTransaction(taskInfo, destinationBounds,
|
||||||
direction, tx, wct);
|
direction, tx, wct);
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.wm.shell.pip;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to keep track of PiP leash state as it appears and animates by {@link PipTaskOrganizer} and
|
||||||
|
* {@link PipTransition}.
|
||||||
|
*/
|
||||||
|
public class PipTransitionState {
|
||||||
|
|
||||||
|
public static final int UNDEFINED = 0;
|
||||||
|
public static final int TASK_APPEARED = 1;
|
||||||
|
public static final int ENTRY_SCHEDULED = 2;
|
||||||
|
public static final int ENTERING_PIP = 3;
|
||||||
|
public static final int ENTERED_PIP = 4;
|
||||||
|
public static final int EXITING_PIP = 5;
|
||||||
|
|
||||||
|
// Not a complete set of states but serves what we want right now.
|
||||||
|
@IntDef(prefix = { "TRANSITION_STATE_" }, value = {
|
||||||
|
UNDEFINED,
|
||||||
|
TASK_APPEARED,
|
||||||
|
ENTRY_SCHEDULED,
|
||||||
|
ENTERING_PIP,
|
||||||
|
ENTERED_PIP,
|
||||||
|
EXITING_PIP
|
||||||
|
})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface TransitionState {}
|
||||||
|
|
||||||
|
private @TransitionState int mState;
|
||||||
|
|
||||||
|
public PipTransitionState() {
|
||||||
|
mState = UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransitionState(@TransitionState int state) {
|
||||||
|
mState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @TransitionState int getTransitionState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInPip() {
|
||||||
|
return mState >= TASK_APPEARED
|
||||||
|
&& mState != EXITING_PIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize request can be initiated in other component, ignore if we are no longer in PIP,
|
||||||
|
* still waiting for animation or we're exiting from it.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the resize request should be blocked/ignored.
|
||||||
|
*/
|
||||||
|
public boolean shouldBlockResizeRequest() {
|
||||||
|
return mState < ENTERING_PIP
|
||||||
|
|| mState == EXITING_PIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,6 +79,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
|||||||
@Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
|
@Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
|
||||||
private TestShellExecutor mMainExecutor;
|
private TestShellExecutor mMainExecutor;
|
||||||
private PipBoundsState mPipBoundsState;
|
private PipBoundsState mPipBoundsState;
|
||||||
|
private PipTransitionState mPipTransitionState;
|
||||||
private PipBoundsAlgorithm mPipBoundsAlgorithm;
|
private PipBoundsAlgorithm mPipBoundsAlgorithm;
|
||||||
|
|
||||||
private ComponentName mComponent1;
|
private ComponentName mComponent1;
|
||||||
@@ -90,11 +91,12 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
|||||||
mComponent1 = new ComponentName(mContext, "component1");
|
mComponent1 = new ComponentName(mContext, "component1");
|
||||||
mComponent2 = new ComponentName(mContext, "component2");
|
mComponent2 = new ComponentName(mContext, "component2");
|
||||||
mPipBoundsState = new PipBoundsState(mContext);
|
mPipBoundsState = new PipBoundsState(mContext);
|
||||||
|
mPipTransitionState = new PipTransitionState();
|
||||||
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
|
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
|
||||||
new PipSnapAlgorithm());
|
new PipSnapAlgorithm());
|
||||||
mMainExecutor = new TestShellExecutor();
|
mMainExecutor = new TestShellExecutor();
|
||||||
mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext,
|
mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext,
|
||||||
mMockSyncTransactionQueue, mPipBoundsState,
|
mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
|
||||||
mPipBoundsAlgorithm, mMockPhonePipMenuController,
|
mPipBoundsAlgorithm, mMockPhonePipMenuController,
|
||||||
mMockPipAnimationController, mMockPipSurfaceTransactionHelper,
|
mMockPipAnimationController, mMockPipSurfaceTransactionHelper,
|
||||||
mMockPipTransitionController, mMockOptionalSplitScreen, mMockDisplayController,
|
mMockPipTransitionController, mMockOptionalSplitScreen, mMockDisplayController,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.android.wm.shell.pip.PipSnapAlgorithm;
|
|||||||
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
||||||
import com.android.wm.shell.pip.PipTaskOrganizer;
|
import com.android.wm.shell.pip.PipTaskOrganizer;
|
||||||
import com.android.wm.shell.pip.PipTransitionController;
|
import com.android.wm.shell.pip.PipTransitionController;
|
||||||
|
import com.android.wm.shell.pip.PipTransitionState;
|
||||||
import com.android.wm.shell.pip.PipUiEventLogger;
|
import com.android.wm.shell.pip.PipUiEventLogger;
|
||||||
import com.android.wm.shell.pip.tv.TvPipController;
|
import com.android.wm.shell.pip.tv.TvPipController;
|
||||||
import com.android.wm.shell.pip.tv.TvPipMenuController;
|
import com.android.wm.shell.pip.tv.TvPipMenuController;
|
||||||
@@ -142,12 +143,19 @@ public abstract class TvPipModule {
|
|||||||
return new PipAnimationController(pipSurfaceTransactionHelper);
|
return new PipAnimationController(pipSurfaceTransactionHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WMSingleton
|
||||||
|
@Provides
|
||||||
|
static PipTransitionState providePipTransitionState() {
|
||||||
|
return new PipTransitionState();
|
||||||
|
}
|
||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
@Provides
|
@Provides
|
||||||
static PipTaskOrganizer providePipTaskOrganizer(Context context,
|
static PipTaskOrganizer providePipTaskOrganizer(Context context,
|
||||||
TvPipMenuController tvPipMenuController,
|
TvPipMenuController tvPipMenuController,
|
||||||
SyncTransactionQueue syncTransactionQueue,
|
SyncTransactionQueue syncTransactionQueue,
|
||||||
PipBoundsState pipBoundsState,
|
PipBoundsState pipBoundsState,
|
||||||
|
PipTransitionState pipTransitionState,
|
||||||
PipBoundsAlgorithm pipBoundsAlgorithm,
|
PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||||
PipAnimationController pipAnimationController,
|
PipAnimationController pipAnimationController,
|
||||||
PipTransitionController pipTransitionController,
|
PipTransitionController pipTransitionController,
|
||||||
@@ -157,7 +165,7 @@ public abstract class TvPipModule {
|
|||||||
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
|
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
|
||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor) {
|
||||||
return new PipTaskOrganizer(context,
|
return new PipTaskOrganizer(context,
|
||||||
syncTransactionQueue, pipBoundsState, pipBoundsAlgorithm,
|
syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
|
||||||
tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper,
|
tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper,
|
||||||
pipTransitionController, splitScreenOptional, displayController, pipUiEventLogger,
|
pipTransitionController, splitScreenOptional, displayController, pipUiEventLogger,
|
||||||
shellTaskOrganizer, mainExecutor);
|
shellTaskOrganizer, mainExecutor);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
|||||||
import com.android.wm.shell.pip.PipTaskOrganizer;
|
import com.android.wm.shell.pip.PipTaskOrganizer;
|
||||||
import com.android.wm.shell.pip.PipTransition;
|
import com.android.wm.shell.pip.PipTransition;
|
||||||
import com.android.wm.shell.pip.PipTransitionController;
|
import com.android.wm.shell.pip.PipTransitionController;
|
||||||
|
import com.android.wm.shell.pip.PipTransitionState;
|
||||||
import com.android.wm.shell.pip.PipUiEventLogger;
|
import com.android.wm.shell.pip.PipUiEventLogger;
|
||||||
import com.android.wm.shell.pip.phone.PhonePipMenuController;
|
import com.android.wm.shell.pip.phone.PhonePipMenuController;
|
||||||
import com.android.wm.shell.pip.phone.PipAppOpsListener;
|
import com.android.wm.shell.pip.phone.PipAppOpsListener;
|
||||||
@@ -182,10 +183,17 @@ public class WMShellModule {
|
|||||||
floatingContentCoordinator, pipUiEventLogger, mainExecutor);
|
floatingContentCoordinator, pipUiEventLogger, mainExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WMSingleton
|
||||||
|
@Provides
|
||||||
|
static PipTransitionState providePipTransitionState() {
|
||||||
|
return new PipTransitionState();
|
||||||
|
}
|
||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
@Provides
|
@Provides
|
||||||
static PipTaskOrganizer providePipTaskOrganizer(Context context,
|
static PipTaskOrganizer providePipTaskOrganizer(Context context,
|
||||||
SyncTransactionQueue syncTransactionQueue,
|
SyncTransactionQueue syncTransactionQueue,
|
||||||
|
PipTransitionState pipTransitionState,
|
||||||
PipBoundsState pipBoundsState,
|
PipBoundsState pipBoundsState,
|
||||||
PipBoundsAlgorithm pipBoundsAlgorithm,
|
PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||||
PhonePipMenuController menuPhoneController,
|
PhonePipMenuController menuPhoneController,
|
||||||
@@ -197,7 +205,7 @@ public class WMShellModule {
|
|||||||
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
|
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
|
||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor) {
|
||||||
return new PipTaskOrganizer(context,
|
return new PipTaskOrganizer(context,
|
||||||
syncTransactionQueue, pipBoundsState, pipBoundsAlgorithm,
|
syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
|
||||||
menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
|
menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
|
||||||
pipTransitionController, splitScreenOptional, displayController, pipUiEventLogger,
|
pipTransitionController, splitScreenOptional, displayController, pipUiEventLogger,
|
||||||
shellTaskOrganizer, mainExecutor);
|
shellTaskOrganizer, mainExecutor);
|
||||||
@@ -215,8 +223,9 @@ public class WMShellModule {
|
|||||||
static PipTransitionController providePipTransitionController(Context context,
|
static PipTransitionController providePipTransitionController(Context context,
|
||||||
Transitions transitions, ShellTaskOrganizer shellTaskOrganizer,
|
Transitions transitions, ShellTaskOrganizer shellTaskOrganizer,
|
||||||
PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
|
PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||||
PipBoundsState pipBoundsState, PhonePipMenuController pipMenuController) {
|
PipBoundsState pipBoundsState, PipTransitionState pipTransitionState,
|
||||||
return new PipTransition(context, pipBoundsState, pipMenuController,
|
PhonePipMenuController pipMenuController) {
|
||||||
|
return new PipTransition(context, pipBoundsState, pipTransitionState, pipMenuController,
|
||||||
pipBoundsAlgorithm, pipAnimationController, transitions, shellTaskOrganizer);
|
pipBoundsAlgorithm, pipAnimationController, transitions, shellTaskOrganizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user