diff --git a/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java new file mode 100644 index 0000000000..8ce932d281 --- /dev/null +++ b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java @@ -0,0 +1,76 @@ +/* + * 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.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; + +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.ui.AbstractLauncherUiTest; +import com.android.launcher3.util.ContentWriter; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class FavoriteItemsTransaction { + private ArrayList mItemsToSubmit; + private Context mContext; + private ContentResolver mResolver; + public AbstractLauncherUiTest mTest; + + public FavoriteItemsTransaction(Context context, AbstractLauncherUiTest test) { + mItemsToSubmit = new ArrayList<>(); + mContext = context; + mResolver = mContext.getContentResolver(); + mTest = test; + } + + public FavoriteItemsTransaction addItem(ItemInfo itemInfo) { + this.mItemsToSubmit.add(itemInfo); + return this; + } + + public FavoriteItemsTransaction removeLast() { + this.mItemsToSubmit.remove(this.mItemsToSubmit.size() - 1); + return this; + } + + /** + * Commits all the ItemInfo into the database of Favorites + **/ + public void commit() throws ExecutionException, InterruptedException { + List values = new ArrayList<>(); + for (ItemInfo item : this.mItemsToSubmit) { + ContentWriter writer = new ContentWriter(mContext); + item.onAddToDatabase(writer); + writer.put(LauncherSettings.Favorites._ID, item.id); + values.add(writer.getValues(mContext)); + } + // Submit the icons to the database in the model thread to prevent race conditions + MODEL_EXECUTOR.submit(() -> mResolver.bulkInsert(LauncherSettings.Favorites.CONTENT_URI, + values.toArray(new ContentValues[0]))).get(); + // Reload the state of the Launcher + MAIN_EXECUTOR.submit(() -> LauncherAppState.getInstance( + mContext).getModel().forceReload()).get(); + } +} diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java index 93fbf97e99..2846cae1e8 100644 --- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java +++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java @@ -47,6 +47,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.util.Map; +import java.util.concurrent.ExecutionException; @SmallTest @@ -58,7 +59,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private static final String TAG = ReorderWidgets.class.getSimpleName(); - TestWorkspaceBuilder mBoardBuilder; + TestWorkspaceBuilder mWorkspaceBuilder; private View getViewAt(int cellX, int cellY) { return getFromLauncher(l -> l.getWorkspace().getScreenWithId( @@ -76,7 +77,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { @Before public void setup() throws Throwable { - mBoardBuilder = new TestWorkspaceBuilder(this); + mWorkspaceBuilder = new TestWorkspaceBuilder(this, mTargetContext); TaplTestsLauncher3.initialize(this); clearHomescreen(); } @@ -87,7 +88,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest { private boolean validateBoard(CellLayoutBoard board) { boolean match = true; Point cellDimensions = getCellDimensions(); - for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) { + for (CellLayoutBoard.WidgetRect widgetRect : board.getWidgets()) { if (widgetRect.shouldIgnore()) { continue; } @@ -108,10 +109,13 @@ public class ReorderWidgets extends AbstractLauncherUiTest { return match; } - private void runTestCase(ReorderTestCase testCase) { + private void runTestCase(ReorderTestCase testCase) + throws ExecutionException, InterruptedException { Point mainWidgetCellPos = testCase.mStart.getMain(); - mBoardBuilder.buildBoard(testCase.mStart); + FavoriteItemsTransaction transaction = + new FavoriteItemsTransaction(mTargetContext, this); + mWorkspaceBuilder.buildFromBoard(testCase.mStart, transaction).commit(); Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y); @@ -132,7 +136,8 @@ public class ReorderWidgets extends AbstractLauncherUiTest { * * @param testCaseMap map containing all the tests per grid size (Point) */ - private void runTestCaseMap(Map testCaseMap, String testName) { + private void runTestCaseMap(Map testCaseMap, String testName) + throws ExecutionException, InterruptedException { Point iconGridDimensions = mLauncher.getWorkspace().getIconGridDimensions(); Log.d(TAG, "Running test " + testName + " for grid " + iconGridDimensions); Assume.assumeTrue( @@ -143,26 +148,26 @@ public class ReorderWidgets extends AbstractLauncherUiTest { @ScreenRecord // b/242323136 @Test - public void simpleReorder() { + public void simpleReorder() throws ExecutionException, InterruptedException { runTestCaseMap(SimpleReorderCase.TEST_BY_GRID_SIZE, SimpleReorderCase.class.getSimpleName()); } @ScreenRecord // b/242323136 @Test - public void pushTest() { + public void pushTest() throws ExecutionException, InterruptedException { runTestCaseMap(PushReorderCase.TEST_BY_GRID_SIZE, PushReorderCase.class.getSimpleName()); } @ScreenRecord // b/242323136 @Test - public void fullReorder() { + public void fullReorder() throws ExecutionException, InterruptedException { runTestCaseMap(FullReorderCase.TEST_BY_GRID_SIZE, FullReorderCase.class.getSimpleName()); } @ScreenRecord // b/242323136 @Test - public void moveOutReorder() { + public void moveOutReorder() throws ExecutionException, InterruptedException { runTestCaseMap(MoveOutReorderCase.TEST_BY_GRID_SIZE, MoveOutReorderCase.class.getSimpleName()); } diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java index 10e399dfd5..16448afda0 100644 --- a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java +++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java @@ -15,9 +15,12 @@ */ package com.android.launcher3.celllayout; +import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID; import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; import android.graphics.Rect; import android.os.Process; import android.os.UserHandle; @@ -25,8 +28,10 @@ import android.util.Log; import androidx.test.core.app.ApplicationProvider; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherSettings; import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.ui.AbstractLauncherUiTest; @@ -35,6 +40,7 @@ import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; public class TestWorkspaceBuilder { + private static final String TAG = "CellLayoutBoardBuilder"; private static final ComponentName APP_COMPONENT_NAME = new ComponentName( "com.google.android.calculator", "com.android.calculator2.Calculator"); @@ -42,69 +48,118 @@ public class TestWorkspaceBuilder { private UserHandle mMyUser; - public TestWorkspaceBuilder(AbstractLauncherUiTest test) { + private Context mContext; + private ContentResolver mResolver; + + public TestWorkspaceBuilder(AbstractLauncherUiTest test, Context context) { mTest = test; mMyUser = Process.myUserHandle(); + mContext = context; + mResolver = mContext.getContentResolver(); } - 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) { + private FavoriteItemsTransaction fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect, + FavoriteItemsTransaction transaction) { 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( + ItemInfo item = createWidgetInCell( new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE, new Rect(x, y, x, y)) ); + transaction.addItem(item); } catch (Exception e) { Log.d(TAG, "Unable to place filling widget at " + x + "," + y); } } } + return transaction; } - private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) { + private int getID() { + return LauncherSettings.Settings.call( + mResolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID) + .getInt(LauncherSettings.Settings.EXTRA_VALUE); + } + + private AppInfo getApp() { + return new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser, + AppInfo.makeLaunchIntent(APP_COMPONENT_NAME)); + } + + private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect, + FavoriteItemsTransaction transaction) { + if (widgetRect.mType == 'x') { + fillWithWidgets(widgetRect, transaction); + } else { + transaction.addItem(createWidgetInCell(widgetRect)); + } + } + + /** + * Builds the given board into the transaction + */ + public FavoriteItemsTransaction buildFromBoard(CellLayoutBoard board, + FavoriteItemsTransaction transaction) { + board.getWidgets().forEach( + (widgetRect) -> addCorrespondingWidgetRect(widgetRect, transaction)); + board.getIcons().forEach((iconPoint) -> + transaction.addItem(createIconInCell(iconPoint)) + ); + return transaction; + } + + /** + * Fills the hotseat row with apps instead of suggestions, for this to work the workspace should + * be clean otherwise this doesn't overrides the existing icons. + */ + public FavoriteItemsTransaction fillHotseatIcons(FavoriteItemsTransaction transaction) { + int hotseatCount = InvariantDeviceProfile.INSTANCE.get(mContext).numShownHotseatIcons; + for (int i = 0; i < hotseatCount; i++) { + transaction.addItem(getHotseatValues(i)); + } + return transaction; + } + + private ItemInfo createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) { LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false); LauncherAppWidgetInfo item = createWidgetInfo(info, ApplicationProvider.getApplicationContext(), true); - + item.id = getID(); item.cellX = widgetRect.getCellX(); item.cellY = widgetRect.getCellY(); item.spanX = widgetRect.getSpanX(); item.spanY = widgetRect.getSpanY(); - mTest.addItemToScreen(item); + item.screenId = FIRST_SCREEN_ID; + return 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 ItemInfo createIconInCell(CellLayoutBoard.IconPoint iconPoint) { + WorkspaceItemInfo item = new WorkspaceItemInfo(getApp()); + item.id = getID(); + item.screenId = FIRST_SCREEN_ID; + item.cellX = iconPoint.getCoord().x; + item.cellY = iconPoint.getCoord().y; + item.minSpanY = item.minSpanX = item.spanX = item.spanY = 1; + item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; + return item; } - 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); + private ItemInfo getHotseatValues(int x) { + WorkspaceItemInfo item = new WorkspaceItemInfo(getApp()); + item.id = getID(); + item.cellX = x; + item.cellY = 0; + item.minSpanY = item.minSpanX = item.spanX = item.spanY = 1; + item.rank = x; + item.screenId = x; + item.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT; + return item; } } diff --git a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java index 94e55cfbde..a98882cc7f 100644 --- a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java +++ b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java @@ -31,13 +31,13 @@ public class FullReorderCase { + "xxxxx\n" + "222mm\n" + "222mm\n" - + "ad111\n" - + "bc111"; + + "ii111\n" + + "ii111"; private static final Point MOVE_TO_5x5 = new Point(0, 4); private static final String END_BOARD_STR_5x5 = "" + "xxxxx\n" - + "222ad\n" - + "222bc\n" + + "222ii\n" + + "222ii\n" + "mm111\n" + "mm111"; private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5, @@ -50,13 +50,13 @@ public class FullReorderCase { + "xxxxxx\n" + "2222mm\n" + "2222mm\n" - + "ad1111\n" - + "bc1111"; + + "ii1111\n" + + "ii1111"; private static final Point MOVE_TO_6x5 = new Point(0, 4); private static final String END_BOARD_STR_6x5 = "" + "xxxxxx\n" - + "2222ad\n" - + "2222bc\n" + + "2222ii\n" + + "2222ii\n" + "mm1111\n" + "mm1111"; private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5, @@ -68,13 +68,13 @@ public class FullReorderCase { private static final String START_BOARD_STR_4x4 = "" + "xxxx\n" + "22mm\n" - + "admm\n" - + "bc11"; + + "iimm\n" + + "ii11"; private static final Point MOVE_TO_4x4 = new Point(0, 3); private static final String END_BOARD_STR_4x4 = "" + "xxxx\n" - + "22ad\n" - + "mmbc\n" + + "22ii\n" + + "mmii\n" + "mm11"; private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,