Refreshing photo cache when list is reloaded

Bug: 2781900
Change-Id: Ia224c3906beab4084a1c91cfe42a8e42e7521adc
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 7cfd672..d0d0a91 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -324,6 +324,10 @@
             ((DirectoryPartition)partition).setStatus(DirectoryPartition.STATUS_LOADED);
         }
 
+        if (mDisplayPhotos && mPhotoLoader != null && isPhotoSupported(partitionIndex)) {
+            mPhotoLoader.refreshCache();
+        }
+
         super.changeCursor(partitionIndex, cursor);
 
         if (isSectionHeaderDisplayEnabled() && partitionIndex == getIndexedPartition()) {
diff --git a/src/com/android/contacts/list/ContactPhotoLoader.java b/src/com/android/contacts/list/ContactPhotoLoader.java
index 83e9131..06b79d0 100644
--- a/src/com/android/contacts/list/ContactPhotoLoader.java
+++ b/src/com/android/contacts/list/ContactPhotoLoader.java
@@ -79,6 +79,7 @@
         private static final int NEEDED = 0;
         private static final int LOADING = 1;
         private static final int LOADED = 2;
+        private static final int REFRESH_CACHE = 3;
 
         int state;
         SoftReference<Bitmap> bitmapRef;
@@ -176,6 +177,19 @@
     }
 
     /**
+     * Mark all cached photos for reloading.  We can continue using cache but should
+     * also make sure the photos haven't changed in the background and notify the views
+     * if so.
+     */
+    public void refreshCache() {
+        for (BitmapHolder holder : mBitmapCache.values()) {
+            if (holder.state == BitmapHolder.LOADED && holder.bitmapRef.get() != null) {
+                holder.state = BitmapHolder.REFRESH_CACHE;
+            }
+        }
+    }
+
+    /**
      * Checks if the photo is present in cache.  If so, sets the photo on the view,
      * otherwise sets the state of the photo to {@link BitmapHolder#NEEDED} and
      * temporarily set the image to the default resource ID.
@@ -185,22 +199,30 @@
         if (holder == null) {
             holder = new BitmapHolder();
             mBitmapCache.put(key, holder);
-        } else if (holder.state == BitmapHolder.LOADED) {
-            // Null bitmap reference means that database contains no bytes for the photo
-            if (holder.bitmapRef == null) {
-                view.setImageResource(mDefaultResourceId);
-                return true;
+        } else {
+            boolean freshCache = true;
+            if (holder.state == BitmapHolder.REFRESH_CACHE) {
+                freshCache = false;
+                holder.state = BitmapHolder.NEEDED;
             }
 
-            Bitmap bitmap = holder.bitmapRef.get();
-            if (bitmap != null) {
-                view.setImageBitmap(bitmap);
-                return true;
-            }
+            if (holder.state == BitmapHolder.LOADED || freshCache) {
+                // Null bitmap reference means that database contains no bytes for the photo
+                if (holder.bitmapRef == null) {
+                    view.setImageResource(mDefaultResourceId);
+                    return freshCache;
+                }
 
-            // Null bitmap means that the soft reference was released by the GC
-            // and we need to reload the photo.
-            holder.bitmapRef = null;
+                Bitmap bitmap = holder.bitmapRef.get();
+                if (bitmap != null) {
+                    view.setImageBitmap(bitmap);
+                    return freshCache;
+                }
+
+                // Null bitmap means that the soft reference was released by the GC
+                // and we need to reload the photo.
+                holder.bitmapRef = null;
+            }
         }
 
         // The bitmap has not been loaded - should display the placeholder image.