From cc1f82538c33f245128d2eb9461b2a6dcb6c3e46 Mon Sep 17 00:00:00 2001 From: Maryam Dehaini Date: Thu, 6 Apr 2023 14:57:14 -0700 Subject: [PATCH] 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 --- .../DesktopModeVisualIndicator.java | 7 +-- .../desktopmode/DesktopTasksController.kt | 45 +++++++++++++------ .../EnterDesktopTaskTransitionHandler.java | 25 ++++++++--- .../ExitDesktopTaskTransitionHandler.java | 14 ++++-- .../DesktopModeWindowDecorViewModel.java | 7 ++- ...EnterDesktopTaskTransitionHandlerTest.java | 4 +- .../ExitDesktopTaskTransitionHandlerTest.java | 2 +- 7 files changed, 69 insertions(+), 35 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java index fb0a91f178025..0f0d572f8eaed 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java @@ -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(); - }); } } 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 c814fe575e811..4b70f794dd629 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 @@ -78,6 +78,11 @@ class DesktopTasksController( private val desktopMode: DesktopModeImpl private var visualIndicator: DesktopModeVisualIndicator? = null + private val mOnAnimationFinishedCallback = Consumer { + 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. * 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 94675788c5141..d55fdddf4fea8 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 @@ -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 mPendingTransitionTokens = new ArrayList<>(); private Point mStartPosition; + private Consumer 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 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 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)); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java index fa3eee257a520..160a83d7ed366 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java @@ -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 mPendingTransitionTokens = new ArrayList<>(); - + private Consumer mOnAnimationFinishedCallback; private Supplier 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 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)); } 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 4cda5715ac1f6..f46b100a3e3ac 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 @@ -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) { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java index 6199e0b050597..8592dea192890 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java @@ -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); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java index 4fad05433d1c9..265b10df1945a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java @@ -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);