Recover when reading corrupted widget previews

Bug: 10785722
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index eead085..1598e2b 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2477,7 +2477,7 @@
                     for (int i=0; i<N; i++) {
                         if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]);
                         mBgAllAppsList.updatePackage(context, packages[i]);
-                        WidgetPreviewLoader.removeFromDb(
+                        WidgetPreviewLoader.removePackageFromDb(
                                 mApp.getWidgetPreviewCacheDb(), packages[i]);
                     }
                     break;
@@ -2486,7 +2486,7 @@
                     for (int i=0; i<N; i++) {
                         if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
                         mBgAllAppsList.removePackage(packages[i]);
-                        WidgetPreviewLoader.removeFromDb(
+                        WidgetPreviewLoader.removePackageFromDb(
                                 mApp.getWidgetPreviewCacheDb(), packages[i]);
                     }
                     break;
diff --git a/src/com/android/launcher3/PackageChangedReceiver.java b/src/com/android/launcher3/PackageChangedReceiver.java
index 75a1e09..e59f6d8 100644
--- a/src/com/android/launcher3/PackageChangedReceiver.java
+++ b/src/com/android/launcher3/PackageChangedReceiver.java
@@ -16,6 +16,6 @@
         // in rare cases the receiver races with the application to set up LauncherAppState
         LauncherAppState.setApplicationContext(context.getApplicationContext());
         LauncherAppState app = LauncherAppState.getInstance();
-        WidgetPreviewLoader.removeFromDb(app.getWidgetPreviewCacheDb(), packageName);
+        WidgetPreviewLoader.removePackageFromDb(app.getWidgetPreviewCacheDb(), packageName);
     }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 11c12f8..1910ab7 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -159,11 +159,12 @@
     }
 
     public Bitmap getPreview(final Object o) {
-        String name = getObjectName(o);
+        final String name = getObjectName(o);
+        final String packageName = getObjectPackage(o);
         // check if the package is valid
         boolean packageValid = true;
         synchronized(sInvalidPackages) {
-            packageValid = !sInvalidPackages.contains(getObjectPackage(o));
+            packageValid = !sInvalidPackages.contains(packageName);
         }
         if (!packageValid) {
             return null;
@@ -334,7 +335,7 @@
         db.insert(CacheDb.TABLE_NAME, null, values);
     }
 
-    public static void removeFromDb(final CacheDb cacheDb, final String packageName) {
+    public static void removePackageFromDb(final CacheDb cacheDb, final String packageName) {
         synchronized(sInvalidPackages) {
             sInvalidPackages.add(packageName);
         }
@@ -356,6 +357,18 @@
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
     }
 
+    public static void removeItemFromDb(final CacheDb cacheDb, final String objectName) {
+        new AsyncTask<Void, Void, Void>() {
+            public Void doInBackground(Void ... args) {
+                SQLiteDatabase db = cacheDb.getWritableDatabase();
+                db.delete(CacheDb.TABLE_NAME,
+                        CacheDb.COLUMN_NAME + " = ? ", // SELECT query
+                        new String[] { objectName }); // args to SELECT query
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
+    }
+
     private Bitmap readFromDb(String name, Bitmap b) {
         if (mCachedSelectQuery == null) {
             mCachedSelectQuery = CacheDb.COLUMN_NAME + " = ? AND " +
@@ -377,8 +390,12 @@
             final BitmapFactory.Options opts = mCachedBitmapFactoryOptions.get();
             opts.inBitmap = b;
             opts.inSampleSize = 1;
-            Bitmap out = BitmapFactory.decodeByteArray(blob, 0, blob.length, opts);
-            return out;
+            try {
+                return BitmapFactory.decodeByteArray(blob, 0, blob.length, opts);
+            } catch (IllegalArgumentException e) {
+                removeItemFromDb(mDb, name);
+                return null;
+            }
         } else {
             result.close();
             return null;