Merge "Implement the new PiP animation (fade-in)." into qt-dev
This commit is contained in:
@@ -41,9 +41,11 @@ interface IRecentsAnimationController {
|
|||||||
* with remote animation targets should be relinquished. If {@param moveHomeToTop} is true, then
|
* with remote animation targets should be relinquished. If {@param moveHomeToTop} is true, then
|
||||||
* the home activity should be moved to the top. Otherwise, the home activity is hidden and the
|
* the home activity should be moved to the top. Otherwise, the home activity is hidden and the
|
||||||
* user is returned to the app.
|
* user is returned to the app.
|
||||||
|
* @param sendUserLeaveHint If set to true, {@link Activity#onUserLeaving} will be sent to the
|
||||||
|
* top resumed app, false otherwise.
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
void finish(boolean moveHomeToTop);
|
void finish(boolean moveHomeToTop, boolean sendUserLeaveHint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the handler to indicate that the recents animation input consumer should be
|
* Called by the handler to indicate that the recents animation input consumer should be
|
||||||
|
|||||||
@@ -77,9 +77,15 @@ public class RecentsAnimationControllerCompat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finish(boolean toHome) {
|
/**
|
||||||
|
* Finish the current recents animation.
|
||||||
|
* @param toHome Going to home or back to the previous app.
|
||||||
|
* @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous
|
||||||
|
* app.
|
||||||
|
*/
|
||||||
|
public void finish(boolean toHome, boolean sendUserLeaveHint) {
|
||||||
try {
|
try {
|
||||||
mAnimationController.finish(toHome);
|
mAnimationController.finish(toHome, sendUserLeaveHint);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Failed to finish recents animation", e);
|
Log.e(TAG, "Failed to finish recents animation", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,13 @@ public class BoundsAnimationController {
|
|||||||
/** Schedule a PiP mode changed callback when this animation ends. */
|
/** Schedule a PiP mode changed callback when this animation ends. */
|
||||||
public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2;
|
public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2;
|
||||||
|
|
||||||
|
public static final int BOUNDS = 0;
|
||||||
|
public static final int FADE_IN = 1;
|
||||||
|
|
||||||
|
@IntDef({BOUNDS, FADE_IN}) public @interface AnimationType {}
|
||||||
|
|
||||||
|
private static final int FADE_IN_DURATION = 500;
|
||||||
|
|
||||||
// Only accessed on UI thread.
|
// Only accessed on UI thread.
|
||||||
private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
|
private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
|
||||||
|
|
||||||
@@ -115,6 +122,7 @@ public class BoundsAnimationController {
|
|||||||
private boolean mFinishAnimationAfterTransition = false;
|
private boolean mFinishAnimationAfterTransition = false;
|
||||||
private final AnimationHandler mAnimationHandler;
|
private final AnimationHandler mAnimationHandler;
|
||||||
private Choreographer mChoreographer;
|
private Choreographer mChoreographer;
|
||||||
|
private @AnimationType int mAnimationType;
|
||||||
|
|
||||||
private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
|
private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
|
||||||
|
|
||||||
@@ -140,6 +148,7 @@ public class BoundsAnimationController {
|
|||||||
implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
|
implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
|
||||||
|
|
||||||
private final BoundsAnimationTarget mTarget;
|
private final BoundsAnimationTarget mTarget;
|
||||||
|
private final @AnimationType int mAnimationType;
|
||||||
private final Rect mFrom = new Rect();
|
private final Rect mFrom = new Rect();
|
||||||
private final Rect mTo = new Rect();
|
private final Rect mTo = new Rect();
|
||||||
private final Rect mTmpRect = new Rect();
|
private final Rect mTmpRect = new Rect();
|
||||||
@@ -166,8 +175,8 @@ public class BoundsAnimationController {
|
|||||||
|
|
||||||
// Depending on whether we are animating from
|
// Depending on whether we are animating from
|
||||||
// a smaller to a larger size
|
// a smaller to a larger size
|
||||||
private final int mFrozenTaskWidth;
|
private int mFrozenTaskWidth;
|
||||||
private final int mFrozenTaskHeight;
|
private int mFrozenTaskHeight;
|
||||||
|
|
||||||
// Timeout callback to ensure we continue the animation if waiting for resuming or app
|
// Timeout callback to ensure we continue the animation if waiting for resuming or app
|
||||||
// windows drawn fails
|
// windows drawn fails
|
||||||
@@ -176,12 +185,13 @@ public class BoundsAnimationController {
|
|||||||
resume();
|
resume();
|
||||||
};
|
};
|
||||||
|
|
||||||
BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to,
|
BoundsAnimator(BoundsAnimationTarget target, @AnimationType int animationType, Rect from,
|
||||||
@SchedulePipModeChangedState int schedulePipModeChangedState,
|
Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState,
|
||||||
@SchedulePipModeChangedState int prevShedulePipModeChangedState,
|
@SchedulePipModeChangedState int prevShedulePipModeChangedState,
|
||||||
boolean moveFromFullscreen, boolean moveToFullscreen, Rect frozenTask) {
|
boolean moveFromFullscreen, boolean moveToFullscreen, Rect frozenTask) {
|
||||||
super();
|
super();
|
||||||
mTarget = target;
|
mTarget = target;
|
||||||
|
mAnimationType = animationType;
|
||||||
mFrom.set(from);
|
mFrom.set(from);
|
||||||
mTo.set(to);
|
mTo.set(to);
|
||||||
mSchedulePipModeChangedState = schedulePipModeChangedState;
|
mSchedulePipModeChangedState = schedulePipModeChangedState;
|
||||||
@@ -195,12 +205,14 @@ public class BoundsAnimationController {
|
|||||||
// to their final size immediately so we can use scaling to make the window
|
// to their final size immediately so we can use scaling to make the window
|
||||||
// larger. Likewise if we are going from bigger to smaller, we want to wait until
|
// larger. Likewise if we are going from bigger to smaller, we want to wait until
|
||||||
// the end so we don't have to upscale from the smaller finished size.
|
// the end so we don't have to upscale from the smaller finished size.
|
||||||
if (animatingToLargerSize()) {
|
if (mAnimationType == BOUNDS) {
|
||||||
mFrozenTaskWidth = mTo.width();
|
if (animatingToLargerSize()) {
|
||||||
mFrozenTaskHeight = mTo.height();
|
mFrozenTaskWidth = mTo.width();
|
||||||
} else {
|
mFrozenTaskHeight = mTo.height();
|
||||||
mFrozenTaskWidth = frozenTask.isEmpty() ? mFrom.width() : frozenTask.width();
|
} else {
|
||||||
mFrozenTaskHeight = frozenTask.isEmpty() ? mFrom.height() : frozenTask.height();
|
mFrozenTaskWidth = frozenTask.isEmpty() ? mFrom.width() : frozenTask.width();
|
||||||
|
mFrozenTaskHeight = frozenTask.isEmpty() ? mFrom.height() : frozenTask.height();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,8 +234,9 @@ public class BoundsAnimationController {
|
|||||||
// otherwise.
|
// otherwise.
|
||||||
boolean continueAnimation;
|
boolean continueAnimation;
|
||||||
if (mPrevSchedulePipModeChangedState == NO_PIP_MODE_CHANGED_CALLBACKS) {
|
if (mPrevSchedulePipModeChangedState == NO_PIP_MODE_CHANGED_CALLBACKS) {
|
||||||
continueAnimation = mTarget.onAnimationStart(mSchedulePipModeChangedState ==
|
continueAnimation = mTarget.onAnimationStart(
|
||||||
SCHEDULE_PIP_MODE_CHANGED_ON_START, false /* forceUpdate */);
|
mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START,
|
||||||
|
false /* forceUpdate */, mAnimationType);
|
||||||
|
|
||||||
// When starting an animation from fullscreen, pause here and wait for the
|
// When starting an animation from fullscreen, pause here and wait for the
|
||||||
// windows-drawn signal before we start the rest of the transition down into PiP.
|
// windows-drawn signal before we start the rest of the transition down into PiP.
|
||||||
@@ -238,7 +251,8 @@ public class BoundsAnimationController {
|
|||||||
// However, we still need to report to them that they are leaving PiP, so this will
|
// However, we still need to report to them that they are leaving PiP, so this will
|
||||||
// force an update via a mode changed callback.
|
// force an update via a mode changed callback.
|
||||||
continueAnimation = mTarget.onAnimationStart(
|
continueAnimation = mTarget.onAnimationStart(
|
||||||
true /* schedulePipModeChangedCallback */, true /* forceUpdate */);
|
true /* schedulePipModeChangedCallback */, true /* forceUpdate */,
|
||||||
|
mAnimationType);
|
||||||
} else {
|
} else {
|
||||||
// The animation is already running, but we should check that the TaskStack is still
|
// The animation is already running, but we should check that the TaskStack is still
|
||||||
// valid before continuing with the animation
|
// valid before continuing with the animation
|
||||||
@@ -285,6 +299,13 @@ public class BoundsAnimationController {
|
|||||||
@Override
|
@Override
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
final float value = (Float) animation.getAnimatedValue();
|
final float value = (Float) animation.getAnimatedValue();
|
||||||
|
if (mAnimationType == FADE_IN) {
|
||||||
|
if (!mTarget.setPinnedStackAlpha(value)) {
|
||||||
|
cancelAndCallAnimationEnd();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final float remains = 1 - value;
|
final float remains = 1 - value;
|
||||||
mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value + 0.5f);
|
mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value + 0.5f);
|
||||||
mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f);
|
mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f);
|
||||||
@@ -408,16 +429,29 @@ public class BoundsAnimationController {
|
|||||||
|
|
||||||
public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
|
public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
|
||||||
int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
|
int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
|
||||||
boolean moveFromFullscreen, boolean moveToFullscreen) {
|
boolean moveFromFullscreen, boolean moveToFullscreen,
|
||||||
|
@AnimationType int animationType) {
|
||||||
animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState,
|
animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState,
|
||||||
moveFromFullscreen, moveToFullscreen);
|
moveFromFullscreen, moveToFullscreen, animationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to,
|
BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to,
|
||||||
int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
|
int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
|
||||||
boolean moveFromFullscreen, boolean moveToFullscreen) {
|
boolean moveFromFullscreen, boolean moveToFullscreen,
|
||||||
|
@AnimationType int animationType) {
|
||||||
final BoundsAnimator existing = mRunningAnimations.get(target);
|
final BoundsAnimator existing = mRunningAnimations.get(target);
|
||||||
|
// animateBoundsImpl gets called twice for each animation. The second time we get the final
|
||||||
|
// to rect that respects the shelf, which is when we want to resize. Our signal for fade in
|
||||||
|
// comes in from how to enter into pip, but we also need to use the to and from rect to
|
||||||
|
// decide which animation we want to run finally.
|
||||||
|
boolean shouldResize = false;
|
||||||
|
if (isRunningFadeInAnimation(target)) {
|
||||||
|
shouldResize = true;
|
||||||
|
if (from.contains(to)) {
|
||||||
|
animationType = FADE_IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
final boolean replacing = existing != null;
|
final boolean replacing = existing != null;
|
||||||
@SchedulePipModeChangedState int prevSchedulePipModeChangedState =
|
@SchedulePipModeChangedState int prevSchedulePipModeChangedState =
|
||||||
NO_PIP_MODE_CHANGED_CALLBACKS;
|
NO_PIP_MODE_CHANGED_CALLBACKS;
|
||||||
@@ -477,18 +511,34 @@ public class BoundsAnimationController {
|
|||||||
// Since we are replacing, we skip both animation start and end callbacks
|
// Since we are replacing, we skip both animation start and end callbacks
|
||||||
existing.cancel();
|
existing.cancel();
|
||||||
}
|
}
|
||||||
final BoundsAnimator animator = new BoundsAnimator(target, from, to,
|
if (shouldResize) {
|
||||||
|
target.setPinnedStackSize(to, null);
|
||||||
|
}
|
||||||
|
final BoundsAnimator animator = new BoundsAnimator(target, animationType, from, to,
|
||||||
schedulePipModeChangedState, prevSchedulePipModeChangedState,
|
schedulePipModeChangedState, prevSchedulePipModeChangedState,
|
||||||
moveFromFullscreen, moveToFullscreen, frozenTask);
|
moveFromFullscreen, moveToFullscreen, frozenTask);
|
||||||
mRunningAnimations.put(target, animator);
|
mRunningAnimations.put(target, animator);
|
||||||
animator.setFloatValues(0f, 1f);
|
animator.setFloatValues(0f, 1f);
|
||||||
animator.setDuration((animationDuration != -1 ? animationDuration
|
animator.setDuration(animationType == FADE_IN ? FADE_IN_DURATION
|
||||||
: DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
|
: (animationDuration != -1 ? animationDuration : DEFAULT_TRANSITION_DURATION)
|
||||||
|
* DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
|
||||||
animator.setInterpolator(mFastOutSlowInInterpolator);
|
animator.setInterpolator(mFastOutSlowInInterpolator);
|
||||||
animator.start();
|
animator.start();
|
||||||
return animator;
|
return animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAnimationType(@AnimationType int animationType) {
|
||||||
|
mAnimationType = animationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** return the current animation type. */
|
||||||
|
public @AnimationType int getAnimationType() {
|
||||||
|
@AnimationType int animationType = mAnimationType;
|
||||||
|
// Default to BOUNDS.
|
||||||
|
mAnimationType = BOUNDS;
|
||||||
|
return animationType;
|
||||||
|
}
|
||||||
|
|
||||||
public Handler getHandler() {
|
public Handler getHandler() {
|
||||||
return mHandler;
|
return mHandler;
|
||||||
}
|
}
|
||||||
@@ -498,6 +548,11 @@ public class BoundsAnimationController {
|
|||||||
mHandler.post(this::resume);
|
mHandler.post(this::resume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRunningFadeInAnimation(final BoundsAnimationTarget target) {
|
||||||
|
final BoundsAnimator existing = mRunningAnimations.get(target);
|
||||||
|
return existing != null && existing.mAnimationType == FADE_IN && existing.isStarted();
|
||||||
|
}
|
||||||
|
|
||||||
private void resume() {
|
private void resume() {
|
||||||
for (int i = 0; i < mRunningAnimations.size(); i++) {
|
for (int i = 0; i < mRunningAnimations.size(); i++) {
|
||||||
final BoundsAnimator b = mRunningAnimations.valueAt(i);
|
final BoundsAnimator b = mRunningAnimations.valueAt(i);
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ interface BoundsAnimationTarget {
|
|||||||
* callbacks
|
* callbacks
|
||||||
* @return whether to continue the animation
|
* @return whether to continue the animation
|
||||||
*/
|
*/
|
||||||
boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate);
|
boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate,
|
||||||
|
@BoundsAnimationController.AnimationType int animationType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether the animation should be paused waiting for the windows to draw before
|
* @return Whether the animation should be paused waiting for the windows to draw before
|
||||||
@@ -53,6 +54,9 @@ interface BoundsAnimationTarget {
|
|||||||
*/
|
*/
|
||||||
boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds);
|
boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds);
|
||||||
|
|
||||||
|
/** Sets the alpha of the animation target */
|
||||||
|
boolean setPinnedStackAlpha(float alpha);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for the target to inform it that the animation has ended, so it can do some
|
* Callback for the target to inform it that the animation has ended, so it can do some
|
||||||
* necessary cleanup.
|
* necessary cleanup.
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
|||||||
import static android.view.WindowManager.TRANSIT_NONE;
|
import static android.view.WindowManager.TRANSIT_NONE;
|
||||||
|
|
||||||
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.BOUNDS;
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
|
||||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
||||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
|
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
|
||||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
|
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
|
||||||
@@ -201,7 +203,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
|
private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode,
|
||||||
|
boolean sendUserLeaveHint) {
|
||||||
synchronized (mService.mGlobalLock) {
|
synchronized (mService.mGlobalLock) {
|
||||||
if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
|
if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
|
||||||
+ mWindowManager.getRecentsAnimationController()
|
+ mWindowManager.getRecentsAnimationController()
|
||||||
@@ -246,7 +249,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
|
|||||||
if (reorderMode == REORDER_MOVE_TO_TOP) {
|
if (reorderMode == REORDER_MOVE_TO_TOP) {
|
||||||
// Bring the target stack to the front
|
// Bring the target stack to the front
|
||||||
mStackSupervisor.mNoAnimActivities.add(targetActivity);
|
mStackSupervisor.mNoAnimActivities.add(targetActivity);
|
||||||
targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
|
|
||||||
|
if (sendUserLeaveHint) {
|
||||||
|
// Setting this allows the previous app to PiP.
|
||||||
|
mStackSupervisor.mUserLeaving = true;
|
||||||
|
targetStack.moveTaskToFrontLocked(targetActivity.getTaskRecord(),
|
||||||
|
true /* noAnimation */, null /* activityOptions */,
|
||||||
|
targetActivity.appTimeTracker,
|
||||||
|
"RecentsAnimation.onAnimationFinished()");
|
||||||
|
} else {
|
||||||
|
targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
final ActivityStack topStack = getTopNonAlwaysOnTopStack();
|
final ActivityStack topStack = getTopNonAlwaysOnTopStack();
|
||||||
if (topStack != targetStack) {
|
if (topStack != targetStack) {
|
||||||
@@ -300,11 +314,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
|
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
|
||||||
boolean runSychronously) {
|
boolean runSychronously, boolean sendUserLeaveHint) {
|
||||||
if (runSychronously) {
|
if (runSychronously) {
|
||||||
finishAnimation(reorderMode);
|
finishAnimation(reorderMode, sendUserLeaveHint);
|
||||||
} else {
|
} else {
|
||||||
mService.mH.post(() -> finishAnimation(reorderMode));
|
mService.mH.post(() -> finishAnimation(reorderMode, sendUserLeaveHint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,6 +331,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
|
|||||||
}
|
}
|
||||||
final RecentsAnimationController controller =
|
final RecentsAnimationController controller =
|
||||||
mWindowManager.getRecentsAnimationController();
|
mWindowManager.getRecentsAnimationController();
|
||||||
|
final DisplayContent dc =
|
||||||
|
mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
|
||||||
|
dc.mBoundsAnimationController.setAnimationType(
|
||||||
|
controller.shouldCancelWithDeferredScreenshot() ? FADE_IN : BOUNDS);
|
||||||
|
|
||||||
// Cancel running recents animation and screenshot previous task when the next
|
// Cancel running recents animation and screenshot previous task when the next
|
||||||
// transition starts in below cases:
|
// transition starts in below cases:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
|||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||||
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
|
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
|
||||||
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
|
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
|
||||||
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
|
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
|
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
|
||||||
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
|
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
|
||||||
@@ -142,7 +143,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public interface RecentsAnimationCallbacks {
|
public interface RecentsAnimationCallbacks {
|
||||||
void onAnimationFinished(@ReorderMode int reorderMode, boolean runSychronously);
|
/** Callback when recents animation is finished. */
|
||||||
|
void onAnimationFinished(@ReorderMode int reorderMode, boolean runSychronously,
|
||||||
|
boolean sendUserLeaveHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IRecentsAnimationController mController =
|
private final IRecentsAnimationController mController =
|
||||||
@@ -179,7 +182,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish(boolean moveHomeToTop) {
|
public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) {
|
||||||
if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):"
|
if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):"
|
||||||
+ " mCanceled=" + mCanceled);
|
+ " mCanceled=" + mCanceled);
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
@@ -195,7 +198,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
mCallbacks.onAnimationFinished(moveHomeToTop
|
mCallbacks.onAnimationFinished(moveHomeToTop
|
||||||
? REORDER_MOVE_TO_TOP
|
? REORDER_MOVE_TO_TOP
|
||||||
: REORDER_MOVE_TO_ORIGINAL_POSITION,
|
: REORDER_MOVE_TO_ORIGINAL_POSITION,
|
||||||
true /* runSynchronously */);
|
true /* runSynchronously */, sendUserLeaveHint);
|
||||||
|
final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
|
||||||
|
dc.mBoundsAnimationController.setAnimationType(FADE_IN);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(token);
|
Binder.restoreCallingIdentity(token);
|
||||||
}
|
}
|
||||||
@@ -497,7 +502,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
Slog.e(TAG, "Failed to cancel recents animation", e);
|
Slog.e(TAG, "Failed to cancel recents animation", e);
|
||||||
}
|
}
|
||||||
// Clean up and return to the previous app
|
// Clean up and return to the previous app
|
||||||
mCallbacks.onAnimationFinished(reorderMode, runSynchronously);
|
mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
|
||||||
|
false /* sendUserLeaveHint */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +548,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
if (DEBUG_RECENTS_ANIMATIONS) {
|
if (DEBUG_RECENTS_ANIMATIONS) {
|
||||||
Slog.d(TAG, "mRecentScreenshotAnimator finish");
|
Slog.d(TAG, "mRecentScreenshotAnimator finish");
|
||||||
}
|
}
|
||||||
mCallbacks.onAnimationFinished(reorderMode, runSynchronously);
|
mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
|
||||||
|
false /* sendUserLeaveHint */);
|
||||||
}, mService);
|
}, mService);
|
||||||
mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator);
|
mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import static android.view.WindowManager.DOCKED_LEFT;
|
|||||||
import static android.view.WindowManager.DOCKED_RIGHT;
|
import static android.view.WindowManager.DOCKED_RIGHT;
|
||||||
import static android.view.WindowManager.DOCKED_TOP;
|
import static android.view.WindowManager.DOCKED_TOP;
|
||||||
|
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
|
||||||
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
|
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
|
||||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
|
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
|
||||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
||||||
@@ -148,6 +149,7 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
private boolean mCancelCurrentBoundsAnimation = false;
|
private boolean mCancelCurrentBoundsAnimation = false;
|
||||||
private Rect mBoundsAnimationTarget = new Rect();
|
private Rect mBoundsAnimationTarget = new Rect();
|
||||||
private Rect mBoundsAnimationSourceHintBounds = new Rect();
|
private Rect mBoundsAnimationSourceHintBounds = new Rect();
|
||||||
|
private @BoundsAnimationController.AnimationType int mAnimationType;
|
||||||
|
|
||||||
Rect mPreAnimationBounds = new Rect();
|
Rect mPreAnimationBounds = new Rect();
|
||||||
|
|
||||||
@@ -1572,7 +1574,8 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override // AnimatesBounds
|
@Override // AnimatesBounds
|
||||||
public boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate) {
|
public boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate,
|
||||||
|
@BoundsAnimationController.AnimationType int animationType) {
|
||||||
// Hold the lock since this is called from the BoundsAnimator running on the UiThread
|
// Hold the lock since this is called from the BoundsAnimator running on the UiThread
|
||||||
synchronized (mWmService.mGlobalLock) {
|
synchronized (mWmService.mGlobalLock) {
|
||||||
if (!isAttached()) {
|
if (!isAttached()) {
|
||||||
@@ -1583,6 +1586,7 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
mBoundsAnimatingRequested = false;
|
mBoundsAnimatingRequested = false;
|
||||||
mBoundsAnimating = true;
|
mBoundsAnimating = true;
|
||||||
mCancelCurrentBoundsAnimation = false;
|
mCancelCurrentBoundsAnimation = false;
|
||||||
|
mAnimationType = animationType;
|
||||||
|
|
||||||
// If we are changing UI mode, as in the PiP to fullscreen
|
// If we are changing UI mode, as in the PiP to fullscreen
|
||||||
// transition, then we need to wait for the window to draw.
|
// transition, then we need to wait for the window to draw.
|
||||||
@@ -1599,7 +1603,8 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
// I don't believe you...
|
// I don't believe you...
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schedulePipModeChangedCallback && mActivityStack != null) {
|
if ((schedulePipModeChangedCallback || animationType == FADE_IN)
|
||||||
|
&& mActivityStack != null) {
|
||||||
// We need to schedule the PiP mode change before the animation up. It is possible
|
// We need to schedule the PiP mode change before the animation up. It is possible
|
||||||
// in this case for the animation down to not have been completed, so always
|
// in this case for the animation down to not have been completed, so always
|
||||||
// force-schedule and update to the client to ensure that it is notified that it
|
// force-schedule and update to the client to ensure that it is notified that it
|
||||||
@@ -1614,6 +1619,21 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
@Override // AnimatesBounds
|
@Override // AnimatesBounds
|
||||||
public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
|
public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
|
||||||
boolean moveToFullscreen) {
|
boolean moveToFullscreen) {
|
||||||
|
if (mAnimationType == BoundsAnimationController.FADE_IN) {
|
||||||
|
setPinnedStackAlpha(1f);
|
||||||
|
try {
|
||||||
|
mWmService.mActivityTaskManager.notifyPinnedStackAnimationEnded();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// I don't believe you...
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onBoundAnimationEnd(schedulePipModeChangedCallback, finalStackSize, moveToFullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onBoundAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
|
||||||
|
boolean moveToFullscreen) {
|
||||||
if (inPinnedWindowingMode()) {
|
if (inPinnedWindowingMode()) {
|
||||||
// Update to the final bounds if requested. This is done here instead of in the bounds
|
// Update to the final bounds if requested. This is done here instead of in the bounds
|
||||||
// animator to allow us to coordinate this after we notify the PiP mode changed
|
// animator to allow us to coordinate this after we notify the PiP mode changed
|
||||||
@@ -1725,10 +1745,23 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
|
final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
|
||||||
schedulePipModeChangedState;
|
schedulePipModeChangedState;
|
||||||
final DisplayContent displayContent = getDisplayContent();
|
final DisplayContent displayContent = getDisplayContent();
|
||||||
|
@BoundsAnimationController.AnimationType int intendedAnimationType =
|
||||||
|
displayContent.mBoundsAnimationController.getAnimationType();
|
||||||
|
if (intendedAnimationType == FADE_IN) {
|
||||||
|
if (fromFullscreen) {
|
||||||
|
setPinnedStackAlpha(0f);
|
||||||
|
}
|
||||||
|
if (toBounds.width() == fromBounds.width()
|
||||||
|
&& toBounds.height() == fromBounds.height()) {
|
||||||
|
intendedAnimationType = BoundsAnimationController.BOUNDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final @BoundsAnimationController.AnimationType int animationType = intendedAnimationType;
|
||||||
displayContent.mBoundsAnimationController.getHandler().post(() -> {
|
displayContent.mBoundsAnimationController.getHandler().post(() -> {
|
||||||
displayContent.mBoundsAnimationController.animateBounds(this, fromBounds,
|
displayContent.mBoundsAnimationController.animateBounds(this, fromBounds,
|
||||||
finalToBounds, animationDuration, finalSchedulePipModeChangedState,
|
finalToBounds, animationDuration, finalSchedulePipModeChangedState,
|
||||||
fromFullscreen, toFullscreen);
|
fromFullscreen, toFullscreen, animationType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1905,6 +1938,20 @@ public class TaskStack extends WindowContainer<Task> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setPinnedStackAlpha(float alpha) {
|
||||||
|
// Hold the lock since this is called from the BoundsAnimator running on the UiThread
|
||||||
|
synchronized (mWmService.mGlobalLock) {
|
||||||
|
if (mCancelCurrentBoundsAnimation) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
getPendingTransaction().setAlpha(getSurfaceControl(), alpha);
|
||||||
|
scheduleAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public DisplayInfo getDisplayInfo() {
|
public DisplayInfo getDisplayInfo() {
|
||||||
return mDisplayContent.getDisplayInfo();
|
return mDisplayContent.getDisplayInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.server.wm;
|
|||||||
|
|
||||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||||
|
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.BOUNDS;
|
||||||
|
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
|
||||||
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
|
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
|
||||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
|
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
|
||||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
||||||
@@ -131,6 +133,8 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
boolean mCancelRequested;
|
boolean mCancelRequested;
|
||||||
Rect mStackBounds;
|
Rect mStackBounds;
|
||||||
Rect mTaskBounds;
|
Rect mTaskBounds;
|
||||||
|
float mAlpha;
|
||||||
|
@BoundsAnimationController.AnimationType int mAnimationType;
|
||||||
|
|
||||||
void initialize(Rect from) {
|
void initialize(Rect from) {
|
||||||
mAwaitingAnimationStart = true;
|
mAwaitingAnimationStart = true;
|
||||||
@@ -148,11 +152,12 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAnimationStart(boolean schedulePipModeChangedCallback,
|
public boolean onAnimationStart(boolean schedulePipModeChangedCallback,
|
||||||
boolean forceUpdate) {
|
boolean forceUpdate, @BoundsAnimationController.AnimationType int animationType) {
|
||||||
mAwaitingAnimationStart = false;
|
mAwaitingAnimationStart = false;
|
||||||
mAnimationStarted = true;
|
mAnimationStarted = true;
|
||||||
mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
|
mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
|
||||||
mForcePipModeChangedCallback = forceUpdate;
|
mForcePipModeChangedCallback = forceUpdate;
|
||||||
|
mAnimationType = animationType;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +190,12 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
mMovedToFullscreen = moveToFullscreen;
|
mMovedToFullscreen = moveToFullscreen;
|
||||||
mTaskBounds = null;
|
mTaskBounds = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setPinnedStackAlpha(float alpha) {
|
||||||
|
mAlpha = alpha;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,6 +212,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
private Rect mTo;
|
private Rect mTo;
|
||||||
private Rect mLargerBounds;
|
private Rect mLargerBounds;
|
||||||
private Rect mExpectedFinalBounds;
|
private Rect mExpectedFinalBounds;
|
||||||
|
private @BoundsAnimationController.AnimationType int mAnimationType;
|
||||||
|
|
||||||
BoundsAnimationDriver(BoundsAnimationController controller,
|
BoundsAnimationDriver(BoundsAnimationController controller,
|
||||||
TestBoundsAnimationTarget target, MockValueAnimator mockValueAnimator) {
|
TestBoundsAnimationTarget target, MockValueAnimator mockValueAnimator) {
|
||||||
@@ -209,7 +221,8 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
mMockAnimator = mockValueAnimator;
|
mMockAnimator = mockValueAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundsAnimationDriver start(Rect from, Rect to) {
|
BoundsAnimationDriver start(Rect from, Rect to,
|
||||||
|
@BoundsAnimationController.AnimationType int animationType) {
|
||||||
if (mAnimator != null) {
|
if (mAnimator != null) {
|
||||||
throw new IllegalArgumentException("Call restart() to restart an animation");
|
throw new IllegalArgumentException("Call restart() to restart an animation");
|
||||||
}
|
}
|
||||||
@@ -223,7 +236,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
assertTrue(mTarget.mAwaitingAnimationStart);
|
assertTrue(mTarget.mAwaitingAnimationStart);
|
||||||
assertFalse(mTarget.mAnimationStarted);
|
assertFalse(mTarget.mAnimationStarted);
|
||||||
|
|
||||||
startImpl(from, to);
|
startImpl(from, to, animationType);
|
||||||
|
|
||||||
// Ensure that the animator is paused for the all windows drawn signal when animating
|
// Ensure that the animator is paused for the all windows drawn signal when animating
|
||||||
// to/from fullscreen
|
// to/from fullscreen
|
||||||
@@ -253,7 +266,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
mTarget.mAnimationStarted = false;
|
mTarget.mAnimationStarted = false;
|
||||||
|
|
||||||
// Start animation
|
// Start animation
|
||||||
startImpl(mTarget.mStackBounds, to);
|
startImpl(mTarget.mStackBounds, to, BOUNDS);
|
||||||
|
|
||||||
if (toSameBounds) {
|
if (toSameBounds) {
|
||||||
// Same animator if same final bounds
|
// Same animator if same final bounds
|
||||||
@@ -273,13 +286,15 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundsAnimationDriver startImpl(Rect from, Rect to) {
|
private BoundsAnimationDriver startImpl(Rect from, Rect to,
|
||||||
|
@BoundsAnimationController.AnimationType int animationType) {
|
||||||
boolean fromFullscreen = from.equals(BOUNDS_FULL);
|
boolean fromFullscreen = from.equals(BOUNDS_FULL);
|
||||||
boolean toFullscreen = to.equals(BOUNDS_FULL);
|
boolean toFullscreen = to.equals(BOUNDS_FULL);
|
||||||
mFrom = new Rect(from);
|
mFrom = new Rect(from);
|
||||||
mTo = new Rect(to);
|
mTo = new Rect(to);
|
||||||
mExpectedFinalBounds = new Rect(to);
|
mExpectedFinalBounds = new Rect(to);
|
||||||
mLargerBounds = getLargerBounds(mFrom, mTo);
|
mLargerBounds = getLargerBounds(mFrom, mTo);
|
||||||
|
mAnimationType = animationType;
|
||||||
|
|
||||||
// Start animation
|
// Start animation
|
||||||
final @SchedulePipModeChangedState int schedulePipModeChangedState = toFullscreen
|
final @SchedulePipModeChangedState int schedulePipModeChangedState = toFullscreen
|
||||||
@@ -288,17 +303,19 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
? SCHEDULE_PIP_MODE_CHANGED_ON_END
|
? SCHEDULE_PIP_MODE_CHANGED_ON_END
|
||||||
: NO_PIP_MODE_CHANGED_CALLBACKS;
|
: NO_PIP_MODE_CHANGED_CALLBACKS;
|
||||||
mAnimator = mController.animateBoundsImpl(mTarget, from, to, DURATION,
|
mAnimator = mController.animateBoundsImpl(mTarget, from, to, DURATION,
|
||||||
schedulePipModeChangedState, fromFullscreen, toFullscreen);
|
schedulePipModeChangedState, fromFullscreen, toFullscreen, animationType);
|
||||||
|
|
||||||
// Original stack bounds, frozen task bounds
|
if (animationType == BOUNDS) {
|
||||||
assertEquals(mFrom, mTarget.mStackBounds);
|
// Original stack bounds, frozen task bounds
|
||||||
assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
|
assertEquals(mFrom, mTarget.mStackBounds);
|
||||||
|
assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
|
||||||
|
|
||||||
// Animating to larger size
|
// Animating to larger size
|
||||||
if (mFrom.equals(mLargerBounds)) {
|
if (mFrom.equals(mLargerBounds)) {
|
||||||
assertFalse(mAnimator.animatingToLargerSize());
|
assertFalse(mAnimator.animatingToLargerSize());
|
||||||
} else if (mTo.equals(mLargerBounds)) {
|
} else if (mTo.equals(mLargerBounds)) {
|
||||||
assertTrue(mAnimator.animatingToLargerSize());
|
assertTrue(mAnimator.animatingToLargerSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -315,16 +332,20 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
BoundsAnimationDriver update(float t) {
|
BoundsAnimationDriver update(float t) {
|
||||||
mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(t));
|
mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(t));
|
||||||
|
|
||||||
// Temporary stack bounds, frozen task bounds
|
if (mAnimationType == BOUNDS) {
|
||||||
if (t == 0f) {
|
// Temporary stack bounds, frozen task bounds
|
||||||
assertEquals(mFrom, mTarget.mStackBounds);
|
if (t == 0f) {
|
||||||
} else if (t == 1f) {
|
assertEquals(mFrom, mTarget.mStackBounds);
|
||||||
assertEquals(mTo, mTarget.mStackBounds);
|
} else if (t == 1f) {
|
||||||
|
assertEquals(mTo, mTarget.mStackBounds);
|
||||||
|
} else {
|
||||||
|
assertNotEquals(mFrom, mTarget.mStackBounds);
|
||||||
|
assertNotEquals(mTo, mTarget.mStackBounds);
|
||||||
|
}
|
||||||
|
assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
|
||||||
} else {
|
} else {
|
||||||
assertNotEquals(mFrom, mTarget.mStackBounds);
|
assertEquals((float) mMockAnimator.getAnimatedValue(), mTarget.mAlpha, 0.01f);
|
||||||
assertNotEquals(mTo, mTarget.mStackBounds);
|
|
||||||
}
|
}
|
||||||
assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,10 +374,14 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
BoundsAnimationDriver end() {
|
BoundsAnimationDriver end() {
|
||||||
mAnimator.end();
|
mAnimator.end();
|
||||||
|
|
||||||
// Final stack bounds
|
if (mAnimationType == BOUNDS) {
|
||||||
assertEquals(mTo, mTarget.mStackBounds);
|
// Final stack bounds
|
||||||
assertEquals(mExpectedFinalBounds, mTarget.mAnimationEndFinalStackBounds);
|
assertEquals(mTo, mTarget.mStackBounds);
|
||||||
assertNull(mTarget.mTaskBounds);
|
assertEquals(mExpectedFinalBounds, mTarget.mAnimationEndFinalStackBounds);
|
||||||
|
assertNull(mTarget.mTaskBounds);
|
||||||
|
} else {
|
||||||
|
assertEquals(mTarget.mAlpha, 1f, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -413,7 +438,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFullscreenToFloatingTransition() {
|
public void testFullscreenToFloatingTransition() {
|
||||||
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0f)
|
.update(0f)
|
||||||
.update(0.5f)
|
.update(0.5f)
|
||||||
@@ -425,7 +450,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToFullscreenTransition() {
|
public void testFloatingToFullscreenTransition() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL, BOUNDS)
|
||||||
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0f)
|
.update(0f)
|
||||||
.update(0.5f)
|
.update(0.5f)
|
||||||
@@ -437,7 +462,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToSmallerFloatingTransition() {
|
public void testFloatingToSmallerFloatingTransition() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0f)
|
.update(0f)
|
||||||
.update(0.5f)
|
.update(0.5f)
|
||||||
@@ -449,7 +474,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToLargerFloatingTransition() {
|
public void testFloatingToLargerFloatingTransition() {
|
||||||
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0f)
|
.update(0f)
|
||||||
.update(0.5f)
|
.update(0.5f)
|
||||||
@@ -463,7 +488,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFullscreenToFloatingCancelFromTarget() {
|
public void testFullscreenToFloatingCancelFromTarget() {
|
||||||
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.cancel()
|
.cancel()
|
||||||
@@ -473,7 +498,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFullscreenToFloatingCancelFromAnimationToSameBounds() {
|
public void testFullscreenToFloatingCancelFromAnimationToSameBounds() {
|
||||||
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.restart(BOUNDS_FLOATING, false /* expectStartedAndPipModeChangedCallback */)
|
.restart(BOUNDS_FLOATING, false /* expectStartedAndPipModeChangedCallback */)
|
||||||
@@ -484,7 +509,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() {
|
public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() {
|
||||||
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.restart(BOUNDS_SMALLER_FLOATING,
|
.restart(BOUNDS_SMALLER_FLOATING,
|
||||||
@@ -498,7 +523,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() {
|
public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() {
|
||||||
// When animating from fullscreen and the animation is interruped, we expect the animation
|
// When animating from fullscreen and the animation is interruped, we expect the animation
|
||||||
// start callback to be made, with a forced pip mode change callback
|
// start callback to be made, with a forced pip mode change callback
|
||||||
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.restart(BOUNDS_FULL, true /* expectStartedAndPipModeChangedCallback */)
|
.restart(BOUNDS_FULL, true /* expectStartedAndPipModeChangedCallback */)
|
||||||
@@ -511,7 +536,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToFullscreenCancelFromTarget() {
|
public void testFloatingToFullscreenCancelFromTarget() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL, BOUNDS)
|
||||||
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.cancel()
|
.cancel()
|
||||||
@@ -521,7 +546,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToFullscreenCancelFromAnimationToSameBounds() {
|
public void testFloatingToFullscreenCancelFromAnimationToSameBounds() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL, BOUNDS)
|
||||||
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.restart(BOUNDS_FULL, false /* expectStartedAndPipModeChangedCallback */)
|
.restart(BOUNDS_FULL, false /* expectStartedAndPipModeChangedCallback */)
|
||||||
@@ -532,7 +557,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() {
|
public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL, BOUNDS)
|
||||||
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.restart(BOUNDS_SMALLER_FLOATING,
|
.restart(BOUNDS_SMALLER_FLOATING,
|
||||||
@@ -546,7 +571,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToSmallerFloatingCancelFromTarget() {
|
public void testFloatingToSmallerFloatingCancelFromTarget() {
|
||||||
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
|
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.cancel()
|
.cancel()
|
||||||
@@ -556,13 +581,25 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@Test
|
@Test
|
||||||
public void testFloatingToLargerFloatingCancelFromTarget() {
|
public void testFloatingToLargerFloatingCancelFromTarget() {
|
||||||
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
|
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING, BOUNDS)
|
||||||
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.cancel()
|
.cancel()
|
||||||
.expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
|
.expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThreadTest
|
||||||
|
@Test
|
||||||
|
public void testFadeIn() {
|
||||||
|
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING, FADE_IN)
|
||||||
|
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
|
||||||
|
.update(0f)
|
||||||
|
.update(0.5f)
|
||||||
|
.update(1f)
|
||||||
|
.end()
|
||||||
|
.expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
/** MISC **/
|
/** MISC **/
|
||||||
|
|
||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@@ -570,7 +607,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
public void testBoundsAreCopied() {
|
public void testBoundsAreCopied() {
|
||||||
Rect from = new Rect(0, 0, 100, 100);
|
Rect from = new Rect(0, 0, 100, 100);
|
||||||
Rect to = new Rect(25, 25, 75, 75);
|
Rect to = new Rect(25, 25, 75, 75);
|
||||||
mDriver.start(from, to)
|
mDriver.start(from, to, BOUNDS)
|
||||||
.update(0.25f)
|
.update(0.25f)
|
||||||
.end();
|
.end();
|
||||||
assertEquals(new Rect(0, 0, 100, 100), from);
|
assertEquals(new Rect(0, 0, 100, 100), from);
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
// Assume IRecentsAnimationController#cleanupScreenshot called to finish screenshot
|
// Assume IRecentsAnimationController#cleanupScreenshot called to finish screenshot
|
||||||
// animation.
|
// animation.
|
||||||
mController.mRecentScreenshotAnimator.cancelAnimation();
|
mController.mRecentScreenshotAnimator.cancelAnimation();
|
||||||
verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, true);
|
verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
|
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testCancelAnimationOnVisibleStackOrderChange() {
|
public void testCancelAnimationOnVisibleStackOrderChange() {
|
||||||
ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
|
ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
|
||||||
|
display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
|
||||||
ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
|
ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
|
||||||
ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||||
new ActivityBuilder(mService)
|
new ActivityBuilder(mService)
|
||||||
|
|||||||
Reference in New Issue
Block a user