7bc6cdee56
This reverts commit 09905cfa90.
Reason for revert: Fixed the crashing issue
Change-Id: Ibcfc28a89356d262e67e8842d6bae37e230a70f5
825 lines
29 KiB
Kotlin
825 lines
29 KiB
Kotlin
/*
|
|
* 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 androidx.test.platform.app.InstrumentationRegistry
|
|
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.config.FeatureFlags
|
|
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<String>
|
|
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 [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] 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_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE)
|
|
addItem(ITEM_TYPE_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_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<String, Point>()
|
|
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 [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] 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_SHORTCUT, 1, CONTAINER_HOTSEAT, 0, 0, testPackage2, 2, TMP_TABLE)
|
|
addItem(ITEM_TYPE_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_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(context, 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(context, 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(context, 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<String?>) {
|
|
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(context: Context, c: Cursor): Map<String, Triple<Int, Int, Int>> {
|
|
// 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<String, Triple<Int, Int, Int>>()
|
|
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_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_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_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_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 keep the pages if the column difference
|
|
* is less than 2
|
|
*/
|
|
@Test
|
|
@Throws(Exception::class)
|
|
fun migrateFromSmallerGridSmallDifference() {
|
|
enableNewMigrationLogic("4,4")
|
|
|
|
// Setup src grid
|
|
addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 2, testPackage1, 5, TMP_TABLE)
|
|
addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 3, testPackage2, 6, TMP_TABLE)
|
|
addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 3, 1, testPackage3, 7, TMP_TABLE)
|
|
addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 3, 2, testPackage4, 8, TMP_TABLE)
|
|
addItem(ITEM_TYPE_APPLICATION, 2, CONTAINER_DESKTOP, 3, 3, testPackage5, 9, TMP_TABLE)
|
|
|
|
idp.numDatabaseHotseatIcons = 4
|
|
idp.numColumns = 6
|
|
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<String, Int>()
|
|
while (c.moveToNext()) {
|
|
locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
|
|
c.getInt(screenIndex)
|
|
}
|
|
c.close()
|
|
assertThat(locMap.size).isEqualTo(5)
|
|
assertThat(locMap[testPackage1]).isEqualTo(0)
|
|
assertThat(locMap[testPackage2]).isEqualTo(0)
|
|
assertThat(locMap[testPackage3]).isEqualTo(1)
|
|
assertThat(locMap[testPackage4]).isEqualTo(1)
|
|
assertThat(locMap[testPackage5]).isEqualTo(2)
|
|
}
|
|
|
|
/**
|
|
* 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<String, Int>()
|
|
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<String, Int>()
|
|
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
|
|
}
|
|
}
|