/* * 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.model import android.content.ContentValues import android.content.Context import android.content.Intent import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.graphics.Point import android.os.Process import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherPrefs import com.android.launcher3.LauncherPrefs.Companion.WORKSPACE_SIZE import com.android.launcher3.LauncherSettings.Favorites.* import com.android.launcher3.model.GridSizeMigrationUtil.DbReader import com.android.launcher3.pm.UserCache import com.android.launcher3.provider.LauncherDbUtils import com.android.launcher3.util.LauncherModelHelper import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith /** Unit tests for [GridSizeMigrationUtil] */ @SmallTest @RunWith(AndroidJUnit4::class) class GridSizeMigrationUtilTest { private lateinit var modelHelper: LauncherModelHelper private lateinit var context: Context private lateinit var validPackages: Set private lateinit var idp: InvariantDeviceProfile private lateinit var dbHelper: DatabaseHelper private lateinit var db: SQLiteDatabase private val testPackage1 = "com.android.launcher3.validpackage1" private val testPackage2 = "com.android.launcher3.validpackage2" private val testPackage3 = "com.android.launcher3.validpackage3" private val testPackage4 = "com.android.launcher3.validpackage4" private val testPackage5 = "com.android.launcher3.validpackage5" private val testPackage6 = "com.android.launcher3.validpackage6" private val testPackage7 = "com.android.launcher3.validpackage7" private val testPackage8 = "com.android.launcher3.validpackage8" private val testPackage9 = "com.android.launcher3.validpackage9" private val testPackage10 = "com.android.launcher3.validpackage10" @Before fun setUp() { modelHelper = LauncherModelHelper() context = modelHelper.sandboxContext dbHelper = DatabaseHelper( context, null, UserCache.INSTANCE.get(context)::getSerialNumberForUser ) {} db = dbHelper.writableDatabase validPackages = setOf( testPackage1, testPackage2, testPackage3, testPackage4, testPackage5, testPackage6, testPackage7, testPackage8, testPackage9, testPackage10 ) idp = InvariantDeviceProfile.INSTANCE[context] val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle()) LauncherDbUtils.dropTable(db, TMP_TABLE) addTableToDb(db, userSerial, false, TMP_TABLE) } @After fun tearDown() { modelHelper.destroy() } /** Old migration logic, should be modified once is not needed anymore */ @Test @Throws(Exception::class) fun testMigration() { // Src Hotseat icons addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_HOTSEAT, 0, 0, testPackage1, 1, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 3, CONTAINER_HOTSEAT, 0, 0, testPackage3, 3, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 4, CONTAINER_HOTSEAT, 0, 0, testPackage4, 4, TMP_TABLE) // Src grid icons // _ _ _ _ _ // _ _ _ _ 5 // _ _ 6 _ 7 // _ _ 8 _ 9 // _ _ _ _ _ addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 4, 1, testPackage5, 5, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 2, testPackage6, 6, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 4, 2, testPackage7, 7, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 3, testPackage8, 8, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 4, 3, testPackage9, 9, TMP_TABLE) // Dest hotseat icons addItem(ITEM_TYPE_DEEP_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2) // Dest grid icons addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 2, testPackage10) idp.numDatabaseHotseatIcons = 4 idp.numColumns = 4 idp.numRows = 4 val srcReader = DbReader(db, TMP_TABLE, context, validPackages) val destReader = DbReader(db, TABLE_NAME, context, validPackages) GridSizeMigrationUtil.migrate( dbHelper, srcReader, destReader, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Check hotseat items var c = db.query( TABLE_NAME, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() assertThat(c.count).isEqualTo(idp.numDatabaseHotseatIcons) val screenIndex = c.getColumnIndex(SCREEN) var intentIndex = c.getColumnIndex(INTENT) c.moveToNext() assertThat(c.getInt(screenIndex).toLong()).isEqualTo(0) assertThat(c.getString(intentIndex)).contains(testPackage1) c.moveToNext() assertThat(c.getInt(screenIndex).toLong()).isEqualTo(1) assertThat(c.getString(intentIndex)).contains(testPackage2) c.moveToNext() assertThat(c.getInt(screenIndex).toLong()).isEqualTo(2) assertThat(c.getString(intentIndex)).contains(testPackage3) c.moveToNext() assertThat(c.getInt(screenIndex).toLong()).isEqualTo(3) assertThat(c.getString(intentIndex)).contains(testPackage4) c.close() // Check workspace items c = db.query( TABLE_NAME, arrayOf(CELLX, CELLY, INTENT), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() intentIndex = c.getColumnIndex(INTENT) val cellXIndex = c.getColumnIndex(CELLX) val cellYIndex = c.getColumnIndex(CELLY) val locMap = HashMap() while (c.moveToNext()) { locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] = Point(c.getInt(cellXIndex), c.getInt(cellYIndex)) } c.close() // Expected dest grid icons // _ _ _ _ // 5 6 7 8 // 9 _ _ _ // _ _ _ _ assertThat(locMap.size.toLong()).isEqualTo(5) assertThat(locMap[testPackage5]).isEqualTo(Point(0, 1)) assertThat(locMap[testPackage6]).isEqualTo(Point(1, 1)) assertThat(locMap[testPackage7]).isEqualTo(Point(2, 1)) assertThat(locMap[testPackage8]).isEqualTo(Point(3, 1)) assertThat(locMap[testPackage9]).isEqualTo(Point(0, 2)) } /** Old migration logic, should be modified once is not needed anymore */ @Test @Throws(Exception::class) fun testMigrationBackAndForth() { // Hotseat items in grid A // 1 2 _ 3 4 addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_HOTSEAT, 0, 0, testPackage1, 1, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 3, CONTAINER_HOTSEAT, 0, 0, testPackage3, 3, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 4, CONTAINER_HOTSEAT, 0, 0, testPackage4, 4, TMP_TABLE) // Workspace items in grid A // _ _ _ _ _ // _ _ _ _ 5 // _ _ 6 _ 7 // _ _ 8 _ _ // _ _ _ _ _ addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 4, 1, testPackage5, 5, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 2, testPackage6, 6, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 4, 2, testPackage7, 7, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 3, testPackage8, 8, TMP_TABLE) // Hotseat items in grid B // 2 _ _ _ addItem(ITEM_TYPE_DEEP_SHORTCUT, 0, CONTAINER_HOTSEAT, 0, 0, testPackage2) // Workspace items in grid B // _ _ _ _ // _ _ _ 10 // _ _ _ _ // _ _ _ _ addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 1, 3, testPackage10) idp.numDatabaseHotseatIcons = 4 idp.numColumns = 4 idp.numRows = 4 val readerGridA = DbReader(db, TMP_TABLE, context, validPackages) val readerGridB = DbReader(db, TABLE_NAME, context, validPackages) // migrate from A -> B GridSizeMigrationUtil.migrate( dbHelper, readerGridA, readerGridB, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Check hotseat items in grid B var c = db.query( TABLE_NAME, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() // Expected hotseat items in grid B // 2 1 3 4 verifyHotseat( c, idp, mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList() ) // Check workspace items in grid B c = db.query( TABLE_NAME, arrayOf(SCREEN, CELLX, CELLY, INTENT), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() var locMap = parseLocMap(c) // Expected items in grid B // _ _ _ _ // 5 6 7 8 // _ _ _ _ // _ _ _ _ assertThat(locMap.size.toLong()).isEqualTo(4) assertThat(locMap[testPackage5]).isEqualTo(Triple(0, 0, 1)) assertThat(locMap[testPackage6]).isEqualTo(Triple(0, 1, 1)) assertThat(locMap[testPackage7]).isEqualTo(Triple(0, 2, 1)) assertThat(locMap[testPackage8]).isEqualTo(Triple(0, 3, 1)) // add item in B addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 0, 2, testPackage9) // migrate from B -> A GridSizeMigrationUtil.migrate( dbHelper, readerGridB, readerGridA, 5, Point(5, 5), DeviceGridState(idp), DeviceGridState(context) ) // Check hotseat items in grid A c = db.query( TMP_TABLE, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() // Expected hotseat items in grid A // 1 2 _ 3 4 verifyHotseat( c, idp, mutableListOf(testPackage1, testPackage2, null, testPackage3, testPackage4).toList() ) // Check workspace items in grid A c = db.query( TMP_TABLE, arrayOf(SCREEN, CELLX, CELLY, INTENT), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() locMap = parseLocMap(c) // Expected workspace items in grid A // _ _ _ _ _ // _ _ _ _ 5 // 9 _ 6 _ 7 // _ _ 8 _ _ // _ _ _ _ _ assertThat(locMap.size.toLong()).isEqualTo(5) // Verify items that existed in grid A remains in same position assertThat(locMap[testPackage5]).isEqualTo(Triple(0, 4, 1)) assertThat(locMap[testPackage6]).isEqualTo(Triple(0, 2, 2)) assertThat(locMap[testPackage7]).isEqualTo(Triple(0, 4, 2)) assertThat(locMap[testPackage8]).isEqualTo(Triple(0, 2, 3)) // Verify items that didn't exist in grid A are added in new screen assertThat(locMap[testPackage9]).isEqualTo(Triple(0, 0, 2)) // remove item from B db.delete(TMP_TABLE, "$_ID=7", null) // migrate from A -> B GridSizeMigrationUtil.migrate( dbHelper, readerGridA, readerGridB, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Check hotseat items in grid B c = db.query( TABLE_NAME, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() // Expected hotseat items in grid B // 2 1 3 4 verifyHotseat( c, idp, mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList() ) // Check workspace items in grid B c = db.query( TABLE_NAME, arrayOf(SCREEN, CELLX, CELLY, INTENT), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() locMap = parseLocMap(c) // Expected workspace items in grid B // _ _ _ _ // 5 6 _ 8 // 9 _ _ _ // _ _ _ _ assertThat(locMap.size.toLong()).isEqualTo(4) assertThat(locMap[testPackage5]).isEqualTo(Triple(0, 0, 1)) assertThat(locMap[testPackage6]).isEqualTo(Triple(0, 1, 1)) assertThat(locMap[testPackage8]).isEqualTo(Triple(0, 3, 1)) assertThat(locMap[testPackage9]).isEqualTo(Triple(0, 0, 2)) } private fun verifyHotseat(c: Cursor, idp: InvariantDeviceProfile, expected: List) { assertThat(c.count).isEqualTo(idp.numDatabaseHotseatIcons) val screenIndex = c.getColumnIndex(SCREEN) val intentIndex = c.getColumnIndex(INTENT) expected.forEachIndexed { idx, pkg -> if (pkg == null) return@forEachIndexed c.moveToNext() assertThat(c.getInt(screenIndex).toLong()).isEqualTo(idx) assertThat(c.getString(intentIndex)).contains(pkg) } c.close() } private fun parseLocMap(c: Cursor): Map> { // Check workspace items val intentIndex = c.getColumnIndex(INTENT) val screenIndex = c.getColumnIndex(SCREEN) val cellXIndex = c.getColumnIndex(CELLX) val cellYIndex = c.getColumnIndex(CELLY) val locMap = mutableMapOf>() while (c.moveToNext()) { locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] = Triple(c.getInt(screenIndex), c.getInt(cellXIndex), c.getInt(cellYIndex)) } c.close() return locMap.toMap() } @Test fun migrateToLargerHotseat() { val srcHotseatItems = intArrayOf( addItem( ITEM_TYPE_APPLICATION, 0, CONTAINER_HOTSEAT, 0, 0, testPackage1, 1, TMP_TABLE ), addItem( ITEM_TYPE_DEEP_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE ), addItem( ITEM_TYPE_APPLICATION, 2, CONTAINER_HOTSEAT, 0, 0, testPackage3, 3, TMP_TABLE ), addItem( ITEM_TYPE_DEEP_SHORTCUT, 3, CONTAINER_HOTSEAT, 0, 0, testPackage4, 4, TMP_TABLE ) ) val numSrcDatabaseHotseatIcons = srcHotseatItems.size idp.numDatabaseHotseatIcons = 6 idp.numColumns = 4 idp.numRows = 4 val srcReader = DbReader(db, TMP_TABLE, context, validPackages) val destReader = DbReader(db, TABLE_NAME, context, validPackages) GridSizeMigrationUtil.migrate( dbHelper, srcReader, destReader, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Check hotseat items val c = db.query( TABLE_NAME, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() assertThat(c.count.toLong()).isEqualTo(numSrcDatabaseHotseatIcons.toLong()) val screenIndex = c.getColumnIndex(SCREEN) val intentIndex = c.getColumnIndex(INTENT) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(0) assertThat(c.getString(intentIndex)).contains(testPackage1) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(1) assertThat(c.getString(intentIndex)).contains(testPackage2) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(2) assertThat(c.getString(intentIndex)).contains(testPackage3) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(3) assertThat(c.getString(intentIndex)).contains(testPackage4) c.close() } @Test fun migrateFromLargerHotseat() { addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_HOTSEAT, 0, 0, testPackage1, 1, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 2, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 3, CONTAINER_HOTSEAT, 0, 0, testPackage3, 3, TMP_TABLE) addItem(ITEM_TYPE_DEEP_SHORTCUT, 4, CONTAINER_HOTSEAT, 0, 0, testPackage4, 4, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 5, CONTAINER_HOTSEAT, 0, 0, testPackage5, 5, TMP_TABLE) idp.numDatabaseHotseatIcons = 4 idp.numColumns = 4 idp.numRows = 4 val srcReader = DbReader(db, TMP_TABLE, context, validPackages) val destReader = DbReader(db, TABLE_NAME, context, validPackages) GridSizeMigrationUtil.migrate( dbHelper, srcReader, destReader, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Check hotseat items val c = db.query( TABLE_NAME, arrayOf(SCREEN, INTENT), "container=$CONTAINER_HOTSEAT", null, SCREEN, null, null ) ?: throw IllegalStateException() assertThat(c.count.toLong()).isEqualTo(idp.numDatabaseHotseatIcons.toLong()) val screenIndex = c.getColumnIndex(SCREEN) val intentIndex = c.getColumnIndex(INTENT) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(0) assertThat(c.getString(intentIndex)).contains(testPackage1) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(1) assertThat(c.getString(intentIndex)).contains(testPackage2) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(2) assertThat(c.getString(intentIndex)).contains(testPackage3) c.moveToNext() assertThat(c.getInt(screenIndex)).isEqualTo(3) assertThat(c.getString(intentIndex)).contains(testPackage4) c.close() } /** * Migrating from a smaller grid to a large one should reflow the pages if the column difference * is more than 2 */ @Test @Throws(Exception::class) fun migrateFromSmallerGridBigDifference() { enableNewMigrationLogic("2,2") // Setup src grid addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 0, 1, testPackage1, 5, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 1, 1, testPackage2, 6, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 0, 0, testPackage3, 7, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 1, 0, testPackage4, 8, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 2, CONTAINER_DESKTOP, 0, 0, testPackage5, 9, TMP_TABLE) idp.numDatabaseHotseatIcons = 4 idp.numColumns = 5 idp.numRows = 5 val srcReader = DbReader(db, TMP_TABLE, context, validPackages) val destReader = DbReader(db, TABLE_NAME, context, validPackages) GridSizeMigrationUtil.migrate( dbHelper, srcReader, destReader, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Get workspace items val c = db.query( TABLE_NAME, arrayOf(INTENT, SCREEN), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() val intentIndex = c.getColumnIndex(INTENT) val screenIndex = c.getColumnIndex(SCREEN) // Get in which screen the icon is val locMap = HashMap() while (c.moveToNext()) { locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] = c.getInt(screenIndex) } c.close() // All icons fit the first screen assertThat(locMap.size).isEqualTo(5) assertThat(locMap[testPackage1]).isEqualTo(0) assertThat(locMap[testPackage2]).isEqualTo(0) assertThat(locMap[testPackage3]).isEqualTo(0) assertThat(locMap[testPackage4]).isEqualTo(0) assertThat(locMap[testPackage5]).isEqualTo(0) } /** Migrating from a larger grid to a smaller, we reflow from page 0 */ @Test @Throws(Exception::class) fun migrateFromLargerGrid() { enableNewMigrationLogic("5,5") // Setup src grid addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 0, 1, testPackage1, 5, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 1, 1, testPackage2, 6, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 0, 0, testPackage3, 7, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 1, 0, testPackage4, 8, TMP_TABLE) addItem(ITEM_TYPE_APPLICATION, 2, CONTAINER_DESKTOP, 0, 0, testPackage5, 9, TMP_TABLE) idp.numDatabaseHotseatIcons = 4 idp.numColumns = 4 idp.numRows = 4 val srcReader = DbReader(db, TMP_TABLE, context, validPackages) val destReader = DbReader(db, TABLE_NAME, context, validPackages) GridSizeMigrationUtil.migrate( dbHelper, srcReader, destReader, idp.numDatabaseHotseatIcons, Point(idp.numColumns, idp.numRows), DeviceGridState(context), DeviceGridState(idp) ) // Get workspace items val c = db.query( TABLE_NAME, arrayOf(INTENT, SCREEN), "container=$CONTAINER_DESKTOP", null, null, null, null ) ?: throw IllegalStateException() val intentIndex = c.getColumnIndex(INTENT) val screenIndex = c.getColumnIndex(SCREEN) // Get in which screen the icon is val locMap = HashMap() while (c.moveToNext()) { locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] = c.getInt(screenIndex) } c.close() // All icons fit the first screen assertThat(locMap.size).isEqualTo(5) assertThat(locMap[testPackage1]).isEqualTo(0) assertThat(locMap[testPackage2]).isEqualTo(0) assertThat(locMap[testPackage3]).isEqualTo(0) assertThat(locMap[testPackage4]).isEqualTo(0) assertThat(locMap[testPackage5]).isEqualTo(0) } private fun enableNewMigrationLogic(srcGridSize: String) { LauncherPrefs.get(context).putSync(WORKSPACE_SIZE.to(srcGridSize)) } private fun addItem( type: Int, screen: Int, container: Int, x: Int, y: Int, packageName: String? ): Int { return addItem( type, screen, container, x, y, packageName, dbHelper.generateNewItemId(), TABLE_NAME ) } private fun addItem( type: Int, screen: Int, container: Int, x: Int, y: Int, packageName: String?, id: Int, tableName: String ): Int { val values = ContentValues() values.put(_ID, id) values.put(CONTAINER, container) values.put(SCREEN, screen) values.put(CELLX, x) values.put(CELLY, y) values.put(SPANX, 1) values.put(SPANY, 1) values.put(ITEM_TYPE, type) values.put(INTENT, Intent(Intent.ACTION_MAIN).setPackage(packageName).toUri(0)) db.insert(tableName, null, values) return id } }