Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt 0 → 100644 +232 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.windowdecor import android.app.ActivityManager import android.graphics.PointF import android.graphics.Rect import android.os.IBinder import android.testing.AndroidTestingRunner import android.view.Display import android.window.WindowContainerToken import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.any import org.mockito.MockitoAnnotations /** * Tests for [DragPositioningCallbackUtility]. * * Build/Install/Run: * atest WMShellUnitTests:DragPositioningCallbackUtilityTest */ @RunWith(AndroidTestingRunner::class) class DragPositioningCallbackUtilityTest { @Mock private lateinit var mockWindowDecoration: WindowDecoration<*> @Mock private lateinit var taskToken: WindowContainerToken @Mock private lateinit var taskBinder: IBinder @Mock private lateinit var mockDisplayController: DisplayController @Mock private lateinit var mockDisplayLayout: DisplayLayout @Mock private lateinit var mockDisplay: Display @Before fun setup() { MockitoAnnotations.initMocks(this) whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = TASK_ID token = taskToken minWidth = MIN_WIDTH minHeight = MIN_HEIGHT defaultMinSize = DEFAULT_MIN displayId = DISPLAY_ID configuration.windowConfiguration.bounds = STARTING_BOUNDS } mockWindowDecoration.mDisplay = mockDisplay whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } } @Test fun testChangeBoundsDoesNotChangeHeightWhenLessThanMin() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to width of 95px and height of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 95 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotChangeWidthWhenLessThanMin() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to height of 95px and width of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 5 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 5) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotChangeHeightWhenNegative() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to width of 95px and width of -5px with minimum of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 105 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsRunsWhenResizeBoundsValid() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Shrink to height 20px and width 20px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 80 val newY = STARTING_BOUNDS.top.toFloat() + 80 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 80) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotRunWithNegativeHeightAndWidth() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Shrink to height -5px and width -5px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 105 val newY = STARTING_BOUNDS.top.toFloat() + 105 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBounds_toDisallowedBounds_freezesAtLimit() { var hasMoved = false val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat()) val repositionTaskBounds = Rect() // Initial resize to width and height 110px. var newX = STARTING_BOUNDS.right.toFloat() + 10 var newY = STARTING_BOUNDS.bottom.toFloat() + 10 var delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration)) hasMoved = true // Resize width to 120px, height to disallowed area which should not result in a change. newX += 10 newY = DISALLOWED_RESIZE_AREA.top.toFloat() delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration)) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right + 20) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom + 10) } companion object { private const val TASK_ID = 5 private const val MIN_WIDTH = 10 private const val MIN_HEIGHT = 10 private const val DENSITY_DPI = 20 private const val DEFAULT_MIN = 40 private const val DISPLAY_ID = 1 private const val NAVBAR_HEIGHT = 50 private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) private val STARTING_BOUNDS = Rect(0, 0, 100, 100) private val DISALLOWED_RESIZE_AREA = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom) private val STABLE_BOUNDS = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.top, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT ) } } No newline at end of file libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt +6 −294 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM 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 Loading @@ -22,7 +21,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.any import org.mockito.Mockito.argThat import org.mockito.Mockito.never Loading Loading @@ -72,10 +71,10 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { mockDragStartListener ) `when`(taskToken.asBinder()).thenReturn(taskBinder) `when`(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) `when`(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) `when`(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } Loading @@ -89,7 +88,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { configuration.windowConfiguration.bounds = STARTING_BOUNDS } mockWindowDecoration.mDisplay = mockDisplay `when`(mockDisplay.displayId).thenAnswer { DISPLAY_ID } whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } } @Test Loading Loading @@ -237,293 +236,6 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenLessThanMin() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to width of 95px and height of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 95 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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 == STARTING_BOUNDS.top && change.configuration.windowConfiguration.bounds.bottom == STARTING_BOUNDS.bottom } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenLessThanMin() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to height of 95px and width of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 5 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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.right == STARTING_BOUNDS.right && change.configuration.windowConfiguration.bounds.left == STARTING_BOUNDS.left } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenNegative() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to height of -5px and width of 95px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 105 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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 == STARTING_BOUNDS.top && change.configuration.windowConfiguration.bounds.bottom == STARTING_BOUNDS.bottom } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenNegative() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to width of -5px and height of 95px val newX = STARTING_BOUNDS.right.toFloat() - 105 val newY = STARTING_BOUNDS.top.toFloat() + 5 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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.right == STARTING_BOUNDS.right && change.configuration.windowConfiguration.bounds.left == STARTING_BOUNDS.left } }) } @Test fun testDragResize_resize_setBoundsRunsWhenResizeBoundsValid() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to height 20px and width 20px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 80 val newY = STARTING_BOUNDS.top.toFloat() + 80 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_setBoundsDoesNotRunWithNegativeHeightAndWidth() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to height 5px and width 5px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 95 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_useDefaultMinWhenMinWidthInvalid() { mockWindowDecoration.mTaskInfo.minWidth = -1 taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to width and height of 3px with invalid minWidth = -1 and defaultMinSize = 5px val newX = STARTING_BOUNDS.right.toFloat() - 97 val newY = STARTING_BOUNDS.top.toFloat() + 97 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_useMinWidthWhenValid() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to width and height of 7px with valid minWidth = 10px and defaultMinSize = 5px val newX = STARTING_BOUNDS.right.toFloat() - 93 val newY = STARTING_BOUNDS.top.toFloat() + 93 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } fun testDragResize_toDisallowedBounds_freezesAtLimit() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, // Resize right-bottom corner STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat() ) // Resize the task by 10px to the right and bottom, a valid destination val newBounds = Rect( STARTING_BOUNDS.left, STARTING_BOUNDS.top, STARTING_BOUNDS.right + 10, STARTING_BOUNDS.bottom + 10) taskPositioner.onDragPositioningMove( newBounds.right.toFloat(), newBounds.bottom.toFloat() ) // Resize the task by another 10px to the right (allowed) and to just in the disallowed // area of the Y coordinate. val newBounds2 = Rect( newBounds.left, newBounds.top, newBounds.right + 10, DISALLOWED_RESIZE_AREA.top ) taskPositioner.onDragPositioningMove( newBounds2.right.toFloat(), newBounds2.bottom.toFloat() ) taskPositioner.onDragPositioningEnd(newBounds2.right.toFloat(), newBounds2.bottom.toFloat()) // The first resize falls in the allowed area, verify there's a change for it. verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds(newBounds) } }) // The second resize falls in the disallowed area, verify there's no change for it. verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds(newBounds2) } }) // Instead, there should be a change for its allowed portion (the X movement) with the Y // staying frozen in the last valid resize position. verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds( Rect( newBounds2.left, newBounds2.top, newBounds2.right, newBounds.bottom // Stayed at the first resize destination. ) ) } }) } private fun WindowContainerTransaction.Change.ofBounds(bounds: Rect): Boolean { return ((windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) && bounds == configuration.windowConfiguration.bounds Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt +6 −6 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt 0 → 100644 +232 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.windowdecor import android.app.ActivityManager import android.graphics.PointF import android.graphics.Rect import android.os.IBinder import android.testing.AndroidTestingRunner import android.view.Display import android.window.WindowContainerToken import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.any import org.mockito.MockitoAnnotations /** * Tests for [DragPositioningCallbackUtility]. * * Build/Install/Run: * atest WMShellUnitTests:DragPositioningCallbackUtilityTest */ @RunWith(AndroidTestingRunner::class) class DragPositioningCallbackUtilityTest { @Mock private lateinit var mockWindowDecoration: WindowDecoration<*> @Mock private lateinit var taskToken: WindowContainerToken @Mock private lateinit var taskBinder: IBinder @Mock private lateinit var mockDisplayController: DisplayController @Mock private lateinit var mockDisplayLayout: DisplayLayout @Mock private lateinit var mockDisplay: Display @Before fun setup() { MockitoAnnotations.initMocks(this) whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = TASK_ID token = taskToken minWidth = MIN_WIDTH minHeight = MIN_HEIGHT defaultMinSize = DEFAULT_MIN displayId = DISPLAY_ID configuration.windowConfiguration.bounds = STARTING_BOUNDS } mockWindowDecoration.mDisplay = mockDisplay whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } } @Test fun testChangeBoundsDoesNotChangeHeightWhenLessThanMin() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to width of 95px and height of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 95 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotChangeWidthWhenLessThanMin() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to height of 95px and width of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 5 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 5) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotChangeHeightWhenNegative() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Resize to width of 95px and width of -5px with minimum of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 105 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsRunsWhenResizeBoundsValid() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Shrink to height 20px and width 20px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 80 val newY = STARTING_BOUNDS.top.toFloat() + 80 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 80) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBoundsDoesNotRunWithNegativeHeightAndWidth() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect() // Shrink to height -5px and width -5px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 105 val newY = STARTING_BOUNDS.top.toFloat() + 105 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } @Test fun testChangeBounds_toDisallowedBounds_freezesAtLimit() { var hasMoved = false val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat()) val repositionTaskBounds = Rect() // Initial resize to width and height 110px. var newX = STARTING_BOUNDS.right.toFloat() + 10 var newY = STARTING_BOUNDS.bottom.toFloat() + 10 var delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration)) hasMoved = true // Resize width to 120px, height to disallowed area which should not result in a change. newX += 10 newY = DISALLOWED_RESIZE_AREA.top.toFloat() delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, mockWindowDecoration)) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right + 20) assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom + 10) } companion object { private const val TASK_ID = 5 private const val MIN_WIDTH = 10 private const val MIN_HEIGHT = 10 private const val DENSITY_DPI = 20 private const val DEFAULT_MIN = 40 private const val DISPLAY_ID = 1 private const val NAVBAR_HEIGHT = 50 private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) private val STARTING_BOUNDS = Rect(0, 0, 100, 100) private val DISALLOWED_RESIZE_AREA = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom) private val STABLE_BOUNDS = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.top, DISPLAY_BOUNDS.right, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT ) } } No newline at end of file
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt +6 −294 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM 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 Loading @@ -22,7 +21,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.any import org.mockito.Mockito.argThat import org.mockito.Mockito.never Loading Loading @@ -72,10 +71,10 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { mockDragStartListener ) `when`(taskToken.asBinder()).thenReturn(taskBinder) `when`(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) `when`(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) `when`(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } Loading @@ -89,7 +88,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { configuration.windowConfiguration.bounds = STARTING_BOUNDS } mockWindowDecoration.mDisplay = mockDisplay `when`(mockDisplay.displayId).thenAnswer { DISPLAY_ID } whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } } @Test Loading Loading @@ -237,293 +236,6 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenLessThanMin() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to width of 95px and height of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 95 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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 == STARTING_BOUNDS.top && change.configuration.windowConfiguration.bounds.bottom == STARTING_BOUNDS.bottom } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenLessThanMin() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to height of 95px and width of 5px with min width of 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 5 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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.right == STARTING_BOUNDS.right && change.configuration.windowConfiguration.bounds.left == STARTING_BOUNDS.left } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenNegative() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to height of -5px and width of 95px val newX = STARTING_BOUNDS.right.toFloat() - 5 val newY = STARTING_BOUNDS.top.toFloat() + 105 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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 == STARTING_BOUNDS.top && change.configuration.windowConfiguration.bounds.bottom == STARTING_BOUNDS.bottom } }) } @Test fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenNegative() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Resize to width of -5px and height of 95px val newX = STARTING_BOUNDS.right.toFloat() - 105 val newY = STARTING_BOUNDS.top.toFloat() + 5 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) 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.right == STARTING_BOUNDS.right && change.configuration.windowConfiguration.bounds.left == STARTING_BOUNDS.left } }) } @Test fun testDragResize_resize_setBoundsRunsWhenResizeBoundsValid() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to height 20px and width 20px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 80 val newY = STARTING_BOUNDS.top.toFloat() + 80 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_setBoundsDoesNotRunWithNegativeHeightAndWidth() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to height 5px and width 5px with both min height/width equal to 10px val newX = STARTING_BOUNDS.right.toFloat() - 95 val newY = STARTING_BOUNDS.top.toFloat() + 95 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_useDefaultMinWhenMinWidthInvalid() { mockWindowDecoration.mTaskInfo.minWidth = -1 taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to width and height of 3px with invalid minWidth = -1 and defaultMinSize = 5px val newX = STARTING_BOUNDS.right.toFloat() - 97 val newY = STARTING_BOUNDS.top.toFloat() + 97 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } @Test fun testDragResize_resize_useMinWidthWhenValid() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat() ) // Shrink to width and height of 7px with valid minWidth = 10px and defaultMinSize = 5px val newX = STARTING_BOUNDS.right.toFloat() - 93 val newY = STARTING_BOUNDS.top.toFloat() + 93 taskPositioner.onDragPositioningMove( newX, newY ) taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) } }) } fun testDragResize_toDisallowedBounds_freezesAtLimit() { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, // Resize right-bottom corner STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat() ) // Resize the task by 10px to the right and bottom, a valid destination val newBounds = Rect( STARTING_BOUNDS.left, STARTING_BOUNDS.top, STARTING_BOUNDS.right + 10, STARTING_BOUNDS.bottom + 10) taskPositioner.onDragPositioningMove( newBounds.right.toFloat(), newBounds.bottom.toFloat() ) // Resize the task by another 10px to the right (allowed) and to just in the disallowed // area of the Y coordinate. val newBounds2 = Rect( newBounds.left, newBounds.top, newBounds.right + 10, DISALLOWED_RESIZE_AREA.top ) taskPositioner.onDragPositioningMove( newBounds2.right.toFloat(), newBounds2.bottom.toFloat() ) taskPositioner.onDragPositioningEnd(newBounds2.right.toFloat(), newBounds2.bottom.toFloat()) // The first resize falls in the allowed area, verify there's a change for it. verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds(newBounds) } }) // The second resize falls in the disallowed area, verify there's no change for it. verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds(newBounds2) } }) // Instead, there should be a change for its allowed portion (the X movement) with the Y // staying frozen in the last valid resize position. verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> token == taskBinder && change.ofBounds( Rect( newBounds2.left, newBounds2.top, newBounds2.right, newBounds.bottom // Stayed at the first resize destination. ) ) } }) } private fun WindowContainerTransaction.Change.ofBounds(bounds: Rect): Boolean { return ((windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) && bounds == configuration.windowConfiguration.bounds Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt +6 −6 File changed.Preview size limit exceeded, changes collapsed. Show changes