summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java321
-rw-r--r--tests/src/com/android/launcher3/util/TestLauncherProvider.java40
2 files changed, 361 insertions, 0 deletions
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
new file mode 100644
index 000000000..46dac0aab
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -0,0 +1,321 @@
+package com.android.launcher3.model;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Point;
+import android.test.ProviderTestCase2;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.util.TestLauncherProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Unit tests for {@link GridSizeMigrationTask}
+ */
+public class GridSizeMigrationTaskTest extends ProviderTestCase2<TestLauncherProvider> {
+
+ private static final long DESKTOP = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+ private static final long HOTSEAT = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+
+ private static final int APPLICATION = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+ private static final int SHORTCUT = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+
+ private static final String TEST_PACKAGE = "com.android.launcher3.validpackage";
+ private static final String VALID_INTENT =
+ new Intent(Intent.ACTION_MAIN).setPackage(TEST_PACKAGE).toUri(0);
+
+ private HashSet<String> mValidPackages;
+ private InvariantDeviceProfile mIdp;
+
+ public GridSizeMigrationTaskTest() {
+ super(TestLauncherProvider.class, ProviderConfig.AUTHORITY);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mValidPackages = new HashSet<>();
+ mValidPackages.add(TEST_PACKAGE);
+
+ mIdp = new InvariantDeviceProfile();
+ }
+
+ public void testHotseatMigration_apps_dropped() throws Exception {
+ long[] hotseatItems = {
+ addItem(APPLICATION, 0, HOTSEAT, 0, 0),
+ addItem(SHORTCUT, 1, HOTSEAT, 0, 0),
+ -1,
+ addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
+ addItem(APPLICATION, 4, HOTSEAT, 0, 0),
+ };
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, 5, 2, 3, 1)
+ .migrateHotseat();
+ // First & last items are dropped as they have the least weight.
+ verifyHotseat(hotseatItems[1], -1, hotseatItems[3]);
+ }
+
+ public void testHotseatMigration_shortcuts_dropped() throws Exception {
+ long[] hotseatItems = {
+ addItem(APPLICATION, 0, HOTSEAT, 0, 0),
+ addItem(30, 1, HOTSEAT, 0, 0),
+ -1,
+ addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
+ addItem(10, 4, HOTSEAT, 0, 0),
+ };
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, 5, 2, 3, 1)
+ .migrateHotseat();
+ // First & third items are dropped as they have the least weight.
+ verifyHotseat(hotseatItems[1], -1, hotseatItems[4]);
+ }
+
+ private void verifyHotseat(long... sortedIds) {
+ int screenId = 0;
+ int total = 0;
+
+ for (long id : sortedIds) {
+ Cursor c = getMockContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-101 and screen=" + screenId, null, null, null);
+
+ if (id == -1) {
+ assertEquals(0, c.getCount());
+ } else {
+ assertEquals(1, c.getCount());
+ c.moveToNext();
+ assertEquals(id, c.getLong(0));
+ total ++;
+ }
+ c.close();
+
+ screenId++;
+ }
+
+ // Verify that not other entry exist in the DB.
+ Cursor c = getMockContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-101", null, null, null);
+ assertEquals(total, c.getCount());
+ c.close();
+ }
+
+ public void testWorkspace_empty_row_column_removed() throws Exception {
+ long[][][] ids = createGrid(new int[][][]{{
+ { 0, 0, -1, 1},
+ { 3, 1, -1, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Column 2 and row 2 got removed.
+ verifyWorkspace(new long[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }});
+ }
+
+ public void testWorkspace_new_screen_created() throws Exception {
+ long[][][] ids = createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column get moved to new screen
+ verifyWorkspace(new long[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ public void testWorkspace_items_merged_in_next_screen() throws Exception {
+ long[][][] ids = createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ },{
+ { 0, 0, -1, 1},
+ { 3, 1, -1, 4},
+ }});
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on the 3rd
+ // row of the second screen
+ verifyWorkspace(new long[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ {ids[1][0][0], ids[1][0][1], ids[1][0][3]},
+ {ids[1][1][0], ids[1][1][1], ids[1][1][3]},
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ public void testWorkspace_items_not_merged_in_next_screen() throws Exception {
+ // First screen has 2 items that need to be moved, but second screen has only one
+ // empty space after migration (top-left corner)
+ long[][][] ids = createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ },{
+ { -1, 0, -1, 1},
+ { 3, 1, -1, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on a new screen.
+ verifyWorkspace(new long[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ { -1, ids[1][0][1], ids[1][0][3]},
+ {ids[1][1][0], ids[1][1][1], ids[1][1][3]},
+ {ids[1][3][0], ids[1][3][1], ids[1][3][3]},
+ }, {
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ /**
+ * Initializes the DB with dummy elements to represent the provided grid structure.
+ * @param typeArray A 3d array of item types. {@see #addItem(int, long, long, int, int)} for
+ * type definitions. The first dimension represents the screens and the next
+ * two represent the workspace grid.
+ * @return the same grid representation where each entry is the corresponding item id.
+ */
+ private long[][][] createGrid(int[][][] typeArray) throws Exception {
+ long[][][] ids = new long[typeArray.length][][];
+
+ for (int i = 0; i < typeArray.length; i++) {
+ // Add screen to DB
+ long screenId = LauncherSettings.Settings.call(getMockContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+ .getLong(LauncherSettings.Settings.EXTRA_VALUE);
+
+ ContentValues v = new ContentValues();
+ v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
+ v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
+ getMockContentResolver().insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
+
+ ids[i] = new long[typeArray[i].length][];
+ for (int y = 0; y < typeArray[i].length; y++) {
+ ids[i][y] = new long[typeArray[i][y].length];
+ for (int x = 0; x < typeArray[i][y].length; x++) {
+ if (typeArray[i][y][x] < 0) {
+ // Empty cell
+ ids[i][y][x] = -1;
+ } else {
+ ids[i][y][x] = addItem(typeArray[i][y][x], screenId, DESKTOP, x, y);
+ }
+ }
+ }
+ }
+ return ids;
+ }
+
+ /**
+ * Verifies that the workspace items are arranged in the provided order.
+ * @param ids A 3d array where the first dimension represents the screen, and the rest two
+ * represent the workspace grid.
+ */
+ private void verifyWorkspace(long[][][] ids) {
+ ArrayList<Long> allScreens = LauncherModel.loadWorkspaceScreensDb(getMockContext());
+ assertEquals(ids.length, allScreens.size());
+ int total = 0;
+
+ for (int i = 0; i < ids.length; i++) {
+ long screenId = allScreens.get(i);
+ for (int y = 0; y < ids[i].length; y++) {
+ for (int x = 0; x < ids[i][y].length; x++) {
+ long id = ids[i][y][x];
+
+ Cursor c = getMockContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-100 and screen=" + screenId +
+ " and cellX=" + x + " and cellY=" + y, null, null, null);
+ if (id == -1) {
+ assertEquals(0, c.getCount());
+ } else {
+ assertEquals(1, c.getCount());
+ c.moveToNext();
+ assertEquals(id, c.getLong(0));
+ total++;
+ }
+ c.close();
+ }
+ }
+ }
+
+ // Verify that not other entry exist in the DB.
+ Cursor c = getMockContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-100", null, null, null);
+ assertEquals(total, c.getCount());
+ c.close();
+ }
+
+ /**
+ * Adds a dummy item in the DB.
+ * @param type {@link #APPLICATION} or {@link #SHORTCUT} or >= 2 for
+ * folder (where the type represents the number of items in the folder).
+ */
+ private long addItem(int type, long screen, long container, int x, int y) throws Exception {
+ long id = LauncherSettings.Settings.call(getMockContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
+ .getLong(LauncherSettings.Settings.EXTRA_VALUE);
+
+ ContentValues values = new ContentValues();
+ values.put(LauncherSettings.Favorites._ID, id);
+ values.put(LauncherSettings.Favorites.CONTAINER, container);
+ values.put(LauncherSettings.Favorites.SCREEN, screen);
+ values.put(LauncherSettings.Favorites.CELLX, x);
+ values.put(LauncherSettings.Favorites.CELLY, y);
+ values.put(LauncherSettings.Favorites.SPANX, 1);
+ values.put(LauncherSettings.Favorites.SPANY, 1);
+
+ if (type == APPLICATION || type == SHORTCUT) {
+ values.put(LauncherSettings.Favorites.ITEM_TYPE, type);
+ values.put(LauncherSettings.Favorites.INTENT, VALID_INTENT);
+ } else {
+ values.put(LauncherSettings.Favorites.ITEM_TYPE,
+ LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
+ // Add folder items.
+ for (int i = 0; i < type; i++) {
+ addItem(APPLICATION, 0, id, 0, 0);
+ }
+ }
+
+ getMockContentResolver().insert(LauncherSettings.Favorites.CONTENT_URI, values);
+ return id;
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/TestLauncherProvider.java b/tests/src/com/android/launcher3/util/TestLauncherProvider.java
new file mode 100644
index 000000000..aef3240ca
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/TestLauncherProvider.java
@@ -0,0 +1,40 @@
+package com.android.launcher3.util;
+
+import android.content.Context;
+
+import com.android.launcher3.LauncherProvider;
+
+/**
+ * An extension of LauncherProvider backed up by in-memory database.
+ */
+public class TestLauncherProvider extends LauncherProvider {
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ protected synchronized void createDbIfNotExists() {
+ if (mOpenHelper == null) {
+ mOpenHelper = new MyDatabaseHelper(getContext(), this);
+ }
+ }
+
+ @Override
+ protected void notifyListeners() { }
+
+ private static class MyDatabaseHelper extends DatabaseHelper {
+ public MyDatabaseHelper(Context context, LauncherProvider provider) {
+ super(context, provider, null);
+ }
+
+ @Override
+ protected long getDefaultUserSerial() {
+ return 0;
+ }
+
+ @Override
+ protected void onEmptyDbCreated() { }
+ }
+} \ No newline at end of file