diff options
author | Daniel Sandler <dsandler@android.com> | 2010-05-26 16:28:16 -0400 |
---|---|---|
committer | Daniel Sandler <dsandler@android.com> | 2010-05-26 16:50:49 -0400 |
commit | 8802e960495e61803c18ea3dda2e30ef0a611d8f (patch) | |
tree | 8ba0562e5dd9d24d457f338ec28ef7b875096b14 /src | |
parent | 3e297b57a0cb06450034a80893b5ede223b33552 (diff) | |
download | android_packages_apps_Trebuchet-8802e960495e61803c18ea3dda2e30ef0a611d8f.tar.gz android_packages_apps_Trebuchet-8802e960495e61803c18ea3dda2e30ef0a611d8f.tar.bz2 android_packages_apps_Trebuchet-8802e960495e61803c18ea3dda2e30ef0a611d8f.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher2/ItemInfo.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherAppWidgetInfo.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 59 |
3 files changed, 64 insertions, 2 deletions
diff --git a/src/com/android/launcher2/ItemInfo.java b/src/com/android/launcher2/ItemInfo.java index ca2ea86c8..a96d9aeb2 100644 --- a/src/com/android/launcher2/ItemInfo.java +++ b/src/com/android/launcher2/ItemInfo.java @@ -137,4 +137,9 @@ class ItemInfo { void unbind() { } + + @Override + public String toString() { + return "Item(id=" + this.id + " type=" + this.itemType + ")"; + } } diff --git a/src/com/android/launcher2/LauncherAppWidgetInfo.java b/src/com/android/launcher2/LauncherAppWidgetInfo.java index a28973bc4..8499ebb7c 100644 --- a/src/com/android/launcher2/LauncherAppWidgetInfo.java +++ b/src/com/android/launcher2/LauncherAppWidgetInfo.java @@ -49,7 +49,7 @@ class LauncherAppWidgetInfo extends ItemInfo { @Override public String toString() { - return Integer.toString(appWidgetId); + return "AppWidget(id=" + Integer.toString(appWidgetId) + ")"; } diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 612764984..26671ad2c 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -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 + " ]"); + } } } |