diff options
10 files changed, 169 insertions, 83 deletions
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 2e3f60441b3a..14e82539a6a5 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -419,4 +419,8 @@ <dimen name="freeform_resize_handle">15dp</dimen> <dimen name="freeform_resize_corner">44dp</dimen> + + <!-- The height of the area at the top of the screen where a freeform task will transition to + fullscreen if dragged until the top bound of the task is within the area. --> + <dimen name="desktop_mode_transition_area_height">16dp</dimen> </resources> 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 65a35b2ffcb3..4fda4b7896c2 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 @@ -100,6 +100,10 @@ class DesktopTasksController( } } + private val transitionAreaHeight + get() = context.resources.getDimensionPixelSize( + com.android.wm.shell.R.dimen.desktop_mode_transition_area_height) + init { desktopMode = DesktopModeImpl() if (DesktopModeStatus.isProto2Enabled()) { @@ -700,13 +704,12 @@ class DesktopTasksController( y: Float ) { if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) { - val statusBarHeight = getStatusBarHeight(taskInfo) - if (y <= statusBarHeight && visualIndicator == null) { + if (y <= transitionAreaHeight && visualIndicator == null) { visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo, displayController, context, taskSurface, shellTaskOrganizer, rootTaskDisplayAreaOrganizer) visualIndicator?.createFullscreenIndicatorWithAnimatedBounds() - } else if (y > statusBarHeight && visualIndicator != null) { + } else if (y > transitionAreaHeight && visualIndicator != null) { releaseVisualIndicator() } } @@ -726,8 +729,7 @@ class DesktopTasksController( y: Float, windowDecor: DesktopModeWindowDecoration ) { - val statusBarHeight = getStatusBarHeight(taskInfo) - if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) { + if (y <= transitionAreaHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) { windowDecor.incrementRelayoutBlock() moveToFullscreenWithAnimation(taskInfo, position) } @@ -746,9 +748,9 @@ 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)) { + // If the motion event is above the status bar and the visual indicator is not yet visible, + // return since we do not need to show the visual indicator at this point. + if (y < getStatusBarHeight(taskInfo) && visualIndicator == null) { return } if (visualIndicator == null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java index 92c2a7c03ee4..cf1692018518 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java @@ -193,7 +193,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { final DragPositioningCallback dragPositioningCallback = new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController, - null /* disallowedAreaForEndBounds */); + 0 /* disallowedAreaForEndBoundsHeight */); final CaptionTouchEventListener touchEventListener = new CaptionTouchEventListener(taskInfo, dragPositioningCallback); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); 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 331835cca142..7245bc91cfca 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 @@ -845,7 +845,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { windowDecoration.createResizeVeil(); final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback( - windowDecoration, taskInfo); + windowDecoration); final DesktopModeTouchEventListener touchEventListener = new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback); @@ -858,24 +858,17 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { incrementEventReceiverTasks(taskInfo.displayId); } private DragPositioningCallback createDragPositioningCallback( - @NonNull DesktopModeWindowDecoration windowDecoration, - @NonNull RunningTaskInfo taskInfo) { - final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width(); - final Rect disallowedAreaForEndBounds; - if (DesktopModeStatus.isProto2Enabled()) { - disallowedAreaForEndBounds = new Rect(0, 0, screenWidth, - getStatusBarHeight(taskInfo.displayId)); - } else { - disallowedAreaForEndBounds = null; - } + @NonNull DesktopModeWindowDecoration windowDecoration) { + final int transitionAreaHeight = mContext.getResources().getDimensionPixelSize( + R.dimen.desktop_mode_transition_area_height); if (!DesktopModeStatus.isVeiledResizeEnabled()) { return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, - mDisplayController, disallowedAreaForEndBounds, mDragStartListener, - mTransactionFactory); + mDisplayController, mDragStartListener, mTransactionFactory, + transitionAreaHeight); } else { return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration, - mDisplayController, disallowedAreaForEndBounds, mDragStartListener, - mTransitions); + mDisplayController, mDragStartListener, mTransitions, + transitionAreaHeight); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java index 09e29bcbcf9f..e32bd42acf74 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java @@ -83,8 +83,6 @@ public class DragPositioningCallbackUtility { // Make sure the new resizing destination in any direction falls within the stable bounds. // If not, set the bounds back to the old location that was valid to avoid conflicts with // some regions such as the gesture area. - displayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId()) - .getStableBounds(stableBounds); if ((ctrlType & CTRL_TYPE_LEFT) != 0) { final int candidateLeft = repositionTaskBounds.left + (int) delta.x; repositionTaskBounds.left = (candidateLeft > stableBounds.left) @@ -136,7 +134,7 @@ public class DragPositioningCallbackUtility { repositionTaskBounds.top); } - static void updateTaskBounds(Rect repositionTaskBounds, Rect taskBoundsAtDragStart, + private static void updateTaskBounds(Rect repositionTaskBounds, Rect taskBoundsAtDragStart, PointF repositionStartPoint, float x, float y) { final float deltaX = x - repositionStartPoint.x; final float deltaY = y - repositionStartPoint.y; @@ -145,6 +143,23 @@ public class DragPositioningCallbackUtility { } /** + * Updates repositionTaskBounds to the final bounds of the task after the drag is finished. If + * the bounds are outside of the stable bounds, they are shifted to place task at the top of the + * stable bounds. + */ + static void onDragEnd(Rect repositionTaskBounds, Rect taskBoundsAtDragStart, Rect stableBounds, + PointF repositionStartPoint, float x, float y) { + updateTaskBounds(repositionTaskBounds, taskBoundsAtDragStart, repositionStartPoint, + x, y); + + // If task is outside of stable bounds (in the status bar area), shift the task down. + if (stableBounds.top > repositionTaskBounds.top) { + final int yShift = stableBounds.top - repositionTaskBounds.top; + repositionTaskBounds.offset(0, yShift); + } + } + + /** * Apply a bounds change to a task. * @param windowDecoration decor of task we are changing bounds for * @param taskBounds new bounds of this task diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java index 9082323452c9..917abf5524a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java @@ -21,8 +21,6 @@ import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; -import androidx.annotation.Nullable; - import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; @@ -42,28 +40,31 @@ class FluidResizeTaskPositioner implements DragPositioningCallback { private final Rect mTaskBoundsAtDragStart = new Rect(); private final PointF mRepositionStartPoint = new PointF(); private final Rect mRepositionTaskBounds = new Rect(); - // If a task move (not resize) finishes in this region, the positioner will not attempt to + // If a task move (not resize) finishes with the positions y less than this value, do not // finalize the bounds there using WCT#setBounds - private final Rect mDisallowedAreaForEndBounds; + private final int mDisallowedAreaForEndBoundsHeight; private boolean mHasDragResized; private int mCtrlType; FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration, - DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds) { - this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, - dragStartListener -> {}, SurfaceControl.Transaction::new); + DisplayController displayController, int disallowedAreaForEndBoundsHeight) { + this(taskOrganizer, windowDecoration, displayController, dragStartListener -> {}, + SurfaceControl.Transaction::new, disallowedAreaForEndBoundsHeight); } FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration, - DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds, + DisplayController displayController, DragPositioningCallbackUtility.DragStartListener dragStartListener, - Supplier<SurfaceControl.Transaction> supplier) { + Supplier<SurfaceControl.Transaction> supplier, + int disallowedAreaForEndBoundsHeight) { mTaskOrganizer = taskOrganizer; mWindowDecoration = windowDecoration; mDisplayController = displayController; - mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds); mDragStartListener = dragStartListener; mTransactionSupplier = supplier; + mDisallowedAreaForEndBoundsHeight = disallowedAreaForEndBoundsHeight; + mDisplayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId()) + .getStableBounds(mStableBounds); } @Override @@ -121,10 +122,10 @@ class FluidResizeTaskPositioner implements DragPositioningCallback { } mTaskOrganizer.applyTransaction(wct); } else if (mCtrlType == CTRL_TYPE_UNDEFINED - && !mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { + && y > mDisallowedAreaForEndBoundsHeight) { final WindowContainerTransaction wct = new WindowContainerTransaction(); - DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, - mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); + DragPositioningCallbackUtility.onDragEnd(mRepositionTaskBounds, + mTaskBoundsAtDragStart, mStableBounds, mRepositionStartPoint, x, y); wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds); mTaskOrganizer.applyTransaction(wct); } 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 39b90218dce1..bf3ff3fa83ef 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 @@ -53,33 +53,35 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, private final Rect mTaskBoundsAtDragStart = new Rect(); private final PointF mRepositionStartPoint = new PointF(); private final Rect mRepositionTaskBounds = new Rect(); - // If a task move (not resize) finishes in this region, the positioner will not attempt to + // If a task move (not resize) finishes with the positions y less than this value, do not // finalize the bounds there using WCT#setBounds - private final Rect mDisallowedAreaForEndBounds; + private final int mDisallowedAreaForEndBoundsHeight; private final Supplier<SurfaceControl.Transaction> mTransactionSupplier; private int mCtrlType; public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, DesktopModeWindowDecoration windowDecoration, DisplayController displayController, - Rect disallowedAreaForEndBounds, DragPositioningCallbackUtility.DragStartListener dragStartListener, - Transitions transitions) { - this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, - dragStartListener, SurfaceControl.Transaction::new, transitions); + Transitions transitions, + int disallowedAreaForEndBoundsHeight) { + this(taskOrganizer, windowDecoration, displayController, dragStartListener, + SurfaceControl.Transaction::new, transitions, disallowedAreaForEndBoundsHeight); } public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, DesktopModeWindowDecoration windowDecoration, DisplayController displayController, - Rect disallowedAreaForEndBounds, DragPositioningCallbackUtility.DragStartListener dragStartListener, - Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) { + Supplier<SurfaceControl.Transaction> supplier, Transitions transitions, + int disallowedAreaForEndBoundsHeight) { mTaskOrganizer = taskOrganizer; mDesktopWindowDecoration = windowDecoration; mDisplayController = displayController; mDragStartListener = dragStartListener; - mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds); mTransactionSupplier = supplier; mTransitions = transitions; + mDisallowedAreaForEndBoundsHeight = disallowedAreaForEndBoundsHeight; + mDisplayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId()) + .getStableBounds(mStableBounds); } @Override @@ -110,8 +112,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, } else if (mCtrlType == CTRL_TYPE_UNDEFINED) { final SurfaceControl.Transaction t = mTransactionSupplier.get(); DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration, - mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, - x, y); + mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, x, y); t.apply(); } } @@ -138,9 +139,9 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, // won't be called. mDesktopWindowDecoration.hideResizeVeil(); } - } else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { - DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, - mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); + } else if (y > mDisallowedAreaForEndBoundsHeight) { + DragPositioningCallbackUtility.onDragEnd(mRepositionTaskBounds, + mTaskBoundsAtDragStart, mStableBounds, mRepositionStartPoint, x, y); DragPositioningCallbackUtility.applyTaskBoundsChange(new WindowContainerTransaction(), mDesktopWindowDecoration, mRepositionTaskBounds, mTaskOrganizer); } 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 23158eac94de..adc2a6fbff23 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 @@ -90,6 +90,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { @Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory; @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private SurfaceControl.Transaction mTransaction; + @Mock private Display mDisplay; private final List<InputManager> mMockInputManagers = new ArrayList<>(); private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; @@ -126,6 +127,9 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG); inputChannels[0].dispose(); when(mInputMonitor.getInputChannel()).thenReturn(inputChannels[1]); + + mDesktopModeWindowDecoration.mDisplay = mDisplay; + doReturn(Display.DEFAULT_DISPLAY).when(mDisplay).getDisplayId(); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt index 69604ddf0af1..6f0599aa8243 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt @@ -22,6 +22,7 @@ import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFI import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.any import org.mockito.Mockito.argThat @@ -71,16 +72,6 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) - taskPositioner = - FluidResizeTaskPositioner( - mockShellTaskOrganizer, - mockWindowDecoration, - mockDisplayController, - DISALLOWED_AREA_FOR_END_BOUNDS, - mockDragStartListener, - mockTransactionFactory - ) - whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) @@ -101,6 +92,15 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { } mockWindowDecoration.mDisplay = mockDisplay whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } + + taskPositioner = FluidResizeTaskPositioner( + mockShellTaskOrganizer, + mockWindowDecoration, + mockDisplayController, + mockDragStartListener, + mockTransactionFactory, + DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT + ) } @Test @@ -544,7 +544,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { ) val newX = STARTING_BOUNDS.right.toFloat() + 5 - val newY = STARTING_BOUNDS.top.toFloat() + 5 + val newY = DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT.toFloat() - 1 taskPositioner.onDragPositioningMove( newX, newY @@ -614,6 +614,38 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { }) } + @Test + fun testDragResize_drag_taskPositionedInStableBounds() { + taskPositioner.onDragPositioningStart( + CTRL_TYPE_UNDEFINED, // drag + STARTING_BOUNDS.left.toFloat(), + STARTING_BOUNDS.top.toFloat() + ) + + val newX = STARTING_BOUNDS.left.toFloat() + val newY = STABLE_BOUNDS.top.toFloat() - 5 + taskPositioner.onDragPositioningMove( + newX, + newY + ) + verify(mockTransaction).setPosition(any(), eq(newX), eq(newY)) + + taskPositioner.onDragPositioningEnd( + newX, + newY + ) + // Verify task's top bound is set to stable bounds top since dragged outside stable bounds + // but not in disallowed end bounds area. + verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> + return@argThat wct.changes.any { (token, change) -> + token == taskBinder && + (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && + change.configuration.windowConfiguration.bounds.top == + STABLE_BOUNDS.top + } + }) + } + companion object { private const val TASK_ID = 5 private const val MIN_WIDTH = 10 @@ -622,10 +654,11 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { private const val DEFAULT_MIN = 40 private const val DISPLAY_ID = 1 private const val NAVBAR_HEIGHT = 50 + private const val CAPTION_HEIGHT = 50 + private const val DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT = 10 private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) - private val STARTING_BOUNDS = Rect(0, 0, 100, 100) + private val STARTING_BOUNDS = Rect(100, 100, 200, 200) private val STABLE_INSETS = Rect(0, 50, 0, 0) - private val DISALLOWED_AREA_FOR_END_BOUNDS = Rect(0, 0, 300, 300) private val DISALLOWED_RESIZE_AREA = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, @@ -633,7 +666,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { DISPLAY_BOUNDS.bottom) private val STABLE_BOUNDS = Rect( DISPLAY_BOUNDS.left, - DISPLAY_BOUNDS.top, + DISPLAY_BOUNDS.top + CAPTION_HEIGHT, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT ) 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 4147dd8e6152..3465ddd9d101 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 @@ -89,17 +89,6 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) - taskPositioner = - VeiledResizeTaskPositioner( - mockShellTaskOrganizer, - mockDesktopWindowDecoration, - mockDisplayController, - DISALLOWED_AREA_FOR_END_BOUNDS, - mockDragStartListener, - mockTransactionFactory, - mockTransitions - ) - whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) @@ -119,6 +108,17 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { } mockDesktopWindowDecoration.mDisplay = mockDisplay whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } + + taskPositioner = + VeiledResizeTaskPositioner( + mockShellTaskOrganizer, + mockDesktopWindowDecoration, + mockDisplayController, + mockDragStartListener, + mockTransactionFactory, + mockTransitions, + DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT + ) } @Test @@ -269,7 +269,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { ) val newX = STARTING_BOUNDS.left.toFloat() + 5 - val newY = STARTING_BOUNDS.top.toFloat() + 5 + val newY = DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT.toFloat() - 1 taskPositioner.onDragPositioningMove( newX, newY @@ -334,6 +334,38 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { }) } + @Test + fun testDragResize_drag_taskPositionedInStableBounds() { + taskPositioner.onDragPositioningStart( + CTRL_TYPE_UNDEFINED, // drag + STARTING_BOUNDS.left.toFloat(), + STARTING_BOUNDS.top.toFloat() + ) + + val newX = STARTING_BOUNDS.left.toFloat() + val newY = STABLE_BOUNDS.top.toFloat() - 5 + taskPositioner.onDragPositioningMove( + newX, + newY + ) + verify(mockTransaction).setPosition(any(), eq(newX), eq(newY)) + + taskPositioner.onDragPositioningEnd( + newX, + newY + ) + // Verify task's top bound is set to stable bounds top since dragged outside stable bounds + // but not in disallowed end bounds area. + verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> + return@argThat wct.changes.any { (token, change) -> + token == taskBinder && + (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && + change.configuration.windowConfiguration.bounds.top == + STABLE_BOUNDS.top + } + }) + } + companion object { private const val TASK_ID = 5 private const val MIN_WIDTH = 10 @@ -342,12 +374,13 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { private const val DEFAULT_MIN = 40 private const val DISPLAY_ID = 1 private const val NAVBAR_HEIGHT = 50 + private const val CAPTION_HEIGHT = 50 + private const val DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT = 10 private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) - private val STARTING_BOUNDS = Rect(0, 0, 100, 100) - private val DISALLOWED_AREA_FOR_END_BOUNDS = Rect(0, 0, 50, 50) + private val STARTING_BOUNDS = Rect(100, 100, 200, 200) private val STABLE_BOUNDS = Rect( DISPLAY_BOUNDS.left, - DISPLAY_BOUNDS.top, + DISPLAY_BOUNDS.top + CAPTION_HEIGHT, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT ) |