Fix add and remove times for visual indicator

This task fixes two visual indicator bugs:
1. Currently, the visual indicator is added as soon as the task is dragged below the status bar. This change will make the DesktopTasksController wait for the task to be dragged below the status bar to draw the visual indicator.
2. Wait for the animation to grow or shrink a window during fullscreen and freeform transitions before removing so that the visual indicator does not disappear too early.

Bug: 276979555
Test: Manual Testing
Change-Id: Ib1c9a477feaa327f7a2430dd995b12b0bad255b4
This commit is contained in:
Maryam Dehaini
2023-04-06 14:57:14 -07:00
parent c7ac88d484
commit cc1f82538c
7 changed files with 69 additions and 35 deletions

View File

@@ -162,7 +162,7 @@ public class DesktopModeVisualIndicator {
/**
* Release the indicator and its components when it is no longer needed.
*/
public void releaseVisualIndicator() {
public void releaseVisualIndicator(SurfaceControl.Transaction t) {
if (mViewHost == null) return;
if (mViewHost != null) {
mViewHost.release();
@@ -170,13 +170,8 @@ public class DesktopModeVisualIndicator {
}
if (mLeash != null) {
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.remove(mLeash);
mLeash = null;
mSyncQueue.runInSync(transaction -> {
transaction.merge(t);
t.close();
});
}
}

View File

@@ -78,6 +78,11 @@ class DesktopTasksController(
private val desktopMode: DesktopModeImpl
private var visualIndicator: DesktopModeVisualIndicator? = null
private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> {
t: SurfaceControl.Transaction ->
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
}
init {
desktopMode = DesktopModeImpl()
@@ -154,14 +159,14 @@ class DesktopTasksController(
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
enterDesktopTaskTransitionHandler.startTransition(
Transitions.TRANSIT_ENTER_FREEFORM, wct)
Transitions.TRANSIT_ENTER_FREEFORM, wct, mOnAnimationFinishedCallback)
} else {
shellTaskOrganizer.applyTransaction(wct)
}
}
/** Brings apps to front and sets freeform task bounds */
fun moveToDesktopWithAnimation(
private fun moveToDesktopWithAnimation(
taskInfo: RunningTaskInfo,
freeformBounds: Rect
) {
@@ -172,9 +177,10 @@ class DesktopTasksController(
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
enterDesktopTaskTransitionHandler.startTransition(
Transitions.TRANSIT_ENTER_DESKTOP_MODE, wct)
Transitions.TRANSIT_ENTER_DESKTOP_MODE, wct, mOnAnimationFinishedCallback)
} else {
shellTaskOrganizer.applyTransaction(wct)
releaseVisualIndicator()
}
}
@@ -205,21 +211,24 @@ class DesktopTasksController(
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task.token)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, startPosition)
enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, startPosition,
mOnAnimationFinishedCallback)
} else {
shellTaskOrganizer.applyTransaction(wct)
releaseVisualIndicator()
}
}
fun moveToFullscreenWithAnimation(task: ActivityManager.RunningTaskInfo) {
private fun moveToFullscreenWithAnimation(task: ActivityManager.RunningTaskInfo) {
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task.token)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
exitDesktopTaskTransitionHandler.startTransition(
Transitions.TRANSIT_EXIT_DESKTOP_MODE, wct)
Transitions.TRANSIT_EXIT_DESKTOP_MODE, wct, mOnAnimationFinishedCallback)
} else {
shellTaskOrganizer.applyTransaction(wct)
releaseVisualIndicator()
}
}
@@ -267,6 +276,16 @@ class DesktopTasksController(
?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
}
private fun releaseVisualIndicator() {
val t = SurfaceControl.Transaction()
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
syncQueue.runInSync { transaction ->
transaction.merge(t)
t.close()
}
}
override fun getContext(): Context {
return context
}
@@ -408,8 +427,7 @@ class DesktopTasksController(
rootTaskDisplayAreaOrganizer)
visualIndicator?.createFullscreenIndicatorWithAnimatedBounds()
} else if (y > statusBarHeight && visualIndicator != null) {
visualIndicator?.releaseVisualIndicator()
visualIndicator = null
releaseVisualIndicator()
}
}
}
@@ -426,8 +444,6 @@ class DesktopTasksController(
) {
val statusBarHeight = getStatusBarHeight(taskInfo)
if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
visualIndicator?.releaseVisualIndicator()
visualIndicator = null
moveToFullscreenWithAnimation(taskInfo)
}
}
@@ -445,6 +461,11 @@ class DesktopTasksController(
taskSurface: SurfaceControl,
y: Float
) {
// If the motion event is above the status bar, return since we do not need to show the
// visual indicator at this point.
if (y < getStatusBarHeight(taskInfo)) {
return
}
if (visualIndicator == null) {
visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
displayController, context, taskSurface, shellTaskOrganizer,
@@ -472,11 +493,8 @@ class DesktopTasksController(
freeformBounds: Rect
) {
moveToDesktopWithAnimation(taskInfo, freeformBounds)
visualIndicator?.releaseVisualIndicator()
visualIndicator = null
}
private fun getStatusBarHeight(taskInfo: RunningTaskInfo): Int {
return displayController.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
}
@@ -503,7 +521,6 @@ class DesktopTasksController(
desktopModeTaskRepository.removeTaskCorners(taskId)
}
/**
* Adds a listener to find out about changes in the visibility of freeform tasks.
*

View File

@@ -39,6 +39,7 @@ import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -58,6 +59,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
private Point mStartPosition;
private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
public EnterDesktopTaskTransitionHandler(
Transitions transitions) {
@@ -75,9 +77,12 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
* Starts Transition of a given type
* @param type Transition type
* @param wct WindowContainerTransaction for transition
* @param onAnimationEndCallback to be called after animation
*/
public void startTransition(@WindowManager.TransitionType int type,
@NonNull WindowContainerTransaction wct) {
@NonNull WindowContainerTransaction wct,
Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
mOnAnimationFinishedCallback = onAnimationEndCallback;
final IBinder token = mTransitions.startTransition(type, wct, this);
mPendingTransitionTokens.add(token);
}
@@ -86,11 +91,14 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
* Starts Transition of type TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
* @param wct WindowContainerTransaction for transition
* @param startPosition Position of task when transition is triggered
* @param onAnimationEndCallback to be called after animation
*/
public void startCancelMoveToDesktopMode(@NonNull WindowContainerTransaction wct,
Point startPosition) {
Point startPosition,
Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
mStartPosition = startPosition;
startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct);
startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct,
mOnAnimationFinishedCallback);
}
@Override
@@ -111,7 +119,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
if (change.getMode() == WindowManager.TRANSIT_CHANGE) {
transitionHandled |= startChangeTransition(
transition, info.getType(), change, startT, finishCallback);
transition, info.getType(), change, startT, finishT, finishCallback);
}
}
@@ -125,6 +133,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
@WindowManager.TransitionType int type,
@NonNull TransitionInfo.Change change,
@NonNull SurfaceControl.Transaction startT,
@NonNull SurfaceControl.Transaction finishT,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
if (!mPendingTransitionTokens.contains(transition)) {
return false;
@@ -178,6 +187,9 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mOnAnimationFinishedCallback != null) {
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
() -> finishCallback.onTransitionFinished(null, null));
}
@@ -204,7 +216,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
animator.setDuration(FREEFORM_ANIMATION_DURATION);
final SurfaceControl.Transaction t = mTransactionSupplier.get();
animator.addUpdateListener(animation -> {
final float scale = animation.getAnimatedFraction();
final float scale = (float) animation.getAnimatedValue();
t.setPosition(sc, mStartPosition.x * (1 - scale), mStartPosition.y * (1 - scale))
.setScale(sc, scale, scale)
.show(sc)
@@ -213,6 +225,9 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mOnAnimationFinishedCallback != null) {
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
() -> finishCallback.onTransitionFinished(null, null));
}

View File

@@ -42,6 +42,7 @@ import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -54,7 +55,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
private final Context mContext;
private final Transitions mTransitions;
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
private Supplier<SurfaceControl.Transaction> mTransactionSupplier;
public ExitDesktopTaskTransitionHandler(
@@ -76,9 +77,12 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
* Starts Transition of a given type
* @param type Transition type
* @param wct WindowContainerTransaction for transition
* @param onAnimationEndCallback to be called after animation
*/
public void startTransition(@WindowManager.TransitionType int type,
@NonNull WindowContainerTransaction wct) {
@NonNull WindowContainerTransaction wct,
Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
mOnAnimationFinishedCallback = onAnimationEndCallback;
final IBinder token = mTransitions.startTransition(type, wct, this);
mPendingTransitionTokens.add(token);
}
@@ -101,7 +105,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
if (change.getMode() == WindowManager.TRANSIT_CHANGE) {
transitionHandled |= startChangeTransition(
transition, info.getType(), change, startT, finishCallback);
transition, info.getType(), change, startT, finishT, finishCallback);
}
}
@@ -116,6 +120,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
@WindowManager.TransitionType int type,
@NonNull TransitionInfo.Change change,
@NonNull SurfaceControl.Transaction startT,
@NonNull SurfaceControl.Transaction finishT,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
if (!mPendingTransitionTokens.contains(transition)) {
return false;
@@ -156,6 +161,9 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mOnAnimationFinishedCallback != null) {
mOnAnimationFinishedCallback.accept(finishT);
}
mTransitions.getMainExecutor().execute(
() -> finishCallback.onTransitionFinished(null, null));
}

View File

@@ -111,7 +111,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private ValueAnimator mDragToDesktopValueAnimator;
private final Rect mDragToDesktopAnimationStartBounds = new Rect();
private boolean mDragToDesktopAnimationStarted;
private float mCaptionDragStartX;
public DesktopModeWindowDecorViewModel(
Context context,
@@ -518,7 +517,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
DesktopModeWindowDecoration relevantDecor) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
mCaptionDragStartX = ev.getX();
// Begin drag through status bar if applicable.
if (relevantDecor != null) {
mDragToDesktopAnimationStartBounds.set(
@@ -573,8 +571,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
if (mTransitionDragActive) {
mDesktopTasksController.ifPresent(
c -> c.onDragPositioningMoveThroughStatusBar(relevantDecor.mTaskInfo,
relevantDecor.mTaskSurface, ev.getY()));
c -> c.onDragPositioningMoveThroughStatusBar(
relevantDecor.mTaskInfo,
relevantDecor.mTaskSurface, ev.getY()));
final int statusBarHeight = getStatusBarHeight(
relevantDecor.mTaskInfo.displayId);
if (ev.getY() > statusBarHeight) {

View File

@@ -94,7 +94,7 @@ public class EnterDesktopTaskTransitionHandlerTest {
WindowContainerTransaction wct = new WindowContainerTransaction();
doReturn(mToken).when(mTransitions)
.startTransition(transitionType, wct, mEnterDesktopTaskTransitionHandler);
mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct);
mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct, null);
TransitionInfo.Change change =
createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FREEFORM);
@@ -115,7 +115,7 @@ public class EnterDesktopTaskTransitionHandlerTest {
WindowContainerTransaction wct = new WindowContainerTransaction();
doReturn(mToken).when(mTransitions)
.startTransition(transitionType, wct, mEnterDesktopTaskTransitionHandler);
mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct);
mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct, null);
TransitionInfo.Change change =
createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FREEFORM);

View File

@@ -100,7 +100,7 @@ public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
doReturn(mToken).when(mTransitions)
.startTransition(transitionType, wct, mExitDesktopTaskTransitionHandler);
mExitDesktopTaskTransitionHandler.startTransition(transitionType, wct);
mExitDesktopTaskTransitionHandler.startTransition(transitionType, wct, null);
TransitionInfo.Change change =
createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FULLSCREEN);