Bug 885519: Show favicons if there is no thumbnail available. [r=lucasr]
authorSriram Ramasubramanian <sriram@mozilla.com>
Fri, 21 Jun 2013 16:47:40 -0700
changeset 143357 3d60ab3e61b629bfd91a45351319748278d47fef
parent 143356 03069010d40f7de094f9573a961b0f2e42ec3b6b
child 143358 ce84e7c8901cb12853c54155f104e17934eeaff4
push id25130
push userlrocha@mozilla.com
push dateWed, 21 Aug 2013 09:41:27 +0000
treeherdermozilla-central@b2486721572e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs885519
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 885519: Show favicons if there is no thumbnail available. [r=lucasr]
mobile/android/base/home/TopBookmarksView.java
--- a/mobile/android/base/home/TopBookmarksView.java
+++ b/mobile/android/base/home/TopBookmarksView.java
@@ -11,16 +11,17 @@ import org.mozilla.gecko.db.BrowserContr
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.db.BrowserDB.TopSitesCursorWrapper;
 import org.mozilla.gecko.db.BrowserDB.URLColumns;
 import org.mozilla.gecko.gfx.BitmapUtils;
 import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.UiAsyncTask;
 
+import android.content.ContentResolver;
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
@@ -48,17 +49,33 @@ public class TopBookmarksView extends Gr
 
     // On URL open listener.
     private OnUrlOpenListener mUrlOpenListener;
 
     // A cursor based adapter backing this view.
     protected TopBookmarksAdapter mAdapter;
 
     // Temporary cache to store the thumbnails until the next layout pass.
-    private Map<String, Bitmap> mThumbnailsCache;
+    private Map<String, Thumbnail> mThumbnailsCache;
+
+    /**
+     *  Class to hold the bitmap of cached thumbnails/favicons.
+     */
+    private class Thumbnail {
+        // Thumbnail or favicon.
+        private final boolean isThumbnail;
+
+        // Bitmap of thumbnail/favicon.
+        private final Bitmap bitmap;
+
+        public Thumbnail(Bitmap bitmap, boolean isThumbnail) {
+            this.bitmap = bitmap;
+            this.isThumbnail = isThumbnail;
+        }
+    }
 
     public TopBookmarksView(Context context) {
         this(context, null);
     }
 
     public TopBookmarksView(Context context, AttributeSet attrs) {
         this(context, attrs, R.attr.topBookmarksViewStyle);
     }
@@ -202,17 +219,17 @@ public class TopBookmarksView extends Gr
         mUrlOpenListener = listener;
     }
 
     /**
      * Update the thumbnails returned by the db.
      *
      * @param thumbnails A map of urls and their thumbnail bitmaps.
      */
-    private void updateThumbnails(Map<String, Bitmap> thumbnails) {
+    private void updateThumbnails(Map<String, Thumbnail> thumbnails) {
         final int count = mAdapter.getCount();
         for (int i = 0; i < count; i++) {
             final View child = getChildAt(i);
 
             // The grid view might get temporarily out of sync with the
             // adapter refreshes (e.g. on device rotation).
             if (child == null) {
                 continue;
@@ -221,18 +238,24 @@ public class TopBookmarksView extends Gr
             TopBookmarkItemView view = (TopBookmarkItemView) child;
             final String url = view.getUrl();
 
             // If there is no url, then show "add bookmark".
             if (TextUtils.isEmpty(url)) {
                 view.displayThumbnail(R.drawable.abouthome_thumbnail_add);
             } else {
                 // Show the thumbnail.
-                Bitmap bitmap = (thumbnails != null ? thumbnails.get(url) : null);
-                view.displayThumbnail(bitmap);
+                Thumbnail thumbnail = (thumbnails != null ? thumbnails.get(url) : null);
+                if (thumbnail == null) {
+                    view.displayThumbnail(null);
+                } else if (thumbnail.isThumbnail) {
+                    view.displayThumbnail(thumbnail.bitmap);
+                } else {
+                    view.displayFavicon(thumbnail.bitmap);
+                }
             }
         }
     }
 
     /**
      * A cursor adapter holding the pinned and top bookmarks.
      */
     public class TopBookmarksAdapter extends CursorAdapter {
@@ -312,71 +335,79 @@ public class TopBookmarksView extends Gr
                 new LoadThumbnailsTask().execute(cursor);
             }
         }
     }
 
     /**
      * An AsyncTask to load the thumbnails from a cursor.
      */
-    private class LoadThumbnailsTask extends UiAsyncTask<Cursor, Void, Map<String,Bitmap>> {
+    private class LoadThumbnailsTask extends UiAsyncTask<Cursor, Void, Map<String, Thumbnail>> {
         public LoadThumbnailsTask() {
             super(ThreadUtils.getBackgroundHandler());
         }
 
         @Override
-        protected Map<String, Bitmap> doInBackground(Cursor... params) {
+        protected Map<String, Thumbnail> doInBackground(Cursor... params) {
             // TopBookmarksAdapter's cursor.
             final Cursor adapterCursor = params[0];
             if (adapterCursor == null || !adapterCursor.moveToFirst()) {
                 return null;
             }
 
             final List<String> urls = new ArrayList<String>();
             do {
                 final String url = adapterCursor.getString(adapterCursor.getColumnIndexOrThrow(URLColumns.URL));
                 urls.add(url);
             } while(adapterCursor.moveToNext());
 
             if (urls.size() == 0) {
                 return null;
             }
 
-            Map<String, Bitmap> thumbnails = new HashMap<String, Bitmap>();
-            Cursor cursor = BrowserDB.getThumbnailsForUrls(getContext().getContentResolver(), urls);
-            if (cursor == null || !cursor.moveToFirst()) {
-                return null;
-            }
+            final Map<String, Thumbnail> thumbnails = new HashMap<String, Thumbnail>();
+
+            // Query the DB for thumbnails.
+            final ContentResolver cr = getContext().getContentResolver();
+            final Cursor cursor = BrowserDB.getThumbnailsForUrls(cr, urls);
 
             try {
-                do {
-                    final String url = cursor.getString(cursor.getColumnIndexOrThrow(Thumbnails.URL));
-                    final byte[] b = cursor.getBlob(cursor.getColumnIndexOrThrow(Thumbnails.DATA));
-                    if (b == null) {
-                        continue;
-                    }
+                if (cursor != null && cursor.moveToFirst()) {
+                    do {
+                        // Try to get the thumbnail, if cursor is valid.
+                        String url = cursor.getString(cursor.getColumnIndexOrThrow(Thumbnails.URL));
+                        final byte[] b = cursor.getBlob(cursor.getColumnIndexOrThrow(Thumbnails.DATA));
+                        final Bitmap bitmap = (b == null ? null : BitmapUtils.decodeByteArray(b));
 
-                    Bitmap thumbnail = BitmapUtils.decodeByteArray(b);
-                    if (thumbnail == null) {
-                        continue;
-                    }
-
-                    thumbnails.put(url, thumbnail);
-                } while (cursor.moveToNext());
+                        if (bitmap != null) {
+                            thumbnails.put(url, new Thumbnail(bitmap, true));
+                        }
+                    } while (cursor.moveToNext());
+                }
             } finally {
                 if (cursor != null) {
                     cursor.close();
                 }
             }
 
+            // Query the DB for favicons for the urls without thumbnails.
+            for (String url : urls) {
+                if (!thumbnails.containsKey(url)) {
+                    final Bitmap bitmap = BrowserDB.getFaviconForUrl(cr, url);
+                    if (bitmap != null) {
+                        thumbnails.put(url, new Thumbnail(bitmap, true));
+                    }
+                }
+            }
+
             return thumbnails;
         }
 
         @Override
-        public void onPostExecute(Map<String, Bitmap> thumbnails) {
+        public void onPostExecute(Map<String, Thumbnail> thumbnails) {
             // If there's a layout scheduled on this view, wait for it to happen
             // by storing the thumbnails in a cache. If not, update them right away.
             if (isLayoutRequested()) {
                 mThumbnailsCache = thumbnails;
             } else {
                 updateThumbnails(thumbnails);
             }
         }