From 8ce3f0f33cd0289b573bf3dc3a0f2474cb423e78 Mon Sep 17 00:00:00 2001 From: Maryam Dehaini Date: Thu, 6 Apr 2023 13:55:30 -0700 Subject: [PATCH] Add animation for drag to freeform cancelled Adds animation for when task is dragged below status bar and then released back in status bar area. Bug: 277256992 Test: Manual Testing Change-Id: Icbfb7680bef316d26aa287e308525f85549d9cc3 --- .../desktopmode/DesktopTasksController.kt | 16 +++++++ .../EnterDesktopTaskTransitionHandler.java | 45 +++++++++++++++++++ .../wm/shell/transition/Transitions.java | 4 ++ .../DesktopModeWindowDecorViewModel.java | 7 ++- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 670b24c176b5a..0400963a47e82 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -25,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.app.WindowConfiguration.WindowingMode import android.content.Context +import android.graphics.Point import android.graphics.Rect import android.os.IBinder import android.os.SystemProperties @@ -193,6 +194,21 @@ class DesktopTasksController( } } + + /** + * Move a task to fullscreen after being dragged from fullscreen and released back into + * status bar area + */ + fun cancelMoveToFreeform(task: RunningTaskInfo, startPosition: Point) { + val wct = WindowContainerTransaction() + addMoveToFullscreenChanges(wct, task.token) + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, startPosition) + } else { + shellTaskOrganizer.applyTransaction(wct) + } + } + fun moveToFullscreenWithAnimation(task: ActivityManager.RunningTaskInfo) { val wct = WindowContainerTransaction() addMoveToFullscreenChanges(wct, task.token) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java index 3df2340d45240..27eda16f4171b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java @@ -17,11 +17,13 @@ package com.android.wm.shell.desktopmode; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.ActivityManager; +import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.view.SurfaceControl; @@ -55,6 +57,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition public static final int FREEFORM_ANIMATION_DURATION = 336; private final List mPendingTransitionTokens = new ArrayList<>(); + private Point mStartPosition; public EnterDesktopTaskTransitionHandler( Transitions transitions) { @@ -79,6 +82,17 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition mPendingTransitionTokens.add(token); } + /** + * Starts Transition of type TRANSIT_CANCEL_ENTERING_DESKTOP_MODE + * @param wct WindowContainerTransaction for transition + * @param startPosition Position of task when transition is triggered + */ + public void startCancelMoveToDesktopMode(@NonNull WindowContainerTransaction wct, + Point startPosition) { + mStartPosition = startPosition; + startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct); + } + @Override public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT, @@ -173,6 +187,37 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition return true; } + if (type == Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE + && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN + && mStartPosition != null) { + // This Transition animates a task to fullscreen after being dragged from the status + // bar and then released back into the status bar area + final SurfaceControl sc = change.getLeash(); + startT.setWindowCrop(sc, null); + startT.apply(); + + final ValueAnimator animator = new ValueAnimator(); + animator.setFloatValues(DRAG_FREEFORM_SCALE, 1f); + animator.setDuration(FREEFORM_ANIMATION_DURATION); + final SurfaceControl.Transaction t = mTransactionSupplier.get(); + animator.addUpdateListener(animation -> { + final float scale = animation.getAnimatedFraction(); + t.setPosition(sc, mStartPosition.x * (1 - scale), + mStartPosition.y * (1 - scale)); + t.setScale(sc, scale, scale); + t.apply(); + }); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mTransitions.getMainExecutor().execute( + () -> finishCallback.onTransitionFinished(null, null)); + } + }); + animator.start(); + return true; + } + return false; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index fa4de16b37f17..bdb7d44bad32b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -143,6 +143,10 @@ public class Transitions implements RemoteCallable { /** Transition type to fullscreen from desktop mode. */ public static final int TRANSIT_EXIT_DESKTOP_MODE = WindowManager.TRANSIT_FIRST_CUSTOM + 12; + /** Transition type to animate back to fullscreen when drag to freeform is cancelled. */ + public static final int TRANSIT_CANCEL_ENTERING_DESKTOP_MODE = + WindowManager.TRANSIT_FIRST_CUSTOM + 13; + private final WindowOrganizer mOrganizer; private final Context mContext; private final ShellExecutor mMainExecutor; 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 f99821747fef7..af4c9001a727a 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 @@ -34,6 +34,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityTaskManager; import android.content.Context; import android.content.res.Resources; +import android.graphics.Point; import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Handler; @@ -553,8 +554,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDragToDesktopAnimationStarted = false; return; } else if (mDragToDesktopAnimationStarted) { - mDesktopTasksController.ifPresent(c -> - c.moveToFullscreen(relevantDecor.mTaskInfo)); + Point startPosition = new Point((int) ev.getX(), (int) ev.getY()); + mDesktopTasksController.ifPresent( + c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo, + startPosition)); mDragToDesktopAnimationStarted = false; return; }