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
This commit is contained in:
Maryam Dehaini
2023-04-06 13:55:30 -07:00
parent d5494efd55
commit 8ce3f0f33c
4 changed files with 70 additions and 2 deletions

View File

@@ -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)

View File

@@ -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<IBinder> 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;
}

View File

@@ -143,6 +143,10 @@ public class Transitions implements RemoteCallable<Transitions> {
/** 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;

View File

@@ -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;
}