summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-01-11 12:25:10 -0800
committerSunny Goyal <sunnygoyal@google.com>2016-01-20 11:58:09 -0800
commitf076eae0cab10f035f7b187c72a680cd220acf1b (patch)
treef109ef5e204e2602fc8d9ae25074b3a2e4290baa /tests
parent5743d870bd1c8281d90d424bdcd51792413592ae (diff)
downloadandroid_packages_apps_Trebuchet-f076eae0cab10f035f7b187c72a680cd220acf1b.tar.gz
android_packages_apps_Trebuchet-f076eae0cab10f035f7b187c72a680cd220acf1b.tar.bz2
android_packages_apps_Trebuchet-f076eae0cab10f035f7b187c72a680cd220acf1b.zip
Adding support for migrating the grid between any two valid screens sizes.
The grid is migrated in steps where each step consists of at max one column change and at max one row change. Adding some unit tests for GridMigrationLogic Bug: 25958224 Change-Id: Ie54e872ea0925cc4c463edbba0a7201d62b373a0
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