2016-09-09 15:47:55 -07:00
|
|
|
package com.android.launcher3.model;
|
|
|
|
|
|
2018-08-24 14:04:43 -07:00
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
|
import static org.junit.Assert.assertFalse;
|
|
|
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
|
import static org.mockito.Mockito.any;
|
|
|
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
|
|
2016-09-09 15:47:55 -07:00
|
|
|
import android.content.ComponentName;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.graphics.Rect;
|
|
|
|
|
import android.util.Pair;
|
|
|
|
|
|
|
|
|
|
import com.android.launcher3.ItemInfo;
|
|
|
|
|
import com.android.launcher3.LauncherSettings;
|
2018-12-07 11:43:47 -08:00
|
|
|
import com.android.launcher3.LauncherSettings.Favorites;
|
2019-03-27 16:03:06 -07:00
|
|
|
import com.android.launcher3.WorkspaceItemInfo;
|
2018-12-07 11:43:47 -08:00
|
|
|
import com.android.launcher3.util.ContentWriter;
|
2016-09-09 15:47:55 -07:00
|
|
|
import com.android.launcher3.util.GridOccupancy;
|
2018-10-04 15:11:00 -07:00
|
|
|
import com.android.launcher3.util.IntArray;
|
|
|
|
|
import com.android.launcher3.util.IntSparseArrayMap;
|
2016-09-09 15:47:55 -07:00
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
import org.junit.Before;
|
|
|
|
|
import org.junit.Test;
|
|
|
|
|
import org.junit.runner.RunWith;
|
2016-09-09 15:47:55 -07:00
|
|
|
import org.mockito.ArgumentCaptor;
|
2018-11-07 16:54:02 -08:00
|
|
|
import org.robolectric.RobolectricTestRunner;
|
2016-09-09 15:47:55 -07:00
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2017-05-04 16:47:11 -07:00
|
|
|
import java.util.List;
|
2018-12-07 11:43:47 -08:00
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
import java.util.concurrent.Executors;
|
2016-09-09 15:47:55 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tests for {@link AddWorkspaceItemsTask}
|
|
|
|
|
*/
|
2018-11-07 16:54:02 -08:00
|
|
|
@RunWith(RobolectricTestRunner.class)
|
2016-09-09 15:47:55 -07:00
|
|
|
public class AddWorkspaceItemsTaskTest extends BaseModelUpdateTaskTestCase {
|
|
|
|
|
|
|
|
|
|
private final ComponentName mComponent1 = new ComponentName("a", "b");
|
|
|
|
|
private final ComponentName mComponent2 = new ComponentName("b", "b");
|
|
|
|
|
|
2018-10-04 15:11:00 -07:00
|
|
|
private IntArray existingScreens;
|
|
|
|
|
private IntArray newScreens;
|
|
|
|
|
private IntSparseArrayMap<GridOccupancy> screenOccupancy;
|
2016-09-09 15:47:55 -07:00
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
@Before
|
|
|
|
|
public void initData() throws Exception {
|
2018-10-04 15:11:00 -07:00
|
|
|
existingScreens = new IntArray();
|
|
|
|
|
screenOccupancy = new IntSparseArrayMap<>();
|
|
|
|
|
newScreens = new IntArray();
|
2016-09-09 15:47:55 -07:00
|
|
|
|
|
|
|
|
idp.numColumns = 5;
|
|
|
|
|
idp.numRows = 5;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-16 09:23:42 -08:00
|
|
|
private AddWorkspaceItemsTask newTask(ItemInfo... items) {
|
2017-05-04 16:47:11 -07:00
|
|
|
List<Pair<ItemInfo, Object>> list = new ArrayList<>();
|
|
|
|
|
for (ItemInfo item : items) {
|
|
|
|
|
list.add(Pair.create(item, null));
|
|
|
|
|
}
|
2018-12-07 11:43:47 -08:00
|
|
|
return new AddWorkspaceItemsTask(list);
|
2016-09-09 15:47:55 -07:00
|
|
|
}
|
|
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
@Test
|
2018-12-07 11:43:47 -08:00
|
|
|
public void testFindSpaceForItem_prefers_second() throws Exception {
|
2016-09-09 15:47:55 -07:00
|
|
|
// First screen has only one hole of size 1
|
|
|
|
|
int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
|
|
|
|
|
|
|
|
|
|
// Second screen has 2 holes of sizes 3x2 and 2x3
|
|
|
|
|
setupWorkspaceWithHoles(nextId, 2, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
|
|
|
|
|
|
2018-10-04 15:11:00 -07:00
|
|
|
int[] spaceFound = newTask()
|
2016-09-09 15:47:55 -07:00
|
|
|
.findSpaceForItem(appState, bgDataModel, existingScreens, newScreens, 1, 1);
|
2018-10-04 15:11:00 -07:00
|
|
|
assertEquals(2, spaceFound[0]);
|
|
|
|
|
assertTrue(screenOccupancy.get(spaceFound[0])
|
|
|
|
|
.isRegionVacant(spaceFound[1], spaceFound[2], 1, 1));
|
2016-09-09 15:47:55 -07:00
|
|
|
|
|
|
|
|
// Find a larger space
|
|
|
|
|
spaceFound = newTask()
|
|
|
|
|
.findSpaceForItem(appState, bgDataModel, existingScreens, newScreens, 2, 3);
|
2018-10-04 15:11:00 -07:00
|
|
|
assertEquals(2, spaceFound[0]);
|
|
|
|
|
assertTrue(screenOccupancy.get(spaceFound[0])
|
|
|
|
|
.isRegionVacant(spaceFound[1], spaceFound[2], 2, 3));
|
2016-09-09 15:47:55 -07:00
|
|
|
}
|
|
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
@Test
|
2016-09-09 15:47:55 -07:00
|
|
|
public void testFindSpaceForItem_adds_new_screen() throws Exception {
|
|
|
|
|
// First screen has 2 holes of sizes 3x2 and 2x3
|
|
|
|
|
setupWorkspaceWithHoles(1, 1, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
|
|
|
|
|
|
2018-10-04 15:11:00 -07:00
|
|
|
IntArray oldScreens = existingScreens.clone();
|
|
|
|
|
int[] spaceFound = newTask()
|
2016-09-09 15:47:55 -07:00
|
|
|
.findSpaceForItem(appState, bgDataModel, existingScreens, newScreens, 3, 3);
|
2018-10-04 15:11:00 -07:00
|
|
|
assertFalse(oldScreens.contains(spaceFound[0]));
|
|
|
|
|
assertTrue(newScreens.contains(spaceFound[0]));
|
2016-09-09 15:47:55 -07:00
|
|
|
}
|
|
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
@Test
|
2016-09-09 15:47:55 -07:00
|
|
|
public void testAddItem_existing_item_ignored() throws Exception {
|
2019-03-27 16:03:06 -07:00
|
|
|
WorkspaceItemInfo info = new WorkspaceItemInfo();
|
2016-09-09 15:47:55 -07:00
|
|
|
info.intent = new Intent().setComponent(mComponent1);
|
|
|
|
|
|
|
|
|
|
// Setup a screen with a hole
|
|
|
|
|
setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
|
|
|
|
|
|
|
|
|
|
// Nothing was added
|
|
|
|
|
assertTrue(executeTaskForTest(newTask(info)).isEmpty());
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-06 21:09:23 -08:00
|
|
|
@Test
|
2016-09-09 15:47:55 -07:00
|
|
|
public void testAddItem_some_items_added() throws Exception {
|
2019-03-27 16:03:06 -07:00
|
|
|
WorkspaceItemInfo info = new WorkspaceItemInfo();
|
2016-09-09 15:47:55 -07:00
|
|
|
info.intent = new Intent().setComponent(mComponent1);
|
|
|
|
|
|
2019-03-27 16:03:06 -07:00
|
|
|
WorkspaceItemInfo info2 = new WorkspaceItemInfo();
|
2016-09-09 15:47:55 -07:00
|
|
|
info2.intent = new Intent().setComponent(mComponent2);
|
|
|
|
|
|
|
|
|
|
// Setup a screen with a hole
|
|
|
|
|
setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
|
|
|
|
|
|
|
|
|
|
executeTaskForTest(newTask(info, info2)).get(0).run();
|
|
|
|
|
ArgumentCaptor<ArrayList> notAnimated = ArgumentCaptor.forClass(ArrayList.class);
|
|
|
|
|
ArgumentCaptor<ArrayList> animated = ArgumentCaptor.forClass(ArrayList.class);
|
|
|
|
|
|
|
|
|
|
// only info2 should be added because info was already added to the workspace
|
|
|
|
|
// in setupWorkspaceWithHoles()
|
2018-10-04 15:11:00 -07:00
|
|
|
verify(callbacks).bindAppsAdded(any(IntArray.class), notAnimated.capture(),
|
2017-08-17 07:45:25 -07:00
|
|
|
animated.capture());
|
2016-09-09 15:47:55 -07:00
|
|
|
assertTrue(notAnimated.getValue().isEmpty());
|
|
|
|
|
|
|
|
|
|
assertEquals(1, animated.getValue().size());
|
|
|
|
|
assertTrue(animated.getValue().contains(info2));
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-07 11:43:47 -08:00
|
|
|
private int setupWorkspaceWithHoles(int startId, int screenId, Rect... holes) throws Exception {
|
2016-09-09 15:47:55 -07:00
|
|
|
GridOccupancy occupancy = new GridOccupancy(idp.numColumns, idp.numRows);
|
|
|
|
|
occupancy.markCells(0, 0, idp.numColumns, idp.numRows, true);
|
|
|
|
|
for (Rect r : holes) {
|
|
|
|
|
occupancy.markCells(r, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
existingScreens.add(screenId);
|
|
|
|
|
screenOccupancy.append(screenId, occupancy);
|
|
|
|
|
|
2018-12-07 11:43:47 -08:00
|
|
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
2016-09-09 15:47:55 -07:00
|
|
|
for (int x = 0; x < idp.numColumns; x++) {
|
|
|
|
|
for (int y = 0; y < idp.numRows; y++) {
|
|
|
|
|
if (!occupancy.cells[x][y]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-27 16:03:06 -07:00
|
|
|
WorkspaceItemInfo info = new WorkspaceItemInfo();
|
2016-09-09 15:47:55 -07:00
|
|
|
info.intent = new Intent().setComponent(mComponent1);
|
|
|
|
|
info.id = startId++;
|
|
|
|
|
info.screenId = screenId;
|
|
|
|
|
info.cellX = x;
|
|
|
|
|
info.cellY = y;
|
|
|
|
|
info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
|
2017-01-11 10:48:34 -08:00
|
|
|
bgDataModel.addItem(targetContext, info, false);
|
2018-12-07 11:43:47 -08:00
|
|
|
|
|
|
|
|
executor.execute(() -> {
|
|
|
|
|
ContentWriter writer = new ContentWriter(targetContext);
|
|
|
|
|
info.writeToValues(writer);
|
|
|
|
|
writer.put(Favorites._ID, info.id);
|
|
|
|
|
targetContext.getContentResolver().insert(Favorites.CONTENT_URI,
|
|
|
|
|
writer.getValues(targetContext));
|
|
|
|
|
});
|
2016-09-09 15:47:55 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-07 11:43:47 -08:00
|
|
|
executor.submit(() -> null).get();
|
|
|
|
|
executor.shutdown();
|
|
|
|
|
return startId;
|
2016-09-09 15:47:55 -07:00
|
|
|
}
|
|
|
|
|
}
|