Merge "If task dragged to outer disallowed area, position back under the area" into udc-qpr-dev

This commit is contained in:
Maryam Dehaini
2023-06-26 20:49:39 +00:00
committed by Android (Google) Code Review
10 changed files with 169 additions and 83 deletions

View File

@@ -419,4 +419,8 @@
<dimen name="freeform_resize_handle">15dp</dimen> <dimen name="freeform_resize_handle">15dp</dimen>
<dimen name="freeform_resize_corner">44dp</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> </resources>

View File

@@ -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 { init {
desktopMode = DesktopModeImpl() desktopMode = DesktopModeImpl()
if (DesktopModeStatus.isProto2Enabled()) { if (DesktopModeStatus.isProto2Enabled()) {
@@ -700,13 +704,12 @@ class DesktopTasksController(
y: Float y: Float
) { ) {
if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) { if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
val statusBarHeight = getStatusBarHeight(taskInfo) if (y <= transitionAreaHeight && visualIndicator == null) {
if (y <= statusBarHeight && visualIndicator == null) {
visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo, visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
displayController, context, taskSurface, shellTaskOrganizer, displayController, context, taskSurface, shellTaskOrganizer,
rootTaskDisplayAreaOrganizer) rootTaskDisplayAreaOrganizer)
visualIndicator?.createFullscreenIndicatorWithAnimatedBounds() visualIndicator?.createFullscreenIndicatorWithAnimatedBounds()
} else if (y > statusBarHeight && visualIndicator != null) { } else if (y > transitionAreaHeight && visualIndicator != null) {
releaseVisualIndicator() releaseVisualIndicator()
} }
} }
@@ -726,8 +729,7 @@ class DesktopTasksController(
y: Float, y: Float,
windowDecor: DesktopModeWindowDecoration windowDecor: DesktopModeWindowDecoration
) { ) {
val statusBarHeight = getStatusBarHeight(taskInfo) if (y <= transitionAreaHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
windowDecor.incrementRelayoutBlock() windowDecor.incrementRelayoutBlock()
moveToFullscreenWithAnimation(taskInfo, position) moveToFullscreenWithAnimation(taskInfo, position)
} }
@@ -746,9 +748,9 @@ class DesktopTasksController(
taskSurface: SurfaceControl, taskSurface: SurfaceControl,
y: Float y: Float
) { ) {
// If the motion event is above the status bar, return since we do not need to show the // If the motion event is above the status bar and the visual indicator is not yet visible,
// visual indicator at this point. // return since we do not need to show the visual indicator at this point.
if (y < getStatusBarHeight(taskInfo)) { if (y < getStatusBarHeight(taskInfo) && visualIndicator == null) {
return return
} }
if (visualIndicator == null) { if (visualIndicator == null) {

View File

@@ -193,7 +193,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
final DragPositioningCallback dragPositioningCallback = final DragPositioningCallback dragPositioningCallback =
new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController, new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController,
null /* disallowedAreaForEndBounds */); 0 /* disallowedAreaForEndBoundsHeight */);
final CaptionTouchEventListener touchEventListener = final CaptionTouchEventListener touchEventListener =
new CaptionTouchEventListener(taskInfo, dragPositioningCallback); new CaptionTouchEventListener(taskInfo, dragPositioningCallback);
windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);

View File

@@ -845,7 +845,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
windowDecoration.createResizeVeil(); windowDecoration.createResizeVeil();
final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback( final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback(
windowDecoration, taskInfo); windowDecoration);
final DesktopModeTouchEventListener touchEventListener = final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback); new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);
@@ -858,24 +858,17 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
incrementEventReceiverTasks(taskInfo.displayId); incrementEventReceiverTasks(taskInfo.displayId);
} }
private DragPositioningCallback createDragPositioningCallback( private DragPositioningCallback createDragPositioningCallback(
@NonNull DesktopModeWindowDecoration windowDecoration, @NonNull DesktopModeWindowDecoration windowDecoration) {
@NonNull RunningTaskInfo taskInfo) { final int transitionAreaHeight = mContext.getResources().getDimensionPixelSize(
final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width(); R.dimen.desktop_mode_transition_area_height);
final Rect disallowedAreaForEndBounds;
if (DesktopModeStatus.isProto2Enabled()) {
disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
getStatusBarHeight(taskInfo.displayId));
} else {
disallowedAreaForEndBounds = null;
}
if (!DesktopModeStatus.isVeiledResizeEnabled()) { if (!DesktopModeStatus.isVeiledResizeEnabled()) {
return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
mDisplayController, disallowedAreaForEndBounds, mDragStartListener, mDisplayController, mDragStartListener, mTransactionFactory,
mTransactionFactory); transitionAreaHeight);
} else { } else {
return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration, return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
mDisplayController, disallowedAreaForEndBounds, mDragStartListener, mDisplayController, mDragStartListener, mTransitions,
mTransitions); transitionAreaHeight);
} }
} }

View File

@@ -83,8 +83,6 @@ public class DragPositioningCallbackUtility {
// Make sure the new resizing destination in any direction falls within the stable bounds. // 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 // If not, set the bounds back to the old location that was valid to avoid conflicts with
// some regions such as the gesture area. // some regions such as the gesture area.
displayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId())
.getStableBounds(stableBounds);
if ((ctrlType & CTRL_TYPE_LEFT) != 0) { if ((ctrlType & CTRL_TYPE_LEFT) != 0) {
final int candidateLeft = repositionTaskBounds.left + (int) delta.x; final int candidateLeft = repositionTaskBounds.left + (int) delta.x;
repositionTaskBounds.left = (candidateLeft > stableBounds.left) repositionTaskBounds.left = (candidateLeft > stableBounds.left)
@@ -136,7 +134,7 @@ public class DragPositioningCallbackUtility {
repositionTaskBounds.top); repositionTaskBounds.top);
} }
static void updateTaskBounds(Rect repositionTaskBounds, Rect taskBoundsAtDragStart, private static void updateTaskBounds(Rect repositionTaskBounds, Rect taskBoundsAtDragStart,
PointF repositionStartPoint, float x, float y) { PointF repositionStartPoint, float x, float y) {
final float deltaX = x - repositionStartPoint.x; final float deltaX = x - repositionStartPoint.x;
final float deltaY = y - repositionStartPoint.y; final float deltaY = y - repositionStartPoint.y;
@@ -144,6 +142,23 @@ public class DragPositioningCallbackUtility {
repositionTaskBounds.offset((int) deltaX, (int) deltaY); repositionTaskBounds.offset((int) deltaX, (int) deltaY);
} }
/**
* 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. * Apply a bounds change to a task.
* @param windowDecoration decor of task we are changing bounds for * @param windowDecoration decor of task we are changing bounds for

View File

@@ -21,8 +21,6 @@ import android.graphics.Rect;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import androidx.annotation.Nullable;
import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController;
@@ -42,28 +40,31 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
private final Rect mTaskBoundsAtDragStart = new Rect(); private final Rect mTaskBoundsAtDragStart = new Rect();
private final PointF mRepositionStartPoint = new PointF(); private final PointF mRepositionStartPoint = new PointF();
private final Rect mRepositionTaskBounds = new Rect(); 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 // finalize the bounds there using WCT#setBounds
private final Rect mDisallowedAreaForEndBounds; private final int mDisallowedAreaForEndBoundsHeight;
private boolean mHasDragResized; private boolean mHasDragResized;
private int mCtrlType; private int mCtrlType;
FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration, FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds) { DisplayController displayController, int disallowedAreaForEndBoundsHeight) {
this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, this(taskOrganizer, windowDecoration, displayController, dragStartListener -> {},
dragStartListener -> {}, SurfaceControl.Transaction::new); SurfaceControl.Transaction::new, disallowedAreaForEndBoundsHeight);
} }
FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration, FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
DisplayController displayController, @Nullable Rect disallowedAreaForEndBounds, DisplayController displayController,
DragPositioningCallbackUtility.DragStartListener dragStartListener, DragPositioningCallbackUtility.DragStartListener dragStartListener,
Supplier<SurfaceControl.Transaction> supplier) { Supplier<SurfaceControl.Transaction> supplier,
int disallowedAreaForEndBoundsHeight) {
mTaskOrganizer = taskOrganizer; mTaskOrganizer = taskOrganizer;
mWindowDecoration = windowDecoration; mWindowDecoration = windowDecoration;
mDisplayController = displayController; mDisplayController = displayController;
mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds);
mDragStartListener = dragStartListener; mDragStartListener = dragStartListener;
mTransactionSupplier = supplier; mTransactionSupplier = supplier;
mDisallowedAreaForEndBoundsHeight = disallowedAreaForEndBoundsHeight;
mDisplayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId())
.getStableBounds(mStableBounds);
} }
@Override @Override
@@ -121,10 +122,10 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
} }
mTaskOrganizer.applyTransaction(wct); mTaskOrganizer.applyTransaction(wct);
} else if (mCtrlType == CTRL_TYPE_UNDEFINED } else if (mCtrlType == CTRL_TYPE_UNDEFINED
&& !mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { && y > mDisallowedAreaForEndBoundsHeight) {
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, DragPositioningCallbackUtility.onDragEnd(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); mTaskBoundsAtDragStart, mStableBounds, mRepositionStartPoint, x, y);
wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds); wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
mTaskOrganizer.applyTransaction(wct); mTaskOrganizer.applyTransaction(wct);
} }

View File

@@ -53,33 +53,35 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
private final Rect mTaskBoundsAtDragStart = new Rect(); private final Rect mTaskBoundsAtDragStart = new Rect();
private final PointF mRepositionStartPoint = new PointF(); private final PointF mRepositionStartPoint = new PointF();
private final Rect mRepositionTaskBounds = new Rect(); 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 // finalize the bounds there using WCT#setBounds
private final Rect mDisallowedAreaForEndBounds; private final int mDisallowedAreaForEndBoundsHeight;
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier; private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
private int mCtrlType; private int mCtrlType;
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration, DisplayController displayController, DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
Rect disallowedAreaForEndBounds,
DragPositioningCallbackUtility.DragStartListener dragStartListener, DragPositioningCallbackUtility.DragStartListener dragStartListener,
Transitions transitions) { Transitions transitions,
this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, int disallowedAreaForEndBoundsHeight) {
dragStartListener, SurfaceControl.Transaction::new, transitions); this(taskOrganizer, windowDecoration, displayController, dragStartListener,
SurfaceControl.Transaction::new, transitions, disallowedAreaForEndBoundsHeight);
} }
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration, DisplayController displayController, DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
Rect disallowedAreaForEndBounds,
DragPositioningCallbackUtility.DragStartListener dragStartListener, DragPositioningCallbackUtility.DragStartListener dragStartListener,
Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) { Supplier<SurfaceControl.Transaction> supplier, Transitions transitions,
int disallowedAreaForEndBoundsHeight) {
mTaskOrganizer = taskOrganizer; mTaskOrganizer = taskOrganizer;
mDesktopWindowDecoration = windowDecoration; mDesktopWindowDecoration = windowDecoration;
mDisplayController = displayController; mDisplayController = displayController;
mDragStartListener = dragStartListener; mDragStartListener = dragStartListener;
mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds);
mTransactionSupplier = supplier; mTransactionSupplier = supplier;
mTransitions = transitions; mTransitions = transitions;
mDisallowedAreaForEndBoundsHeight = disallowedAreaForEndBoundsHeight;
mDisplayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId())
.getStableBounds(mStableBounds);
} }
@Override @Override
@@ -110,8 +112,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
} else if (mCtrlType == CTRL_TYPE_UNDEFINED) { } else if (mCtrlType == CTRL_TYPE_UNDEFINED) {
final SurfaceControl.Transaction t = mTransactionSupplier.get(); final SurfaceControl.Transaction t = mTransactionSupplier.get();
DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration, DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration,
mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, x, y);
x, y);
t.apply(); t.apply();
} }
} }
@@ -138,9 +139,9 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
// won't be called. // won't be called.
mDesktopWindowDecoration.hideResizeVeil(); mDesktopWindowDecoration.hideResizeVeil();
} }
} else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { } else if (y > mDisallowedAreaForEndBoundsHeight) {
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, DragPositioningCallbackUtility.onDragEnd(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); mTaskBoundsAtDragStart, mStableBounds, mRepositionStartPoint, x, y);
DragPositioningCallbackUtility.applyTaskBoundsChange(new WindowContainerTransaction(), DragPositioningCallbackUtility.applyTaskBoundsChange(new WindowContainerTransaction(),
mDesktopWindowDecoration, mRepositionTaskBounds, mTaskOrganizer); mDesktopWindowDecoration, mRepositionTaskBounds, mTaskOrganizer);
} }

View File

@@ -90,6 +90,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
@Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory; @Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory;
@Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory;
@Mock private SurfaceControl.Transaction mTransaction; @Mock private SurfaceControl.Transaction mTransaction;
@Mock private Display mDisplay;
private final List<InputManager> mMockInputManagers = new ArrayList<>(); private final List<InputManager> mMockInputManagers = new ArrayList<>();
private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel;
@@ -126,6 +127,9 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG); final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG);
inputChannels[0].dispose(); inputChannels[0].dispose();
when(mInputMonitor.getInputChannel()).thenReturn(inputChannels[1]); when(mInputMonitor.getInputChannel()).thenReturn(inputChannels[1]);
mDesktopModeWindowDecoration.mDisplay = mDisplay;
doReturn(Display.DEFAULT_DISPLAY).when(mDisplay).getDisplayId();
} }
@Test @Test

View File

@@ -22,6 +22,7 @@ import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFI
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.any import org.mockito.Mockito.any
import org.mockito.Mockito.argThat import org.mockito.Mockito.argThat
@@ -71,16 +72,6 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
taskPositioner =
FluidResizeTaskPositioner(
mockShellTaskOrganizer,
mockWindowDecoration,
mockDisplayController,
DISALLOWED_AREA_FOR_END_BOUNDS,
mockDragStartListener,
mockTransactionFactory
)
whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(taskToken.asBinder()).thenReturn(taskBinder)
whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
@@ -101,6 +92,15 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
} }
mockWindowDecoration.mDisplay = mockDisplay mockWindowDecoration.mDisplay = mockDisplay
whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
taskPositioner = FluidResizeTaskPositioner(
mockShellTaskOrganizer,
mockWindowDecoration,
mockDisplayController,
mockDragStartListener,
mockTransactionFactory,
DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT
)
} }
@Test @Test
@@ -544,7 +544,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
) )
val newX = STARTING_BOUNDS.right.toFloat() + 5 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( taskPositioner.onDragPositioningMove(
newX, newX,
newY 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 { companion object {
private const val TASK_ID = 5 private const val TASK_ID = 5
private const val MIN_WIDTH = 10 private const val MIN_WIDTH = 10
@@ -622,10 +654,11 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
private const val DEFAULT_MIN = 40 private const val DEFAULT_MIN = 40
private const val DISPLAY_ID = 1 private const val DISPLAY_ID = 1
private const val NAVBAR_HEIGHT = 50 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 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 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( private val DISALLOWED_RESIZE_AREA = Rect(
DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.left,
DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
@@ -633,7 +666,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
DISPLAY_BOUNDS.bottom) DISPLAY_BOUNDS.bottom)
private val STABLE_BOUNDS = Rect( private val STABLE_BOUNDS = Rect(
DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.left,
DISPLAY_BOUNDS.top, DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.right,
DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
) )

View File

@@ -89,17 +89,6 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
taskPositioner =
VeiledResizeTaskPositioner(
mockShellTaskOrganizer,
mockDesktopWindowDecoration,
mockDisplayController,
DISALLOWED_AREA_FOR_END_BOUNDS,
mockDragStartListener,
mockTransactionFactory,
mockTransitions
)
whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(taskToken.asBinder()).thenReturn(taskBinder)
whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
@@ -119,6 +108,17 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
} }
mockDesktopWindowDecoration.mDisplay = mockDisplay mockDesktopWindowDecoration.mDisplay = mockDisplay
whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
taskPositioner =
VeiledResizeTaskPositioner(
mockShellTaskOrganizer,
mockDesktopWindowDecoration,
mockDisplayController,
mockDragStartListener,
mockTransactionFactory,
mockTransitions,
DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT
)
} }
@Test @Test
@@ -269,7 +269,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
) )
val newX = STARTING_BOUNDS.left.toFloat() + 5 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( taskPositioner.onDragPositioningMove(
newX, newX,
newY 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 { companion object {
private const val TASK_ID = 5 private const val TASK_ID = 5
private const val MIN_WIDTH = 10 private const val MIN_WIDTH = 10
@@ -342,12 +374,13 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
private const val DEFAULT_MIN = 40 private const val DEFAULT_MIN = 40
private const val DISPLAY_ID = 1 private const val DISPLAY_ID = 1
private const val NAVBAR_HEIGHT = 50 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 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 DISALLOWED_AREA_FOR_END_BOUNDS = Rect(0, 0, 50, 50)
private val STABLE_BOUNDS = Rect( private val STABLE_BOUNDS = Rect(
DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.left,
DISPLAY_BOUNDS.top, DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.right,
DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
) )