summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Matt Sziklay <mattsziklay@google.com> 2024-04-02 21:08:51 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-04-02 21:08:51 +0000
commit2f663508f8201102d292079b0d44b683d15c4786 (patch)
tree59743f770e15eec15e93a531188a75c902b7d5f5
parentc8d77cfb4a3036d5a78434b77955e8b7a3a9193d (diff)
parentdafa45174601930e07879e7114cc2e44b0d15ed8 (diff)
Merge "Combine bounds change and move-to-center animations." into main
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt81
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt13
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt2
4 files changed, 45 insertions, 127 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index b830a41b6671..0061d03af8e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -369,67 +369,50 @@ class DragToDesktopTransitionHandler(
val startBounds = draggedTaskChange.startAbsBounds
val endBounds = draggedTaskChange.endAbsBounds
- // TODO(b/301106941): Instead of forcing-finishing the animation that scales the
- // surface down and then starting another that scales it back up to the final size,
- // blend the two animations.
- state.dragAnimator.endAnimator()
- // Using [DRAG_FREEFORM_SCALE] to calculate animated width/height is possible because
- // it is known that the animation scale is finished because the animation was
- // force-ended above. This won't be true when the two animations are blended.
- val animStartWidth = (startBounds.width() * DRAG_FREEFORM_SCALE).toInt()
- val animStartHeight = (startBounds.height() * DRAG_FREEFORM_SCALE).toInt()
- // Using end bounds here to find the left/top also assumes the center animation has
- // finished and the surface is placed exactly in the center of the screen which matches
- // the end/default bounds of the now freeform task.
- val animStartLeft = endBounds.centerX() - (animStartWidth / 2)
- val animStartTop = endBounds.centerY() - (animStartHeight / 2)
- val animStartBounds = Rect(
- animStartLeft,
- animStartTop,
- animStartLeft + animStartWidth,
- animStartTop + animStartHeight
+ // Pause any animation that may be currently playing; we will use the relevant
+ // details of that animation here.
+ state.dragAnimator.cancelAnimator()
+ // We still apply scale to task bounds; as we animate the bounds to their
+ // end value, animate scale to 1.
+ val startScale = state.dragAnimator.scale
+ val startPosition = state.dragAnimator.position
+ val unscaledStartWidth = startBounds.width()
+ val unscaledStartHeight = startBounds.height()
+ val unscaledStartBounds = Rect(
+ startPosition.x.toInt(),
+ startPosition.y.toInt(),
+ startPosition.x.toInt() + unscaledStartWidth,
+ startPosition.y.toInt() + unscaledStartHeight
)
-
dragToDesktopStateListener?.onCommitToDesktopAnimationStart(t)
- t.apply {
- setScale(draggedTaskLeash, 1f, 1f)
- setPosition(
- draggedTaskLeash,
- animStartBounds.left.toFloat(),
- animStartBounds.top.toFloat()
- )
- setWindowCrop(
- draggedTaskLeash,
- animStartBounds.width(),
- animStartBounds.height()
- )
- }
// Accept the merge by applying the merging transaction (applied by #showResizeVeil)
// and finish callback. Show the veil and position the task at the first frame before
// starting the final animation.
- onTaskResizeAnimationListener.onAnimationStart(state.draggedTaskId, t, animStartBounds)
+ onTaskResizeAnimationListener.onAnimationStart(state.draggedTaskId, t,
+ unscaledStartBounds)
finishCallback.onTransitionFinished(null /* wct */)
- // Because the task surface was scaled down during the drag, we must use the animated
- // bounds instead of the [startAbsBounds].
val tx: SurfaceControl.Transaction = transactionSupplier.get()
- ValueAnimator.ofObject(rectEvaluator, animStartBounds, endBounds)
+ ValueAnimator.ofObject(rectEvaluator, unscaledStartBounds, endBounds)
.setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
.apply {
addUpdateListener { animator ->
val animBounds = animator.animatedValue as Rect
+ val animFraction = animator.animatedFraction
+ // Progress scale from starting value to 1 as animation plays.
+ val animScale = startScale + animFraction * (1 - startScale)
tx.apply {
- setScale(draggedTaskLeash, 1f, 1f)
- setPosition(
- draggedTaskLeash,
- animBounds.left.toFloat(),
- animBounds.top.toFloat()
- )
+ setScale(draggedTaskLeash, animScale, animScale)
+ setPosition(
+ draggedTaskLeash,
+ animBounds.left.toFloat(),
+ animBounds.top.toFloat()
+ )
setWindowCrop(
- draggedTaskLeash,
- animBounds.width(),
- animBounds.height()
+ draggedTaskLeash,
+ animBounds.width(),
+ animBounds.height()
)
}
onTaskResizeAnimationListener.onBoundsChange(
@@ -493,10 +476,8 @@ class DragToDesktopTransitionHandler(
val draggedTaskChange = state.draggedTaskChange
?: throw IllegalStateException("Expected non-null task change")
val sc = draggedTaskChange.leash
- // TODO(b/301106941): Don't end the animation and start one to scale it back, merge them
- // instead.
- // End the animation that shrinks the window when task is first dragged from fullscreen
- dragToDesktopAnimator.endAnimator()
+ // Pause the animation that shrinks the window when task is first dragged from fullscreen
+ dragToDesktopAnimator.cancelAnimator()
// Then animate the scaled window back to its original bounds.
val x: Float = dragToDesktopAnimator.position.x
val y: Float = dragToDesktopAnimator.position.y
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 708b14cdd19a..a0f9c6b9bb15 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -33,16 +33,8 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
-import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
-import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
+
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
@@ -858,26 +850,18 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
case MotionEvent.ACTION_UP: {
if (mTransitionDragActive) {
- final DesktopModeVisualIndicator.IndicatorType indicatorType =
- mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
- relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+ mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
mTransitionDragActive = false;
- if (indicatorType == TO_DESKTOP_INDICATOR
- || indicatorType == TO_SPLIT_LEFT_INDICATOR
- || indicatorType == TO_SPLIT_RIGHT_INDICATOR) {
- if (DesktopModeStatus.isEnabled()) {
- animateToDesktop(relevantDecor, ev);
- }
- mMoveToDesktopAnimator = null;
- return;
- } else if (mMoveToDesktopAnimator != null) {
+ if (mMoveToDesktopAnimator != null) {
// Though this isn't a hover event, we need to update handle's hover state
// as it likely will change.
relevantDecor.updateHoverAndPressStatus(ev);
mDesktopTasksController.onDragPositioningEndThroughStatusBar(
new PointF(ev.getRawX(), ev.getRawY()),
relevantDecor.mTaskInfo,
- calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE));
+ calculateFreeformBounds(ev.getDisplayId(),
+ DesktopTasksController.DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
mMoveToDesktopAnimator = null;
return;
} else {
@@ -946,54 +930,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
(int) (screenHeight * (adjustmentPercentage + scale)));
}
- /**
- * Blocks relayout until transition is finished and transitions to Desktop
- */
- private void animateToDesktop(DesktopModeWindowDecoration relevantDecor,
- MotionEvent ev) {
- centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
- }
-
- /**
- * Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
- * @param relevantDecor the window decor of the task to be animated
- * @param ev the motion event that triggers the animation
- * TODO(b/315527000): This animation needs to be adjusted to allow snap left/right cases.
- * Currently fullscreen -> split snap still animates to center screen before readjusting.
- */
- private void centerAndMoveToDesktopWithAnimation(DesktopModeWindowDecoration relevantDecor,
- MotionEvent ev) {
- ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
- animator.setDuration(FREEFORM_ANIMATION_DURATION);
- final SurfaceControl sc = relevantDecor.mTaskSurface;
- final Rect endBounds = calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE);
- final Transaction t = mTransactionFactory.get();
- final float diffX = endBounds.centerX() - ev.getRawX();
- final float diffY = endBounds.top - ev.getRawY();
- final float startingX = ev.getRawX() - DRAG_FREEFORM_SCALE
- * mDragToDesktopAnimationStartBounds.width() / 2;
-
- animator.addUpdateListener(animation -> {
- final float animatorValue = (float) animation.getAnimatedValue();
- final float x = startingX + diffX * animatorValue;
- final float y = ev.getRawY() + diffY * animatorValue;
- t.setPosition(sc, x, y);
- t.apply();
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mDesktopTasksController.onDragPositioningEndThroughStatusBar(
- new PointF(ev.getRawX(), ev.getRawY()),
- relevantDecor.mTaskInfo,
- calculateFreeformBounds(ev.getDisplayId(),
- DesktopTasksController
- .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
- }
- });
- animator.start();
- }
-
@Nullable
private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
index af055230b629..987aadfbdef2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
@@ -31,15 +31,16 @@ class MoveToDesktopAnimator @JvmOverloads constructor(
private val animatedTaskWidth
get() = dragToDesktopAnimator.animatedValue as Float * startBounds.width()
+ val scale: Float
+ get() = dragToDesktopAnimator.animatedValue as Float
private val dragToDesktopAnimator: ValueAnimator = ValueAnimator.ofFloat(1f,
DRAG_FREEFORM_SCALE)
.setDuration(ANIMATION_DURATION.toLong())
.apply {
val t = SurfaceControl.Transaction()
val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
- addUpdateListener { animation ->
- val animatorValue = animation.animatedValue as Float
- t.setScale(taskSurface, animatorValue, animatorValue)
+ addUpdateListener {
+ t.setScale(taskSurface, scale, scale)
.setCornerRadius(taskSurface, cornerRadius)
.apply()
}
@@ -90,9 +91,9 @@ class MoveToDesktopAnimator @JvmOverloads constructor(
}
/**
- * Ends the animation, setting the scale and position to the final animation value
+ * Cancels the animation, intended to be used when another animator will take over.
*/
- fun endAnimator() {
- dragToDesktopAnimator.end()
+ fun cancelAnimator() {
+ dragToDesktopAnimator.cancel()
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index 98e90d60b3b6..2ade3fba9b08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -190,7 +190,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
handler.cancelDragToDesktopTransition()
// Cancel animation should run since it had already started.
- verify(dragAnimator).endAnimator()
+ verify(dragAnimator).cancelAnimator()
}
@Test