diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index b054f51d1b..438a4a02e7 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -202,10 +202,11 @@ public class TestInformationHandler implements ResourceBasedOverride { } case TestProtocol.REQUEST_WORKSPACE_COLUMNS_ROWS: { + InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(mContext); return getLauncherUIProperty(Bundle::putParcelable, launcher -> new Point( - InvariantDeviceProfile.INSTANCE.get(mContext).numColumns, - InvariantDeviceProfile.INSTANCE.get(mContext).numRows) - ); + idp.getDeviceProfile(mContext).getPanelCount() * idp.numColumns, + idp.numRows + )); } case TestProtocol.REQUEST_WORKSPACE_CURRENT_PAGE_INDEX: { diff --git a/tests/assets/ReorderWidgets/multiple_cell_layouts_no_space_reorder b/tests/assets/ReorderWidgets/multiple_cell_layouts_no_space_reorder new file mode 100644 index 0000000000..c6d65f866a --- /dev/null +++ b/tests/assets/ReorderWidgets/multiple_cell_layouts_no_space_reorder @@ -0,0 +1,56 @@ +################################################################################################### +# This file contains test case composed of the following tags: +# * # (coments): Lines starting with this character would be ignored. +# * arguments: is set of words separated by spaces that can later be parsed +# * board: represent a workspace, the first line is the dimensions of the board width x height (wxh) +# There are different characters on the board that represent different things: +# * x: The x character represents spaces that would be ignored, for example it can be used in +# the first row if we don't know how wide the smartspace is. +# * i: Represents an icon on the workspace, none in particular just an icon +# * [a-z]: Represents a widget and it can be any number or character +# except any other already in use. The whole continuos are of the same character is the +# area of the widget. +# * [A-Z]: Represents a folder and number of icons in the folder is represented by the order of +# letter in the alphabet, A=2, B=3, C=4 ... etc. +# Test are parsed by CellLayoutTestCaseReader.java and boards are parsed by CellLayoutBoard.java +################################################################################################### +# 5x5 Test +board: 5x5 +xxxxx|aeeee +--mm-|acccc +--mm-|acccc +ggggg|acccc +ggggg|adddd +arguments: 7 1 +board: 10x5 +xxxxx|aeeee +---mm|acccc +---mm|acccc +ggggg|acccc +ggggg|adddd +# 4x4 Test +board: 4x4 +xxxx|aeee +--mm|accc +--mm|accc +gggg|accc +arguments: 5 1 +board: 8x4 +xxxx|aeee +--mm|accc +--mm|accc +gggg|accc +# 6x5 Test +board: 6x5 +xxxxxx|aeeeee +--mm--|accccc +--mm--|accccc +gggggg|accccc +gggggg|addddd +arguments: 8 1 +board: 12x5 +xxxxxx|aeeeee +----mm|accccc +----mm|accccc +gggggg|accccc +gggggg|addddd diff --git a/tests/assets/ReorderWidgets/multiple_cell_layouts_reorder_other_side b/tests/assets/ReorderWidgets/multiple_cell_layouts_reorder_other_side new file mode 100644 index 0000000000..376638ee19 --- /dev/null +++ b/tests/assets/ReorderWidgets/multiple_cell_layouts_reorder_other_side @@ -0,0 +1,56 @@ +################################################################################################### +# This file contains test case composed of the following tags: +# * # (coments): Lines starting with this character would be ignored. +# * arguments: is set of words separated by spaces that can later be parsed +# * board: represent a workspace, the first line is the dimensions of the board width x height (wxh) +# There are different characters on the board that represent different things: +# * x: The x character represents spaces that would be ignored, for example it can be used in +# the first row if we don't know how wide the smartspace is. +# * i: Represents an icon on the workspace, none in particular just an icon +# * [a-z]: Represents a widget and it can be any number or character +# except any other already in use. The whole continuos are of the same character is the +# area of the widget. +# * [A-Z]: Represents a folder and number of icons in the folder is represented by the order of +# letter in the alphabet, A=2, B=3, C=4 ... etc. +# Test are parsed by CellLayoutTestCaseReader.java and boards are parsed by CellLayoutBoard.java +################################################################################################### +# 5x5 Test +board: 5x5 +xxxxx|aaaaa +--mm-|plllh +--mm-|piiih +ggggg|piiih +ggggg|fffff +arguments: 7 1 +board: 10x5 +xxxxx|aaaaa +--lll|p-mmh +---ii|pimmh +ggggg|piiih +ggggg|fffff +# 4x4 Test +board: 4x4 +xxxx|aaaa +--mm|pllh +--mm|piih +gggg|ffff +arguments: 5 1 +board: 8x4 +xxxx|aaaa +--ll|pmmh +--ii|pmmh +gggg|ffff +# 6x5 Test +board: 6x5 +xxxxxx|aaaaaa +--mmm-|pllllh +--mmm-|piiiih +--mmm-|piiiih +gggggg|ffffff +arguments: 8 1 +board: 12x5 +xxxxxx|aaaaaa +--llll|p-mmmh +---iii|pimmmh +---iii|pimmmh +gggggg|ffffff \ No newline at end of file diff --git a/tests/assets/ReorderWidgets/multiple_cell_layouts_simple_reorder b/tests/assets/ReorderWidgets/multiple_cell_layouts_simple_reorder new file mode 100644 index 0000000000..44301d29ef --- /dev/null +++ b/tests/assets/ReorderWidgets/multiple_cell_layouts_simple_reorder @@ -0,0 +1,56 @@ +################################################################################################### +# This file contains test case composed of the following tags: +# * # (coments): Lines starting with this character would be ignored. +# * arguments: is set of words separated by spaces that can later be parsed +# * board: represent a workspace, the first line is the dimensions of the board width x height (wxh) +# There are different characters on the board that represent different things: +# * x: The x character represents spaces that would be ignored, for example it can be used in +# the first row if we don't know how wide the smartspace is. +# * i: Represents an icon on the workspace, none in particular just an icon +# * [a-z]: Represents a widget and it can be any number or character +# except any other already in use. The whole continuos are of the same character is the +# area of the widget. +# * [A-Z]: Represents a folder and number of icons in the folder is represented by the order of +# letter in the alphabet, A=2, B=3, C=4 ... etc. +# Test are parsed by CellLayoutTestCaseReader.java and boards are parsed by CellLayoutBoard.java +################################################################################################### +# 5x5 Test +board: 5x5 +xxxxx|----- +--mm-|----- +--mm-|----- +-----|----- +-----|----- +arguments: 8 3 +board: 10x5 +xxxxx|----- +-----|----- +-----|----- +-----|---mm +-----|---mm +# 4x4 Test +board: 4x4 +xxxx|---- +--mm|---- +--mm|---- +----|---- +arguments: 5 3 +board: 8x4 +xxxx|---- +----|---- +----|-mm- +----|-mm- +# 6x5 Test +board: 6x5 +xxxxxx|------ +--m---|------ +------|------ +------|------ +------|------ +arguments: 10 4 +board: 12x5 +xxxxxx|------ +------|------ +------|------ +------|------ +------|----m- \ No newline at end of file diff --git a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java index 28899d9e02..ff667e60bf 100644 --- a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java +++ b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java @@ -141,9 +141,14 @@ public class CellLayoutBoard implements Comparable { return this.mType == CellType.IGNORE; } + boolean contains(int x, int y) { + return mBounds.contains(x, y); + } + @Override public String toString() { - return "WidgetRect type = " + mType + " bounds = " + mBounds.toString(); + return "WidgetRect type = " + mType + " x = " + getCellX() + " | y " + getCellY() + + " xs = " + getSpanX() + " ys = " + getSpanY(); } } @@ -227,6 +232,17 @@ public class CellLayoutBoard implements Comparable { } } + public boolean pointInsideRect(int x, int y, WidgetRect rect) { + Boolean isXInRect = x >= rect.getCellX() && x < rect.getCellX() + rect.getSpanX(); + Boolean isYInRect = y >= rect.getCellY() && y < rect.getCellY() + rect.getSpanY(); + return isXInRect && isYInRect; + } + + public WidgetRect getWidgetAt(int x, int y) { + return mWidgetsRects.stream() + .filter(widgetRect -> pointInsideRect(x, y, widgetRect)).findFirst().orElse(null); + } + public List getWidgets() { return mWidgetsRects; } @@ -443,6 +459,17 @@ public class CellLayoutBoard implements Comparable { return null; } + public static WidgetRect getWidgetIn(List boards, int x, int y) { + for (CellLayoutBoard board : boards) { + WidgetRect main = board.getWidgetAt(x, y); + if (main != null) { + return main; + } + x -= board.mWidth; + } + return null; + } + public static CellLayoutBoard boardFromString(String boardStr) { String[] lines = boardStr.split("\n"); CellLayoutBoard board = new CellLayoutBoard(); diff --git a/tests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java b/tests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java index 0d2f252b07..b6c55af47a 100644 --- a/tests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java +++ b/tests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java @@ -42,8 +42,8 @@ public class CellLayoutTestUtils { params.getCellX(), params.getCellY(), launcher.getWorkspace().getIdForScreen(cellLayout), CONTAINER_DESKTOP); int screenId = pos.screenId; - if (screenId >= boards.size() - 1) { - boards.add(new CellLayoutBoard()); + if (screenId > boards.size() - 1) { + boards.add(new CellLayoutBoard(cellLayout.getCountX(), cellLayout.getCountY())); } CellLayoutBoard board = boards.get(screenId); // is icon @@ -51,7 +51,7 @@ public class CellLayoutTestUtils { board.addIcon(pos.cellX, pos.cellY); } else { // is widget - board.addWidget(params.getCellX(), params.getCellY(), params.cellHSpan, + board.addWidget(pos.cellX, pos.cellY, params.cellHSpan, params.cellVSpan); } } diff --git a/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java b/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java deleted file mode 100644 index 706c1a7187..0000000000 --- a/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2022 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.launcher3.celllayout.testcases; - -import android.graphics.Point; - -import com.android.launcher3.celllayout.ReorderTestCase; - -import java.util.Map; - -/** - * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character - * in the board mean refer to {@code CellType} - */ -public class MultipleCellLayoutsSimpleReorder { - - /** 5x5 Test - **/ - private static final String START_BOARD_STR_5x5 = "" - + "xxxxx|-----\n" - + "--mm-|-----\n" - + "--mm-|-----\n" - + "-----|-----\n" - + "-----|-----"; - private static final Point MOVE_TO_5x5 = new Point(8, 3); - private static final String END_BOARD_STR_5x5 = "" - + "xxxxx|-----\n" - + "-----|-----\n" - + "-----|-----\n" - + "-----|---mm\n" - + "-----|---mm"; - private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5, - MOVE_TO_5x5, - END_BOARD_STR_5x5); - - /** 4x4 Test - **/ - private static final String START_BOARD_STR_4x4 = "" - + "xxxx|----\n" - + "--mm|----\n" - + "--mm|----\n" - + "----|----"; - private static final Point MOVE_TO_4x4 = new Point(5, 3); - private static final String END_BOARD_STR_4x4 = "" - + "xxxx|----\n" - + "----|----\n" - + "----|-mm-\n" - + "----|-mm-"; - private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4, - MOVE_TO_4x4, - END_BOARD_STR_4x4); - - - /** 6x5 Test - **/ - private static final String START_BOARD_STR_6x5 = "" - + "xxxxxx|------\n" - + "--m---|------\n" - + "------|------\n" - + "------|------\n" - + "------|------"; - private static final Point MOVE_TO_6x5 = new Point(10, 4); - private static final String END_BOARD_STR_6x5 = "" - + "xxxxxx|------\n" - + "------|------\n" - + "------|------\n" - + "------|------\n" - + "------|----m-"; - private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5, - MOVE_TO_6x5, - END_BOARD_STR_6x5); - - public static final Map TEST_BY_GRID_SIZE = - Map.of(new Point(5, 5), TEST_CASE_5x5, - new Point(4, 4), TEST_CASE_4x4, - new Point(6, 5), TEST_CASE_6x5); -} diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java index 7ec78bb2c9..00d7ce65e3 100644 --- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java +++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java @@ -18,20 +18,24 @@ package com.android.launcher3.celllayout; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import android.content.ContentResolver; +import android.content.ContentValues; import android.graphics.Point; +import android.net.Uri; import android.util.Log; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.celllayout.testcases.MultipleCellLayoutsSimpleReorder; +import com.android.launcher3.MultipageCellLayout; import com.android.launcher3.tapl.Widget; import com.android.launcher3.tapl.WidgetResizeFrame; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.ShellCommandRule; +import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; @@ -44,7 +48,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; @SmallTest @RunWith(AndroidJUnit4.class) @@ -55,6 +58,8 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private static final String TAG = ReorderWidgets.class.getSimpleName(); + private static final List FOLDABLE_GRIDS = List.of("normal", "practical", "reasonable"); + TestWorkspaceBuilder mWorkspaceBuilder; @Before @@ -101,8 +106,48 @@ public class ReorderWidgets extends AbstractLauncherUiTest { return getFromLauncher(CellLayoutTestUtils::workspaceToBoards); } - private void runTestCase(ReorderTestCase testCase) - throws ExecutionException, InterruptedException { + private CellLayoutBoard.WidgetRect getWidgetClosestTo(Point point) { + ArrayList workspaceBoards = workspaceToBoards(); + int maxDistance = 9999; + CellLayoutBoard.WidgetRect bestRect = null; + for (int i = 0; i < workspaceBoards.get(0).getWidgets().size(); i++) { + CellLayoutBoard.WidgetRect widget = workspaceBoards.get(0).getWidgets().get(i); + if (widget.getCellX() == 0 && widget.getCellY() == 0) { + continue; + } + int distance = Math.abs(point.x - widget.getCellX()) + + Math.abs(point.y - widget.getCellY()); + if (distance == 0) { + break; + } + if (distance < maxDistance) { + maxDistance = distance; + bestRect = widget; + } + } + return bestRect; + } + + /** + * This function might be odd, its function is to select a widget and leave it in its place. + * The idea is to make the test broader and also test after a widgets resized because the + * underlying code does different things in that case + */ + private void triggerWidgetResize(ReorderTestCase testCase) { + CellLayoutBoard.WidgetRect widgetRect = getWidgetClosestTo(testCase.moveMainTo); + if (widgetRect == null) { + // Some test doesn't have a widget in the final position, in those cases we will ignore + // them + return; + } + Widget widget = mLauncher.getWorkspace().getWidgetAtCell(widgetRect.getCellX(), + widgetRect.getCellY()); + WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(widgetRect.getCellX(), + widgetRect.getCellY(), widgetRect.getSpanX(), widgetRect.getSpanY()); + resizeFrame.dismiss(); + } + + private void runTestCase(ReorderTestCase testCase) { CellLayoutBoard.WidgetRect mainWidgetCellPos = CellLayoutBoard.getMainFromList( testCase.mStart); @@ -115,6 +160,9 @@ public class ReorderWidgets extends AbstractLauncherUiTest { // waitForLauncherCondition to wait for that condition, otherwise the condition would // always be true and it wouldn't wait for the changes to be applied. waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading()); + + triggerWidgetResize(testCase); + Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.getCellX(), mainWidgetCellPos.getCellY()); assertNotNull(widget); @@ -136,41 +184,91 @@ public class ReorderWidgets extends AbstractLauncherUiTest { * * @param testCaseMap map containing all the tests per grid size (Point) */ - private void runTestCaseMap(Map testCaseMap, String testName) - throws ExecutionException, InterruptedException { + private boolean runTestCaseMap(Map testCaseMap, String testName) { Point iconGridDimensions = mLauncher.getWorkspace().getIconGridDimensions(); Log.d(TAG, "Running test " + testName + " for grid " + iconGridDimensions); - Assume.assumeTrue( - "The test " + testName + " doesn't support " + iconGridDimensions + " grid layout", - testCaseMap.containsKey(iconGridDimensions)); + if (!testCaseMap.containsKey(iconGridDimensions)) { + Log.d(TAG, "The test " + testName + " doesn't support " + iconGridDimensions + + " grid layout"); + return false; + } runTestCase(testCaseMap.get(iconGridDimensions)); + + return true; + } + + private void runTestCaseMapForAllGrids(Map testCaseMap, + String testName) { + boolean runAtLeastOnce = false; + for (String grid : FOLDABLE_GRIDS) { + applyGridOption(grid); + mLauncher.waitForLauncherInitialized(); + runAtLeastOnce |= runTestCaseMap(testCaseMap, testName); + } + Assume.assumeTrue("None of the grids are supported", runAtLeastOnce); + } + + private void applyGridOption(Object argValue) { + String testProviderAuthority = mTargetContext.getPackageName() + ".grid_control"; + Uri gridUri = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(testProviderAuthority) + .appendPath("default_grid") + .build(); + ContentValues values = new ContentValues(); + values.putObject("name", argValue); + Assert.assertEquals(1, + mTargetContext.getContentResolver().update(gridUri, values, null, null)); } @Test public void simpleReorder() throws Exception { - runTestCaseMap(getTestMap("ReorderWidgets/simple_reorder_case"), "push_reorder_case"); + runTestCaseMap(getTestMap("ReorderWidgets/simple_reorder_case"), + "push_reorder_case"); } @Test public void pushTest() throws Exception { - runTestCaseMap(getTestMap("ReorderWidgets/push_reorder_case"), "push_reorder_case"); + runTestCaseMap(getTestMap("ReorderWidgets/push_reorder_case"), + "push_reorder_case"); } @Test public void fullReorder() throws Exception { - runTestCaseMap(getTestMap("ReorderWidgets/full_reorder_case"), "full_reorder_case"); + runTestCaseMap(getTestMap("ReorderWidgets/full_reorder_case"), + "full_reorder_case"); } @Test public void moveOutReorder() throws Exception { - runTestCaseMap(getTestMap("ReorderWidgets/move_out_reorder_case"), "move_out_reorder_case"); + runTestCaseMap(getTestMap("ReorderWidgets/move_out_reorder_case"), + "move_out_reorder_case"); } @Test - public void multipleCellLayoutsSimpleReorder() throws ExecutionException, InterruptedException { - Assume.assumeTrue("Test doesn't support foldables", !mLauncher.isTwoPanels()); - runTestCaseMap(MultipleCellLayoutsSimpleReorder.TEST_BY_GRID_SIZE, - MultipleCellLayoutsSimpleReorder.class.getSimpleName()); + public void multipleCellLayoutsSimpleReorder() throws Exception { + Assume.assumeTrue("Test doesn't support foldables", getFromLauncher( + l -> l.getWorkspace().getScreenWithId(0) instanceof MultipageCellLayout)); + runTestCaseMapForAllGrids(getTestMap("ReorderWidgets/multiple_cell_layouts_simple_reorder"), + "multiple_cell_layouts_simple_reorder"); + } + + @Test + public void multipleCellLayoutsNoSpaceReorder() throws Exception { + Assume.assumeTrue("Test doesn't support foldables", getFromLauncher( + l -> l.getWorkspace().getScreenWithId(0) instanceof MultipageCellLayout)); + runTestCaseMapForAllGrids( + getTestMap("ReorderWidgets/multiple_cell_layouts_no_space_reorder"), + "multiple_cell_layouts_no_space_reorder"); + } + + @Test + public void multipleCellLayoutsReorderToOtherSide() throws Exception { + Assume.assumeTrue("Test doesn't support foldables", getFromLauncher( + l -> l.getWorkspace().getScreenWithId(0) instanceof MultipageCellLayout)); + runTestCaseMapForAllGrids( + getTestMap("ReorderWidgets/multiple_cell_layouts_reorder_other_side"), + "multiple_cell_layouts_reorder_other_side"); } private void addTestCase(Iterator sections, @@ -183,7 +281,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { ((CellLayoutTestCaseReader.Board) sections.next()); Point moveTo = new Point(Integer.parseInt(point.arguments[0]), Integer.parseInt(point.arguments[1])); - testCaseMap.put(startBoard.gridSize, + testCaseMap.put(endBoard.gridSize, new ReorderTestCase(startBoard.board, moveTo, endBoard.board)); }