Merge "Fix to prevent auto-thumbnailer to run on images whose decoding has failed (causing CPU cycles being wasted resulting in sometimes affecting performance of CPU intensive applications such as the video player)" into eclair
diff --git a/src/com/cooliris/cache/BootReceiver.java b/src/com/cooliris/cache/BootReceiver.java
index 35fc3c3..2ca5455 100644
--- a/src/com/cooliris/cache/BootReceiver.java
+++ b/src/com/cooliris/cache/BootReceiver.java
@@ -58,6 +58,7 @@
             PicasaDataSource.sThumbnailCache.close();
             CacheService.sAlbumCache.close();
             CacheService.sMetaAlbumCache.close();
+            CacheService.sSkipThumbnailIds.flush();
         }
     }
 }
diff --git a/src/com/cooliris/cache/CacheService.java b/src/com/cooliris/cache/CacheService.java
index 602e207..6b8f9f0 100644
--- a/src/com/cooliris/cache/CacheService.java
+++ b/src/com/cooliris/cache/CacheService.java
@@ -57,6 +57,7 @@
     public static final String ACTION_CACHE = "com.cooliris.cache.action.CACHE";
     public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");
     public static final DiskCache sMetaAlbumCache = new DiskCache("local-meta-cache");
+    public static final DiskCache sSkipThumbnailIds = new DiskCache("local-skip-cache");
 
     private static final String TAG = "CacheService";
     private static ImageList sList = null;
@@ -603,14 +604,36 @@
             final long id = ids[i];
             final long timeModifiedInSec = timestamp[i];
             final long thumbnailId = thumbnailIds[i];
-            if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
-                buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
-                        DEFAULT_THUMBNAIL_HEIGHT, timeModifiedInSec * 1000);
+            if (!isInThumbnailerSkipList(thumbnailId)) {
+                if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
+                    byte[] retVal = buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
+                            DEFAULT_THUMBNAIL_HEIGHT, timeModifiedInSec * 1000);
+                    if (retVal == null || retVal.length == 0) {
+                        // There was an error in building the thumbnail.
+                        // We record this thumbnail id
+                        addToThumbnailerSkipList(thumbnailId);
+                    }
+                }
             }
         }
         Log.i(TAG, "DiskCache ready for all thumbnails.");
     }
 
+    private static void addToThumbnailerSkipList(long thumbnailId) {
+        sSkipThumbnailIds.put(thumbnailId, sDummyData, 0);
+        sSkipThumbnailIds.flush();
+    }
+
+    private static boolean isInThumbnailerSkipList(long thumbnailId) {
+        if (sSkipThumbnailIds.isDataAvailable(thumbnailId, 0)) {
+            byte[] data = sSkipThumbnailIds.get(thumbnailId, 0);
+            if (data.length > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static final byte[] buildThumbnailForId(final Context context, final DiskCache thumbnailCache, final long thumbId,
             final long origId, final boolean isVideo, final int thumbnailWidth, final int thumbnailHeight, final long timestamp) {
         if (origId == Shared.INVALID) {
@@ -650,7 +673,8 @@
             if (bitmap == null) {
                 return null;
             }
-            final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight, timestamp);
+            final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight,
+                    timestamp);
             return retVal;
         } catch (InterruptedException e) {
             return null;