diff options
6 files changed, 87 insertions, 27 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index f3130d358ec1..5f9c1b291a30 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -200,6 +200,7 @@ public abstract class WMShellModule { ShellTaskOrganizer taskOrganizer, DisplayController displayController, SyncTransactionQueue syncQueue, + Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, Optional<SplitScreenController> splitScreenController) { @@ -211,6 +212,7 @@ public abstract class WMShellModule { taskOrganizer, displayController, syncQueue, + transitions, desktopModeController, desktopTasksController, splitScreenController); 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 54babce13205..9fd57d7e1201 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 @@ -104,6 +104,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final InputMonitorFactory mInputMonitorFactory; private TaskOperations mTaskOperations; private final Supplier<SurfaceControl.Transaction> mTransactionFactory; + private final Transitions mTransitions; private Optional<SplitScreenController> mSplitScreenController; @@ -118,6 +119,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { ShellTaskOrganizer taskOrganizer, DisplayController displayController, SyncTransactionQueue syncQueue, + Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, Optional<SplitScreenController> splitScreenController) { @@ -128,6 +130,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { taskOrganizer, displayController, syncQueue, + transitions, desktopModeController, desktopTasksController, splitScreenController, @@ -144,6 +147,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { ShellTaskOrganizer taskOrganizer, DisplayController displayController, SyncTransactionQueue syncQueue, + Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, Optional<SplitScreenController> splitScreenController, @@ -158,6 +162,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDisplayController = displayController; mSplitScreenController = splitScreenController; mSyncQueue = syncQueue; + mTransitions = transitions; mDesktopModeController = desktopModeController; mDesktopTasksController = desktopTasksController; @@ -818,7 +823,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { } else { windowDecoration.createResizeVeil(); return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration, - mDisplayController, disallowedAreaForEndBounds, mDragStartListener); + mDisplayController, disallowedAreaForEndBounds, mDragStartListener, + mTransitions); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java index b785ef005062..82771095cd82 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java @@ -44,7 +44,7 @@ import java.util.function.Supplier; * Creates and updates a veil that covers task contents on resize. */ public class ResizeVeil { - private static final int RESIZE_ALPHA_DURATION = 200; + private static final int RESIZE_ALPHA_DURATION = 100; private final Context mContext; private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier; private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier; @@ -155,7 +155,6 @@ public class ResizeVeil { * Animate veil's alpha to 0, fading it out. */ public void hideVeil() { - final View resizeVeilView = mViewHost.getView(); final ValueAnimator animator = new ValueAnimator(); animator.setFloatValues(1, 0); animator.setDuration(RESIZE_ALPHA_DURATION); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java index 56475a800ef9..58c78e6a5b9f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java @@ -16,13 +16,22 @@ package com.android.wm.shell.windowdecor; +import static android.view.WindowManager.TRANSIT_CHANGE; + import android.graphics.PointF; import android.graphics.Rect; +import android.os.IBinder; import android.view.SurfaceControl; +import android.window.TransitionInfo; +import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.transition.Transitions; import java.util.function.Supplier; @@ -32,12 +41,14 @@ import java.util.function.Supplier; * If the drag is resizing the task, we resize the veil instead. * If the drag is repositioning, we update in the typical manner. */ -public class VeiledResizeTaskPositioner implements DragPositioningCallback { +public class VeiledResizeTaskPositioner implements DragPositioningCallback, + Transitions.TransitionHandler { private DesktopModeWindowDecoration mDesktopWindowDecoration; private ShellTaskOrganizer mTaskOrganizer; private DisplayController mDisplayController; private DragPositioningCallbackUtility.DragStartListener mDragStartListener; + private final Transitions mTransitions; private final Rect mStableBounds = new Rect(); private final Rect mTaskBoundsAtDragStart = new Rect(); private final PointF mRepositionStartPoint = new PointF(); @@ -46,28 +57,29 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { // finalize the bounds there using WCT#setBounds private final Rect mDisallowedAreaForEndBounds = new Rect(); private final Supplier<SurfaceControl.Transaction> mTransactionSupplier; - private boolean mHasDragResized; private int mCtrlType; public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, DesktopModeWindowDecoration windowDecoration, DisplayController displayController, Rect disallowedAreaForEndBounds, - DragPositioningCallbackUtility.DragStartListener dragStartListener) { + DragPositioningCallbackUtility.DragStartListener dragStartListener, + Transitions transitions) { this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, - dragStartListener, SurfaceControl.Transaction::new); + dragStartListener, SurfaceControl.Transaction::new, transitions); } public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, DesktopModeWindowDecoration windowDecoration, DisplayController displayController, Rect disallowedAreaForEndBounds, DragPositioningCallbackUtility.DragStartListener dragStartListener, - Supplier<SurfaceControl.Transaction> supplier) { + Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) { mTaskOrganizer = taskOrganizer; mDesktopWindowDecoration = windowDecoration; mDisplayController = displayController; mDragStartListener = dragStartListener; mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds); mTransactionSupplier = supplier; + mTransitions = transitions; } @Override @@ -84,7 +96,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { mTaskOrganizer.applyTransaction(wct); } } - mHasDragResized = false; mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId); mRepositionTaskBounds.set(mTaskBoundsAtDragStart); } @@ -96,7 +107,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta, mDisplayController, mDesktopWindowDecoration)) { mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); - mHasDragResized = true; } else if (mCtrlType == CTRL_TYPE_UNDEFINED) { final SurfaceControl.Transaction t = mTransactionSupplier.get(); DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration, @@ -111,18 +121,23 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, mRepositionStartPoint); if (isResizing()) { - if (mHasDragResized) { + if (!mTaskBoundsAtDragStart.equals(mRepositionTaskBounds)) { DragPositioningCallbackUtility.changeBounds( mCtrlType, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta, mDisplayController, mDesktopWindowDecoration); - DragPositioningCallbackUtility.applyTaskBoundsChange( - new WindowContainerTransaction(), mDesktopWindowDecoration, - mRepositionTaskBounds, mTaskOrganizer); + mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds); + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + mTransitions.startTransition(TRANSIT_CHANGE, wct, this); + } else { + mTaskOrganizer.applyTransaction(wct); + } + } else { + // If bounds haven't changed, perform necessary veil reset here as startAnimation + // won't be called. + mDesktopWindowDecoration.hideResizeVeil(); } - // TODO: (b/279062291) Synchronize the start of hide to the end of the draw triggered - // above. - mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); - mDesktopWindowDecoration.hideResizeVeil(); } else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); @@ -133,7 +148,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { mCtrlType = CTRL_TYPE_UNDEFINED; mTaskBoundsAtDragStart.setEmpty(); mRepositionStartPoint.set(0, 0); - mHasDragResized = false; } private boolean isResizing() { @@ -141,4 +155,26 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback { || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0; } + @Override + public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + startTransaction.apply(); + mDesktopWindowDecoration.hideResizeVeil(); + mCtrlType = CTRL_TYPE_UNDEFINED; + finishCallback.onTransitionFinished(null, null); + return true; + } + + /** + * We should never reach this as this handler's transitions are only started from shell + * explicitly. + */ + @Nullable + @Override + public WindowContainerTransaction handleRequest(@NonNull IBinder transition, + @NonNull TransitionRequestInfo request) { + return null; + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java index 4c27706a39a3..41bab95b7dd4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java @@ -54,6 +54,7 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.transition.Transitions; import org.junit.Before; import org.junit.Test; @@ -87,6 +88,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { @Mock private DesktopTasksController mDesktopTasksController; @Mock private InputMonitor mInputMonitor; @Mock private InputManager mInputManager; + @Mock private Transitions mTransitions; @Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory; @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private SurfaceControl.Transaction mTransaction; @@ -106,6 +108,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { mTaskOrganizer, mDisplayController, mSyncQueue, + mTransitions, Optional.of(mDesktopModeController), Optional.of(mDesktopTasksController), Optional.of(mSplitScreenController), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt index 337e40df44bf..4147dd8e6152 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt @@ -22,12 +22,14 @@ import android.os.IBinder import android.testing.AndroidTestingRunner import android.view.Display import android.view.SurfaceControl +import android.view.WindowManager.TRANSIT_CHANGE import android.window.WindowContainerToken import androidx.test.filters.SmallTest import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout +import com.android.wm.shell.transition.Transitions import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED @@ -78,6 +80,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { private lateinit var mockTransactionFactory: Supplier<SurfaceControl.Transaction> @Mock private lateinit var mockTransaction: SurfaceControl.Transaction + @Mock + private lateinit var mockTransitions: Transitions private lateinit var taskPositioner: VeiledResizeTaskPositioner @@ -92,7 +96,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { mockDisplayController, DISALLOWED_AREA_FOR_END_BOUNDS, mockDragStartListener, - mockTransactionFactory + mockTransactionFactory, + mockTransitions ) whenever(taskToken.asBinder()).thenReturn(taskBinder) @@ -129,6 +134,12 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() ) + verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct -> + return@argThat wct.changes.any { (token, change) -> + token == taskBinder && + (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && + change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}}, + eq(taskPositioner)) verify(mockDesktopWindowDecoration).hideResizeVeil() } @@ -206,15 +217,12 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { rectAfterEnd.right += 10 rectAfterEnd.top += 10 verify(mockDesktopWindowDecoration, times(2)).updateResizeVeil(any()) - verify(mockDesktopWindowDecoration).hideResizeVeil() - - verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> + verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && - change.configuration.windowConfiguration.bounds == rectAfterEnd - } - }) + change.configuration.windowConfiguration.bounds == rectAfterEnd}}, + eq(taskPositioner)) } @Test @@ -235,7 +243,13 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10 ) - verify(mockDesktopWindowDecoration).hideResizeVeil() + + verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct -> + return@argThat wct.changes.any { (token, change) -> + token == taskBinder && + (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && + change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}}, + eq(taskPositioner)) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> |