Loading tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java +102 −24 Original line number Diff line number Diff line Loading @@ -30,39 +30,117 @@ import java.util.Set; public class CellLayoutBoard { public static class CellType { // The cells marked by this will be filled by 1x1 widgets and will be ignored when // validating public static final char IGNORE = 'x'; // The cells marked by this will be filled by app icons public static final char ICON = 'i'; // Empty space public static final char EMPTY = '-'; // Widget that will be saved as "main widget" for easier retrieval public static final char MAIN_WIDGET = 'm'; // Everything else will be consider a widget } public static class WidgetRect { public char mType; public Rect mBounds; WidgetRect(char type, Rect bounds) { this.mType = type; this.mBounds = bounds; } int getSpanX() { return mBounds.right - mBounds.left + 1; } int getSpanY() { return mBounds.top - mBounds.bottom + 1; } int getCellX() { return mBounds.left; } int getCellY() { return mBounds.bottom; } boolean shouldIgnore() { return this.mType == CellType.IGNORE; } @Override public String toString() { return "WidgetRect type = " + mType + " bounds = " + mBounds.toString(); } } public static class IconPoint { public Point coord; public char mType; public IconPoint(Point coord, char type) { this.coord = coord; mType = type; } public char getType() { return mType; } public void setType(char type) { mType = type; } public Point getCoord() { return coord; } public void setCoord(Point coord) { this.coord = coord; } } static final int INFINITE = 99999; char[][] mBoard = new char[30][30]; char[][] mWidget = new char[30][30]; List<TestBoardWidget> mWidgetsRects = new ArrayList<>(); Map<Character, TestBoardWidget> mWidgetsMap = new HashMap<>(); List<WidgetRect> mWidgetsRects = new ArrayList<>(); Map<Character, WidgetRect> mWidgetsMap = new HashMap<>(); List<TestBoardAppIcon> mIconPoints = new ArrayList<>(); Map<Character, TestBoardAppIcon> mIconsMap = new HashMap<>(); List<IconPoint> mIconPoints = new ArrayList<>(); Map<Character, IconPoint> mIconsMap = new HashMap<>(); Point mMain = new Point(); CellLayoutBoard() { for (int x = 0; x < mBoard.length; x++) { for (int y = 0; y < mBoard[0].length; y++) { mBoard[x][y] = '-'; for (int x = 0; x < mWidget.length; x++) { for (int y = 0; y < mWidget[0].length; y++) { mWidget[x][y] = CellType.EMPTY; } } } public List<TestBoardWidget> getWidgets() { public List<WidgetRect> getWidgets() { return mWidgetsRects; } public List<IconPoint> getIcons() { return mIconPoints; } public Point getMain() { return mMain; } public TestBoardWidget getWidgetRect(char c) { public WidgetRect getWidgetRect(char c) { return mWidgetsMap.get(c); } public static TestBoardWidget getWidgetRect(int x, int y, Set<Point> used, char[][] board) { public static WidgetRect getWidgetRect(int x, int y, Set<Point> used, char[][] board) { char type = board[x][y]; Queue<Point> search = new ArrayDeque<Point>(); Point current = new Point(x, y); Loading Loading @@ -91,20 +169,20 @@ public class CellLayoutBoard { } } } return new TestBoardWidget(type, widgetRect); return new WidgetRect(type, widgetRect); } public static boolean isWidget(char type) { return type != 'i' && type != '-'; return type != CellType.ICON && type != CellType.EMPTY; } public static boolean isIcon(char type) { return type == 'i'; return type == CellType.ICON; } private static List<TestBoardWidget> getRects(char[][] board) { private static List<WidgetRect> getRects(char[][] board) { Set<Point> used = new HashSet<>(); List<TestBoardWidget> widgetsRects = new ArrayList<>(); List<WidgetRect> widgetsRects = new ArrayList<>(); for (int x = 0; x < board.length; x++) { for (int y = 0; y < board[0].length; y++) { if (!used.contains(new Point(x, y)) && isWidget(board[x][y])) { Loading @@ -115,12 +193,12 @@ public class CellLayoutBoard { return widgetsRects; } private static List<TestBoardAppIcon> getIconPoints(char[][] board) { List<TestBoardAppIcon> iconPoints = new ArrayList<>(); private static List<IconPoint> getIconPoints(char[][] board) { List<IconPoint> iconPoints = new ArrayList<>(); for (int x = 0; x < board.length; x++) { for (int y = 0; y < board[0].length; y++) { if (isIcon(board[x][y])) { iconPoints.add(new TestBoardAppIcon(new Point(x, y), board[x][y])); iconPoints.add(new IconPoint(new Point(x, y), board[x][y])); } } } Loading @@ -135,18 +213,18 @@ public class CellLayoutBoard { String line = lines[y]; for (int x = 0; x < line.length(); x++) { char c = line.charAt(x); if (c == 'm') { if (c == CellType.MAIN_WIDGET) { board.mMain = new Point(x, y); } if (c != '-') { board.mBoard[x][y] = line.charAt(x); if (c != CellType.EMPTY) { board.mWidget[x][y] = line.charAt(x); } } } board.mWidgetsRects = getRects(board.mBoard); board.mWidgetsRects = getRects(board.mWidget); board.mWidgetsRects.forEach( widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect)); board.mIconPoints = getIconPoints(board.mBoard); board.mIconPoints = getIconPoints(board.mWidget); return board; } } tests/src/com/android/launcher3/celllayout/ReorderWidgets.java +24 −57 Original line number Diff line number Diff line Loading @@ -15,16 +15,13 @@ */ package com.android.launcher3.celllayout; import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.graphics.Point; import android.graphics.Rect; import android.util.Log; import android.view.View; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -34,13 +31,14 @@ import com.android.launcher3.celllayout.testcases.MoveOutReorderCase; import com.android.launcher3.celllayout.testcases.PushReorderCase; import com.android.launcher3.celllayout.testcases.ReorderTestCase; import com.android.launcher3.celllayout.testcases.SimpleReorderCase; import com.android.launcher3.model.data.LauncherAppWidgetInfo; 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.ui.TestViewHelpers; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.views.DoubleShadowBubbleTextView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import org.junit.Assume; import org.junit.Before; Loading @@ -60,6 +58,8 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private static final String TAG = ReorderWidgets.class.getSimpleName(); TestWorkspaceBuilder mBoardBuilder; private View getViewAt(int cellX, int cellY) { return getFromLauncher(l -> l.getWorkspace().getScreenWithId( l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY)); Loading @@ -76,6 +76,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { @Before public void setup() throws Throwable { mBoardBuilder = new TestWorkspaceBuilder(this); TaplTestsLauncher3.initialize(this); clearHomescreen(); } Loading @@ -86,78 +87,44 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private boolean validateBoard(CellLayoutBoard board) { boolean match = true; Point cellDimensions = getCellDimensions(); for (TestBoardWidget widgetRect: board.getWidgets()) { for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) { if (widgetRect.shouldIgnore()) { continue; } View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY()); assertTrue("The view selected at " + board + " is not a widget", widget instanceof LauncherAppWidgetHostView); match &= widgetRect.getSpanX() == Math.round(widget.getWidth() / (float) cellDimensions.x); match &= widgetRect.getSpanY() == Math.round(widget.getHeight() / (float) cellDimensions.y); if (!match) return match; } return match; } /** * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases. */ private void fillWithWidgets(TestBoardWidget widgetRect) { int initX = widgetRect.getCellX(); int initY = widgetRect.getCellY(); for (int x = 0; x < widgetRect.getSpanX(); x++) { for (int y = 0; y < widgetRect.getSpanY(); y++) { int auxX = initX + x; int auxY = initY + y; try { // this widgets are filling, we don't care if we can't place them addWidgetInCell( new TestBoardWidget('x', new Rect(auxX, auxY, auxX, auxY)) ); } catch (Exception e) { Log.d(TAG, "Unable to place filling widget at " + auxX + "," + auxY); } } } } private void addWidgetInCell(TestBoardWidget widgetRect) { LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false); LauncherAppWidgetInfo item = createWidgetInfo(info, ApplicationProvider.getApplicationContext(), true); item.cellX = widgetRect.getCellX(); item.cellY = widgetRect.getCellY(); item.spanX = widgetRect.getSpanX(); item.spanY = widgetRect.getSpanY(); addItemToScreen(item); } private void addCorrespondingWidgetRect(TestBoardWidget widgetRect) { if (widgetRect.mType == 'x') { fillWithWidgets(widgetRect); } else { addWidgetInCell(widgetRect); for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) { View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y); assertTrue("The view selected at " + iconPoint.coord + " is not an Icon", icon instanceof DoubleShadowBubbleTextView); } return match; } private void runTestCase(ReorderTestCase testCase) { Point mainWidgetCellPos = testCase.mStart.getMain(); testCase.mStart.getWidgets().forEach(this::addCorrespondingWidgetRect); mBoardBuilder.buildBoard(testCase.mStart); mLauncher.getWorkspace() .getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y) .dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y) .dismiss(); // dismiss resize frame Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y); assertNotNull(widget); WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y); resizeFrame.dismiss(); boolean isValid = false; for (CellLayoutBoard board : testCase.mEnd) { isValid |= validateBoard(board); } assertTrue("None of the valid boards match with the current state", isValid); assertTrue("Non of the valid boards match with the current state", isValid); } /** Loading tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * 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; import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; import android.content.ComponentName; import android.graphics.Rect; import android.os.Process; import android.os.UserHandle; import android.util.Log; import androidx.test.core.app.ApplicationProvider; import com.android.launcher3.LauncherSettings; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; public class TestWorkspaceBuilder { private static final ComponentName APP_COMPONENT_NAME = new ComponentName( "com.google.android.calculator", "com.android.calculator2.Calculator"); public AbstractLauncherUiTest mTest; private UserHandle mMyUser; public TestWorkspaceBuilder(AbstractLauncherUiTest test) { mTest = test; mMyUser = Process.myUserHandle(); } private static final String TAG = "CellLayoutBoardBuilder"; /** * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases. */ private void fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect) { int initX = widgetRect.getCellX(); int initY = widgetRect.getCellY(); for (int x = initX; x < initX + widgetRect.getSpanX(); x++) { for (int y = initY; y < initY + widgetRect.getSpanY(); y++) { try { // this widgets are filling, we don't care if we can't place them addWidgetInCell( new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE, new Rect(x, y, x, y)) ); } catch (Exception e) { Log.d(TAG, "Unable to place filling widget at " + x + "," + y); } } } } private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) { LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false); LauncherAppWidgetInfo item = createWidgetInfo(info, ApplicationProvider.getApplicationContext(), true); item.cellX = widgetRect.getCellX(); item.cellY = widgetRect.getCellY(); item.spanX = widgetRect.getSpanX(); item.spanY = widgetRect.getSpanY(); mTest.addItemToScreen(item); } private void addIconInCell(CellLayoutBoard.IconPoint iconPoint) { AppInfo appInfo = new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser, AppInfo.makeLaunchIntent(APP_COMPONENT_NAME)); appInfo.cellX = iconPoint.getCoord().x; appInfo.cellY = iconPoint.getCoord().y; appInfo.minSpanY = appInfo.minSpanX = appInfo.spanX = appInfo.spanY = 1; appInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; appInfo.componentName = APP_COMPONENT_NAME; mTest.addItemToScreen(new WorkspaceItemInfo(appInfo)); } private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect) { if (widgetRect.mType == 'x') { fillWithWidgets(widgetRect); } else { addWidgetInCell(widgetRect); } } public void buildBoard(CellLayoutBoard board) { board.getWidgets().forEach(this::addCorrespondingWidgetRect); board.getIcons().forEach(this::addIconInCell); } } tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.graphics.Point; 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 FullReorderCase { /** 5x5 Test Loading tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.graphics.Point; 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 MoveOutReorderCase { /** 5x5 Test Loading Loading
tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java +102 −24 Original line number Diff line number Diff line Loading @@ -30,39 +30,117 @@ import java.util.Set; public class CellLayoutBoard { public static class CellType { // The cells marked by this will be filled by 1x1 widgets and will be ignored when // validating public static final char IGNORE = 'x'; // The cells marked by this will be filled by app icons public static final char ICON = 'i'; // Empty space public static final char EMPTY = '-'; // Widget that will be saved as "main widget" for easier retrieval public static final char MAIN_WIDGET = 'm'; // Everything else will be consider a widget } public static class WidgetRect { public char mType; public Rect mBounds; WidgetRect(char type, Rect bounds) { this.mType = type; this.mBounds = bounds; } int getSpanX() { return mBounds.right - mBounds.left + 1; } int getSpanY() { return mBounds.top - mBounds.bottom + 1; } int getCellX() { return mBounds.left; } int getCellY() { return mBounds.bottom; } boolean shouldIgnore() { return this.mType == CellType.IGNORE; } @Override public String toString() { return "WidgetRect type = " + mType + " bounds = " + mBounds.toString(); } } public static class IconPoint { public Point coord; public char mType; public IconPoint(Point coord, char type) { this.coord = coord; mType = type; } public char getType() { return mType; } public void setType(char type) { mType = type; } public Point getCoord() { return coord; } public void setCoord(Point coord) { this.coord = coord; } } static final int INFINITE = 99999; char[][] mBoard = new char[30][30]; char[][] mWidget = new char[30][30]; List<TestBoardWidget> mWidgetsRects = new ArrayList<>(); Map<Character, TestBoardWidget> mWidgetsMap = new HashMap<>(); List<WidgetRect> mWidgetsRects = new ArrayList<>(); Map<Character, WidgetRect> mWidgetsMap = new HashMap<>(); List<TestBoardAppIcon> mIconPoints = new ArrayList<>(); Map<Character, TestBoardAppIcon> mIconsMap = new HashMap<>(); List<IconPoint> mIconPoints = new ArrayList<>(); Map<Character, IconPoint> mIconsMap = new HashMap<>(); Point mMain = new Point(); CellLayoutBoard() { for (int x = 0; x < mBoard.length; x++) { for (int y = 0; y < mBoard[0].length; y++) { mBoard[x][y] = '-'; for (int x = 0; x < mWidget.length; x++) { for (int y = 0; y < mWidget[0].length; y++) { mWidget[x][y] = CellType.EMPTY; } } } public List<TestBoardWidget> getWidgets() { public List<WidgetRect> getWidgets() { return mWidgetsRects; } public List<IconPoint> getIcons() { return mIconPoints; } public Point getMain() { return mMain; } public TestBoardWidget getWidgetRect(char c) { public WidgetRect getWidgetRect(char c) { return mWidgetsMap.get(c); } public static TestBoardWidget getWidgetRect(int x, int y, Set<Point> used, char[][] board) { public static WidgetRect getWidgetRect(int x, int y, Set<Point> used, char[][] board) { char type = board[x][y]; Queue<Point> search = new ArrayDeque<Point>(); Point current = new Point(x, y); Loading Loading @@ -91,20 +169,20 @@ public class CellLayoutBoard { } } } return new TestBoardWidget(type, widgetRect); return new WidgetRect(type, widgetRect); } public static boolean isWidget(char type) { return type != 'i' && type != '-'; return type != CellType.ICON && type != CellType.EMPTY; } public static boolean isIcon(char type) { return type == 'i'; return type == CellType.ICON; } private static List<TestBoardWidget> getRects(char[][] board) { private static List<WidgetRect> getRects(char[][] board) { Set<Point> used = new HashSet<>(); List<TestBoardWidget> widgetsRects = new ArrayList<>(); List<WidgetRect> widgetsRects = new ArrayList<>(); for (int x = 0; x < board.length; x++) { for (int y = 0; y < board[0].length; y++) { if (!used.contains(new Point(x, y)) && isWidget(board[x][y])) { Loading @@ -115,12 +193,12 @@ public class CellLayoutBoard { return widgetsRects; } private static List<TestBoardAppIcon> getIconPoints(char[][] board) { List<TestBoardAppIcon> iconPoints = new ArrayList<>(); private static List<IconPoint> getIconPoints(char[][] board) { List<IconPoint> iconPoints = new ArrayList<>(); for (int x = 0; x < board.length; x++) { for (int y = 0; y < board[0].length; y++) { if (isIcon(board[x][y])) { iconPoints.add(new TestBoardAppIcon(new Point(x, y), board[x][y])); iconPoints.add(new IconPoint(new Point(x, y), board[x][y])); } } } Loading @@ -135,18 +213,18 @@ public class CellLayoutBoard { String line = lines[y]; for (int x = 0; x < line.length(); x++) { char c = line.charAt(x); if (c == 'm') { if (c == CellType.MAIN_WIDGET) { board.mMain = new Point(x, y); } if (c != '-') { board.mBoard[x][y] = line.charAt(x); if (c != CellType.EMPTY) { board.mWidget[x][y] = line.charAt(x); } } } board.mWidgetsRects = getRects(board.mBoard); board.mWidgetsRects = getRects(board.mWidget); board.mWidgetsRects.forEach( widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect)); board.mIconPoints = getIconPoints(board.mBoard); board.mIconPoints = getIconPoints(board.mWidget); return board; } }
tests/src/com/android/launcher3/celllayout/ReorderWidgets.java +24 −57 Original line number Diff line number Diff line Loading @@ -15,16 +15,13 @@ */ package com.android.launcher3.celllayout; import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.graphics.Point; import android.graphics.Rect; import android.util.Log; import android.view.View; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -34,13 +31,14 @@ import com.android.launcher3.celllayout.testcases.MoveOutReorderCase; import com.android.launcher3.celllayout.testcases.PushReorderCase; import com.android.launcher3.celllayout.testcases.ReorderTestCase; import com.android.launcher3.celllayout.testcases.SimpleReorderCase; import com.android.launcher3.model.data.LauncherAppWidgetInfo; 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.ui.TestViewHelpers; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.views.DoubleShadowBubbleTextView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import org.junit.Assume; import org.junit.Before; Loading @@ -60,6 +58,8 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private static final String TAG = ReorderWidgets.class.getSimpleName(); TestWorkspaceBuilder mBoardBuilder; private View getViewAt(int cellX, int cellY) { return getFromLauncher(l -> l.getWorkspace().getScreenWithId( l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY)); Loading @@ -76,6 +76,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { @Before public void setup() throws Throwable { mBoardBuilder = new TestWorkspaceBuilder(this); TaplTestsLauncher3.initialize(this); clearHomescreen(); } Loading @@ -86,78 +87,44 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private boolean validateBoard(CellLayoutBoard board) { boolean match = true; Point cellDimensions = getCellDimensions(); for (TestBoardWidget widgetRect: board.getWidgets()) { for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) { if (widgetRect.shouldIgnore()) { continue; } View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY()); assertTrue("The view selected at " + board + " is not a widget", widget instanceof LauncherAppWidgetHostView); match &= widgetRect.getSpanX() == Math.round(widget.getWidth() / (float) cellDimensions.x); match &= widgetRect.getSpanY() == Math.round(widget.getHeight() / (float) cellDimensions.y); if (!match) return match; } return match; } /** * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases. */ private void fillWithWidgets(TestBoardWidget widgetRect) { int initX = widgetRect.getCellX(); int initY = widgetRect.getCellY(); for (int x = 0; x < widgetRect.getSpanX(); x++) { for (int y = 0; y < widgetRect.getSpanY(); y++) { int auxX = initX + x; int auxY = initY + y; try { // this widgets are filling, we don't care if we can't place them addWidgetInCell( new TestBoardWidget('x', new Rect(auxX, auxY, auxX, auxY)) ); } catch (Exception e) { Log.d(TAG, "Unable to place filling widget at " + auxX + "," + auxY); } } } } private void addWidgetInCell(TestBoardWidget widgetRect) { LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false); LauncherAppWidgetInfo item = createWidgetInfo(info, ApplicationProvider.getApplicationContext(), true); item.cellX = widgetRect.getCellX(); item.cellY = widgetRect.getCellY(); item.spanX = widgetRect.getSpanX(); item.spanY = widgetRect.getSpanY(); addItemToScreen(item); } private void addCorrespondingWidgetRect(TestBoardWidget widgetRect) { if (widgetRect.mType == 'x') { fillWithWidgets(widgetRect); } else { addWidgetInCell(widgetRect); for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) { View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y); assertTrue("The view selected at " + iconPoint.coord + " is not an Icon", icon instanceof DoubleShadowBubbleTextView); } return match; } private void runTestCase(ReorderTestCase testCase) { Point mainWidgetCellPos = testCase.mStart.getMain(); testCase.mStart.getWidgets().forEach(this::addCorrespondingWidgetRect); mBoardBuilder.buildBoard(testCase.mStart); mLauncher.getWorkspace() .getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y) .dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y) .dismiss(); // dismiss resize frame Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y); assertNotNull(widget); WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y); resizeFrame.dismiss(); boolean isValid = false; for (CellLayoutBoard board : testCase.mEnd) { isValid |= validateBoard(board); } assertTrue("None of the valid boards match with the current state", isValid); assertTrue("Non of the valid boards match with the current state", isValid); } /** Loading
tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * 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; import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; import android.content.ComponentName; import android.graphics.Rect; import android.os.Process; import android.os.UserHandle; import android.util.Log; import androidx.test.core.app.ApplicationProvider; import com.android.launcher3.LauncherSettings; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; public class TestWorkspaceBuilder { private static final ComponentName APP_COMPONENT_NAME = new ComponentName( "com.google.android.calculator", "com.android.calculator2.Calculator"); public AbstractLauncherUiTest mTest; private UserHandle mMyUser; public TestWorkspaceBuilder(AbstractLauncherUiTest test) { mTest = test; mMyUser = Process.myUserHandle(); } private static final String TAG = "CellLayoutBoardBuilder"; /** * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases. */ private void fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect) { int initX = widgetRect.getCellX(); int initY = widgetRect.getCellY(); for (int x = initX; x < initX + widgetRect.getSpanX(); x++) { for (int y = initY; y < initY + widgetRect.getSpanY(); y++) { try { // this widgets are filling, we don't care if we can't place them addWidgetInCell( new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE, new Rect(x, y, x, y)) ); } catch (Exception e) { Log.d(TAG, "Unable to place filling widget at " + x + "," + y); } } } } private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) { LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false); LauncherAppWidgetInfo item = createWidgetInfo(info, ApplicationProvider.getApplicationContext(), true); item.cellX = widgetRect.getCellX(); item.cellY = widgetRect.getCellY(); item.spanX = widgetRect.getSpanX(); item.spanY = widgetRect.getSpanY(); mTest.addItemToScreen(item); } private void addIconInCell(CellLayoutBoard.IconPoint iconPoint) { AppInfo appInfo = new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser, AppInfo.makeLaunchIntent(APP_COMPONENT_NAME)); appInfo.cellX = iconPoint.getCoord().x; appInfo.cellY = iconPoint.getCoord().y; appInfo.minSpanY = appInfo.minSpanX = appInfo.spanX = appInfo.spanY = 1; appInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; appInfo.componentName = APP_COMPONENT_NAME; mTest.addItemToScreen(new WorkspaceItemInfo(appInfo)); } private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect) { if (widgetRect.mType == 'x') { fillWithWidgets(widgetRect); } else { addWidgetInCell(widgetRect); } } public void buildBoard(CellLayoutBoard board) { board.getWidgets().forEach(this::addCorrespondingWidgetRect); board.getIcons().forEach(this::addIconInCell); } }
tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.graphics.Point; 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 FullReorderCase { /** 5x5 Test Loading
tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.graphics.Point; 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 MoveOutReorderCase { /** 5x5 Test Loading