handle some edge cases: many albums, deleted albums, and slow network.

Bug: 7258024
Change-Id: If9ab2ecf6bc12881854df83a637dc1fdb685552c
diff --git a/res/layout/settingslist.xml b/res/layout/settingslist.xml
index 2d82b99..114a789 100644
--- a/res/layout/settingslist.xml
+++ b/res/layout/settingslist.xml
@@ -13,10 +13,20 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
- <ListView xmlns:android="http://schemas.android.com/apk/res/android"
-           android:id="@android:id/list"
-           android:layout_width="match_parent"
-           android:layout_height="match_parent"
-           android:paddingLeft="16dp"
-           android:paddingRight="16dp"
-           />
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
+
+     <ListView android:id="@android:id/list"
+         android:layout_width="match_parent"
+         android:layout_height="match_parent"
+         android:paddingLeft="16dp"
+         android:paddingRight="16dp"
+         />
+
+    <ProgressBar android:id="@android:id/empty"
+         style="?android:attr/progressBarStyleLarge"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:layout_gravity="center"
+         />
+
+</FrameLayout>
diff --git a/src/com/android/dreams/phototable/AlbumDataAdapter.java b/src/com/android/dreams/phototable/AlbumDataAdapter.java
index 8682cd5..a0c039b 100644
--- a/src/com/android/dreams/phototable/AlbumDataAdapter.java
+++ b/src/com/android/dreams/phototable/AlbumDataAdapter.java
@@ -53,6 +53,12 @@
         mLayout = resource;
         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mListener = new ItemClickListener();
+
+        HashSet<String> validAlbumIds = new HashSet<String>(objects.size());
+        for (PhotoSource.AlbumData albumData: objects) {
+            validAlbumIds.add(albumData.id);
+        }
+        mSettings.pruneObsoleteSettings(validAlbumIds);
     }
 
     @Override
diff --git a/src/com/android/dreams/phototable/AlbumSettings.java b/src/com/android/dreams/phototable/AlbumSettings.java
index a719d4f..23dda46 100644
--- a/src/com/android/dreams/phototable/AlbumSettings.java
+++ b/src/com/android/dreams/phototable/AlbumSettings.java
@@ -17,6 +17,7 @@
 
 import android.content.SharedPreferences;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
@@ -69,6 +70,16 @@
         }
     }
 
+    public void pruneObsoleteSettings(Collection<String> validAlbums) {
+        if (!validAlbums.containsAll(mEnabledAlbums)) {
+            synchronized (mEnabledAlbums) {
+                readEnabledAlbumsLocked();
+                mEnabledAlbums.retainAll(validAlbums);
+                writeEnabledAlbumsLocked();
+            }
+        }
+    }
+
     public  boolean isConfigured() {
         synchronized (mEnabledAlbums) {
             return mEnabledAlbums.size() != 0;
diff --git a/src/com/android/dreams/phototable/FlipperDreamSettings.java b/src/com/android/dreams/phototable/FlipperDreamSettings.java
index d0d37bb..1252846 100644
--- a/src/com/android/dreams/phototable/FlipperDreamSettings.java
+++ b/src/com/android/dreams/phototable/FlipperDreamSettings.java
@@ -19,6 +19,7 @@
 import android.app.ListActivity;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.view.View;
 import android.widget.ListAdapter;
 
 import java.util.LinkedList;
@@ -56,6 +57,9 @@
            @Override
            public void onPostExecute(Void unused) {
                setListAdapter(mAdapter);
+               if (mAdapter.getCount() == 0) {
+                   findViewById(android.R.id.empty).setVisibility(View.GONE);
+               }
            }
         }.execute();
     }
diff --git a/src/com/android/dreams/phototable/PicasaSource.java b/src/com/android/dreams/phototable/PicasaSource.java
index bb1f1ec..8a3c751 100644
--- a/src/com/android/dreams/phototable/PicasaSource.java
+++ b/src/com/android/dreams/phototable/PicasaSource.java
@@ -19,11 +19,13 @@
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.net.Uri;
+import android.util.Log;
 
 import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Set;
@@ -98,22 +100,30 @@
             }
         }
 
+        if (albumIds.size() > mMaxPostAblums) {
+            Collections.shuffle(albumIds);
+        }
+
         StringBuilder selection = new StringBuilder();
+        int albumIdx = 0;
         for (String albumId : albumIds) {
-            if (albumIds.size() < mMaxPostAblums) {
+            if (albumIdx < mMaxPostAblums) {
                 if (selection.length() > 0) {
                     selection.append(" OR ");
                 }
-                selection.append(PICASA_ALBUM_ID + " = '" + albumId + "'");
                 log(TAG, "adding: " + albumId);
+                selection.append(PICASA_ALBUM_ID + " = '" + albumId + "'");
+            } else {
+                log(TAG, "too many albums, dropping: " + albumId);
             }
+            albumIdx++;
         }
 
         if (selection.length() == 0) {
             return foundImages;
         }
 
-        log(TAG, "selection is: " + selection.toString());
+        log(TAG, "selection is (" + selection.length() + "): " + selection.toString());
 
         Uri.Builder picasaUriBuilder = new Uri.Builder()
                 .scheme("content")
@@ -161,6 +171,8 @@
             }
 
             cursor.close();
+        } else {
+            Log.w(TAG, "received a null cursor in findImages()");
         }
         log(TAG, "found " + foundImages.size() + " items.");
         return foundImages;
@@ -183,6 +195,8 @@
                 displayName = cursor.getString(accountIndex);
             }
             cursor.close();
+        } else {
+            Log.w(TAG, "received a null cursor in resolveAccount()");
         }
         return displayName;
     }
@@ -209,6 +223,7 @@
         Cursor cursor = mResolver.query(picasaUriBuilder.build(),
                 projection, selection, null, order);
         if (cursor != null) {
+            log(TAG, " " + id + " resolved to " + cursor.getCount() + " albums");
             cursor.moveToFirst();
 
             int idIndex = cursor.getColumnIndex(PICASA_ID);
@@ -223,6 +238,8 @@
                 }
             }
             cursor.close();
+        } else {
+            Log.w(TAG, "received a null cursor in resolveAlbumIds()");
         }
         return albumIds;
     }
@@ -275,10 +292,12 @@
                     }
 
                     if (isPosts) {
+                        log(TAG, "replacing " + id + " with " + PICASA_POSTS_TYPE);
                         id = TAG + ":" + PICASA_POSTS_TYPE + ":" + user;
                     }
 
                     if (isUpload) {
+                        log(TAG, "replacing " + id + " with " + PICASA_UPLOAD_TYPE);
                         id = TAG + ":" + PICASA_UPLOAD_TYPE + ":" + user;
                     }
 
@@ -300,23 +319,21 @@
                             data.title = mUnknownAlbumName;
                         }
 
-                        if (thumbIndex >= 0) {
-                            thumbnailUrl = cursor.getString(thumbIndex);
-                        }
-
-                        if (updatedIndex >= 0) {
-                            updated = cursor.getLong(updatedIndex);
-                        }
-
                         log(TAG, "found " + data.title + "(" + data.id + ")" +
-                            " of type " + type + " owned by " + user);
+                                " of type " + type + " owned by " + user);
                         foundAlbums.put(id, data);
                     }
 
                     if (updatedIndex >= 0) {
-                        data.updated = (long) Math.max(data.updated, updated);
+                        updated = cursor.getLong(updatedIndex);
                     }
 
+                    if (thumbIndex >= 0) {
+                        thumbnailUrl = cursor.getString(thumbIndex);
+                    }
+
+                    data.updated = (long) Math.max(data.updated, updated);
+
                     if (data.thumbnailUrl == null || data.updated == updated) {
                         data.thumbnailUrl = thumbnailUrl;
                     }
@@ -326,6 +343,8 @@
             }
             cursor.close();
 
+        } else {
+            Log.w(TAG, "received a null cursor in findAlbums()");
         }
         log(TAG, "found " + foundAlbums.size() + " items.");
         mFoundAlbumIds = foundAlbums.keySet();