Merge "Remove gap between screenIds when restoring from single display device" into sc-v2-dev
This commit is contained in:
commit
048a8246fa
|
@ -483,7 +483,7 @@ public class LauncherProvider extends ContentProvider {
|
||||||
LauncherSettings.Favorites.CONTAINER + " FROM "
|
LauncherSettings.Favorites.CONTAINER + " FROM "
|
||||||
+ Favorites.TABLE_NAME + ")";
|
+ Favorites.TABLE_NAME + ")";
|
||||||
|
|
||||||
IntArray folderIds = LauncherDbUtils.queryIntArray(db, Favorites.TABLE_NAME,
|
IntArray folderIds = LauncherDbUtils.queryIntArray(false, db, Favorites.TABLE_NAME,
|
||||||
Favorites._ID, selection, null, null);
|
Favorites._ID, selection, null, null);
|
||||||
if (!folderIds.isEmpty()) {
|
if (!folderIds.isEmpty()) {
|
||||||
db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
|
db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
|
||||||
|
@ -835,8 +835,8 @@ public class LauncherProvider extends ContentProvider {
|
||||||
case 27: {
|
case 27: {
|
||||||
// Update the favorites table so that the screen ids are ordered based on
|
// Update the favorites table so that the screen ids are ordered based on
|
||||||
// workspace page rank.
|
// workspace page rank.
|
||||||
IntArray finalScreens = LauncherDbUtils.queryIntArray(db, "workspaceScreens",
|
IntArray finalScreens = LauncherDbUtils.queryIntArray(false, db,
|
||||||
BaseColumns._ID, null, null, "screenRank");
|
"workspaceScreens", BaseColumns._ID, null, null, "screenRank");
|
||||||
int[] original = finalScreens.toArray();
|
int[] original = finalScreens.toArray();
|
||||||
Arrays.sort(original);
|
Arrays.sort(original);
|
||||||
String updatemap = "";
|
String updatemap = "";
|
||||||
|
@ -919,7 +919,7 @@ public class LauncherProvider extends ContentProvider {
|
||||||
Log.e(TAG, "getAppWidgetIds not supported", e);
|
Log.e(TAG, "getAppWidgetIds not supported", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(db,
|
final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(false, db,
|
||||||
Favorites.TABLE_NAME, Favorites.APPWIDGET_ID,
|
Favorites.TABLE_NAME, Favorites.APPWIDGET_ID,
|
||||||
"itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null));
|
"itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null));
|
||||||
for (int widgetId : allWidgets) {
|
for (int widgetId : allWidgets) {
|
||||||
|
|
|
@ -31,11 +31,11 @@ import com.android.launcher3.util.IntArray;
|
||||||
*/
|
*/
|
||||||
public class LauncherDbUtils {
|
public class LauncherDbUtils {
|
||||||
|
|
||||||
public static IntArray queryIntArray(SQLiteDatabase db, String tableName, String columnName,
|
public static IntArray queryIntArray(boolean distinct, SQLiteDatabase db, String tableName,
|
||||||
String selection, String groupBy, String orderBy) {
|
String columnName, String selection, String groupBy, String orderBy) {
|
||||||
IntArray out = new IntArray();
|
IntArray out = new IntArray();
|
||||||
try (Cursor c = db.query(tableName, new String[] { columnName }, selection, null,
|
try (Cursor c = db.query(distinct, tableName, new String[] { columnName }, selection, null,
|
||||||
groupBy, null, orderBy)) {
|
groupBy, null, orderBy, null)) {
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
out.add(c.getInt(0));
|
out.add(c.getInt(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package com.android.launcher3.provider;
|
package com.android.launcher3.provider;
|
||||||
|
|
||||||
|
import static com.android.launcher3.model.DeviceGridState.TYPE_MULTI_DISPLAY;
|
||||||
import static com.android.launcher3.model.DeviceGridState.TYPE_PHONE;
|
import static com.android.launcher3.model.DeviceGridState.TYPE_PHONE;
|
||||||
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ public class RestoreDbTask {
|
||||||
try (SQLiteTransaction t = new SQLiteTransaction(db)) {
|
try (SQLiteTransaction t = new SQLiteTransaction(db)) {
|
||||||
RestoreDbTask task = new RestoreDbTask();
|
RestoreDbTask task = new RestoreDbTask();
|
||||||
task.backupWorkspace(context, db);
|
task.backupWorkspace(context, db);
|
||||||
task.sanitizeDB(helper, db, new BackupManager(context));
|
task.sanitizeDB(context, helper, db, new BackupManager(context));
|
||||||
task.restoreAppWidgetIdsIfExists(context);
|
task.restoreAppWidgetIdsIfExists(context);
|
||||||
t.commit();
|
t.commit();
|
||||||
return true;
|
return true;
|
||||||
|
@ -139,7 +140,7 @@ public class RestoreDbTask {
|
||||||
GridBackupTable backupTable = new GridBackupTable(context, db, idp.numDatabaseHotseatIcons,
|
GridBackupTable backupTable = new GridBackupTable(context, db, idp.numDatabaseHotseatIcons,
|
||||||
idp.numColumns, idp.numRows);
|
idp.numColumns, idp.numRows);
|
||||||
if (backupTable.restoreFromRawBackupIfAvailable(getDefaultProfileId(db))) {
|
if (backupTable.restoreFromRawBackupIfAvailable(getDefaultProfileId(db))) {
|
||||||
int itemsDeleted = sanitizeDB(helper, db, backupManager);
|
int itemsDeleted = sanitizeDB(context, helper, db, backupManager);
|
||||||
LauncherAppState.getInstance(context).getModel().forceReload();
|
LauncherAppState.getInstance(context).getModel().forceReload();
|
||||||
restoreAppWidgetIdsIfExists(context);
|
restoreAppWidgetIdsIfExists(context);
|
||||||
if (itemsDeleted == 0) {
|
if (itemsDeleted == 0) {
|
||||||
|
@ -156,11 +157,12 @@ public class RestoreDbTask {
|
||||||
* the restored apps get installed.
|
* the restored apps get installed.
|
||||||
* 3. If the user serial for any restored profile is different than that of the previous
|
* 3. If the user serial for any restored profile is different than that of the previous
|
||||||
* device, update the entries to the new profile id.
|
* device, update the entries to the new profile id.
|
||||||
|
* 4. If restored from a single display backup, remove gaps between screenIds
|
||||||
*
|
*
|
||||||
* @return number of items deleted.
|
* @return number of items deleted.
|
||||||
*/
|
*/
|
||||||
private int sanitizeDB(DatabaseHelper helper, SQLiteDatabase db, BackupManager backupManager)
|
private int sanitizeDB(Context context, DatabaseHelper helper, SQLiteDatabase db,
|
||||||
throws Exception {
|
BackupManager backupManager) throws Exception {
|
||||||
// Primary user ids
|
// Primary user ids
|
||||||
long myProfileId = helper.getDefaultUserSerial();
|
long myProfileId = helper.getDefaultUserSerial();
|
||||||
long oldProfileId = getDefaultProfileId(db);
|
long oldProfileId = getDefaultProfileId(db);
|
||||||
|
@ -236,9 +238,42 @@ public class RestoreDbTask {
|
||||||
if (myProfileId != oldProfileId) {
|
if (myProfileId != oldProfileId) {
|
||||||
changeDefaultColumn(db, myProfileId);
|
changeDefaultColumn(db, myProfileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If restored from a single display backup, remove gaps between screenIds
|
||||||
|
if (Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE)
|
||||||
|
!= TYPE_MULTI_DISPLAY) {
|
||||||
|
removeScreenIdGaps(db);
|
||||||
|
}
|
||||||
|
|
||||||
return itemsDeleted;
|
return itemsDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove gaps between screenIds to make sure no empty pages are left in between.
|
||||||
|
*
|
||||||
|
* e.g. [0, 3, 4, 6, 7] -> [0, 1, 2, 3, 4]
|
||||||
|
*/
|
||||||
|
protected void removeScreenIdGaps(SQLiteDatabase db) {
|
||||||
|
FileLog.d(TAG, "Removing gaps between screenIds");
|
||||||
|
IntArray distinctScreens = LauncherDbUtils.queryIntArray(true, db, Favorites.TABLE_NAME,
|
||||||
|
Favorites.SCREEN, Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP, null,
|
||||||
|
Favorites.SCREEN);
|
||||||
|
if (distinctScreens.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sql = new StringBuilder("UPDATE ").append(Favorites.TABLE_NAME)
|
||||||
|
.append(" SET ").append(Favorites.SCREEN).append(" =\nCASE\n");
|
||||||
|
int screenId = distinctScreens.contains(0) ? 0 : 1;
|
||||||
|
for (int i = 0; i < distinctScreens.size(); i++) {
|
||||||
|
sql.append("WHEN ").append(Favorites.SCREEN).append(" == ")
|
||||||
|
.append(distinctScreens.get(i)).append(" THEN ").append(screenId++).append("\n");
|
||||||
|
}
|
||||||
|
sql.append("ELSE screen\nEND WHERE ").append(Favorites.CONTAINER).append(" = ")
|
||||||
|
.append(Favorites.CONTAINER_DESKTOP).append(";");
|
||||||
|
db.execSQL(sql.toString());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates profile id of all entries from {@param oldProfileId} to {@param newProfileId}.
|
* Updates profile id of all entries from {@param oldProfileId} to {@param newProfileId}.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.android.launcher3.provider;
|
package com.android.launcher3.provider;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
@ -87,6 +88,56 @@ public class RestoreDbTaskTest {
|
||||||
assertEquals(1, getCount(db, "select * from favorites where profileId = 33"));
|
assertEquals(1, getCount(db, "select * from favorites where profileId = 33"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveScreenIdGaps_firstScreenEmpty() {
|
||||||
|
runRemoveScreenIdGapsTest(
|
||||||
|
new int[]{1, 2, 5, 6, 6, 7, 9, 9},
|
||||||
|
new int[]{1, 2, 3, 4, 4, 5, 6, 6});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveScreenIdGaps_firstScreenOccupied() {
|
||||||
|
runRemoveScreenIdGapsTest(
|
||||||
|
new int[]{0, 2, 5, 6, 6, 7, 9, 9},
|
||||||
|
new int[]{0, 1, 2, 3, 3, 4, 5, 5});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveScreenIdGaps_noGap() {
|
||||||
|
runRemoveScreenIdGapsTest(
|
||||||
|
new int[]{0, 1, 1, 2, 3, 3, 4, 5},
|
||||||
|
new int[]{0, 1, 1, 2, 3, 3, 4, 5});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runRemoveScreenIdGapsTest(int[] screenIds, int[] expectedScreenIds) {
|
||||||
|
SQLiteDatabase db = new MyDatabaseHelper(42).getWritableDatabase();
|
||||||
|
// Add some mock data
|
||||||
|
for (int i = 0; i < screenIds.length; i++) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(Favorites._ID, i);
|
||||||
|
values.put(Favorites.SCREEN, screenIds[i]);
|
||||||
|
values.put(Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP);
|
||||||
|
db.insert(Favorites.TABLE_NAME, null, values);
|
||||||
|
}
|
||||||
|
// Verify items are added
|
||||||
|
assertEquals(screenIds.length,
|
||||||
|
getCount(db, "select * from favorites where container = -100"));
|
||||||
|
|
||||||
|
new RestoreDbTask().removeScreenIdGaps(db);
|
||||||
|
|
||||||
|
// verify screenId gaps removed
|
||||||
|
int[] resultScreenIds = new int[screenIds.length];
|
||||||
|
try (Cursor c = db.rawQuery(
|
||||||
|
"select screen from favorites where container = -100 order by screen", null)) {
|
||||||
|
int i = 0;
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
resultScreenIds[i++] = c.getInt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertArrayEquals(expectedScreenIds, resultScreenIds);
|
||||||
|
}
|
||||||
|
|
||||||
private int getCount(SQLiteDatabase db, String sql) {
|
private int getCount(SQLiteDatabase db, String sql) {
|
||||||
try (Cursor c = db.rawQuery(sql, null)) {
|
try (Cursor c = db.rawQuery(sql, null)) {
|
||||||
return c.getCount();
|
return c.getCount();
|
||||||
|
|
Loading…
Reference in New Issue