mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-03 09:26:51 +00:00
Defend against overlapping items in the workspace.
Should the Launcher's database become corrupted by mysterious forces (e.g.: third-party launchers; botched upgrades; smoke monsters) in such a way as to cause two items to share the same cell, we now ignore loading the latter. Prevents a runtime crash (http://b/2655516). Bug: 2655516 Change-Id: Ia514746f04f0e51b2cd07e9290589a6eab75bdd2
This commit is contained in:
@@ -137,4 +137,9 @@ class ItemInfo {
|
||||
|
||||
void unbind() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Item(id=" + this.id + " type=" + this.itemType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class LauncherAppWidgetInfo extends ItemInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(appWidgetId);
|
||||
return "AppWidget(id=" + Integer.toString(appWidgetId) + ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -670,6 +670,28 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
// check & update map of what's occupied; used to discard overlapping/invalid items
|
||||
private boolean checkItemPlacement(ItemInfo occupied[][][], ItemInfo item) {
|
||||
for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
|
||||
for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
|
||||
if (occupied[item.screen][x][y] != null) {
|
||||
Log.e(TAG, "Error loading shortcut " + item
|
||||
+ " into cell (" + item.screen + ":"
|
||||
+ x + "," + y
|
||||
+ ") occupied by "
|
||||
+ occupied[item.screen][x][y]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
|
||||
for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
|
||||
occupied[item.screen][x][y] = item;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void loadWorkspace() {
|
||||
long t = SystemClock.uptimeMillis();
|
||||
|
||||
@@ -688,6 +710,8 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
final Cursor c = contentResolver.query(
|
||||
LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
|
||||
|
||||
final ItemInfo occupied[][][] = new ItemInfo[Launcher.SCREEN_COUNT][Launcher.NUMBER_CELLS_X][Launcher.NUMBER_CELLS_Y];
|
||||
|
||||
try {
|
||||
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
|
||||
final int intentIndex = c.getColumnIndexOrThrow
|
||||
@@ -762,6 +786,11 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
info.cellX = c.getInt(cellXIndex);
|
||||
info.cellY = c.getInt(cellYIndex);
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, info)) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
|
||||
mItems.add(info);
|
||||
@@ -798,6 +827,11 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
folderInfo.cellX = c.getInt(cellXIndex);
|
||||
folderInfo.cellY = c.getInt(cellYIndex);
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, folderInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
|
||||
mItems.add(folderInfo);
|
||||
@@ -841,7 +875,12 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
liveFolderInfo.cellY = c.getInt(cellYIndex);
|
||||
liveFolderInfo.baseIntent = intent;
|
||||
liveFolderInfo.displayMode = c.getInt(displayModeIndex);
|
||||
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, liveFolderInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
|
||||
iconResourceIndex, liveFolderInfo);
|
||||
|
||||
@@ -884,6 +923,11 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
appWidgetInfo.container = c.getInt(containerIndex);
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, appWidgetInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mAppWidgets.add(appWidgetInfo);
|
||||
}
|
||||
break;
|
||||
@@ -916,6 +960,19 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
|
||||
Log.d(TAG, "workspace layout: ");
|
||||
for (int y = 0; y < Launcher.NUMBER_CELLS_Y; y++) {
|
||||
String line = "";
|
||||
for (int s = 0; s < Launcher.SCREEN_COUNT; s++) {
|
||||
if (s > 0) {
|
||||
line += " | ";
|
||||
}
|
||||
for (int x = 0; x < Launcher.NUMBER_CELLS_X; x++) {
|
||||
line += ((occupied[s][x][y] != null) ? "#" : ".");
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "[ " + line + " ]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user