diff options
| author | 2024-04-02 21:08:51 +0000 | |
|---|---|---|
| committer | 2024-04-02 21:08:51 +0000 | |
| commit | 2f663508f8201102d292079b0d44b683d15c4786 (patch) | |
| tree | 59743f770e15eec15e93a531188a75c902b7d5f5 | |
| parent | c8d77cfb4a3036d5a78434b77955e8b7a3a9193d (diff) | |
| parent | dafa45174601930e07879e7114cc2e44b0d15ed8 (diff) | |
Merge "Combine bounds change and move-to-center animations." into main
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 |