From acf42c36837b7d311df186db59c707abf316f999 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 31 Oct 2012 12:34:32 +0000 Subject: [PATCH] Bug 785945 - Load top site thumbnails asynchronously in about:home (r=mfinkle) --- mobile/android/base/AboutHomeContent.java | 130 ++++++++++++++---- mobile/android/base/db/LocalBrowserDB.java | 3 +- .../android/base/resources/values/styles.xml | 2 +- 3 files changed, 102 insertions(+), 33 deletions(-) diff --git a/mobile/android/base/AboutHomeContent.java b/mobile/android/base/AboutHomeContent.java index 8c51603c227..384c43293a2 100644 --- a/mobile/android/base/AboutHomeContent.java +++ b/mobile/android/base/AboutHomeContent.java @@ -7,8 +7,10 @@ package org.mozilla.gecko; import org.mozilla.gecko.db.BrowserDB; import org.mozilla.gecko.db.BrowserDB.URLColumns; +import org.mozilla.gecko.db.BrowserContract.Images; import org.mozilla.gecko.sync.setup.SyncAccounts; import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity; +import org.mozilla.gecko.util.GeckoAsyncTask; import org.json.JSONArray; import org.json.JSONException; @@ -60,7 +62,9 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -250,9 +254,8 @@ public class AboutHomeContent extends ScrollView mTopSitesAdapter = new TopSitesCursorAdapter(mActivity, R.layout.abouthome_topsite_item, mCursor, - new String[] { URLColumns.TITLE, - URLColumns.THUMBNAIL }, - new int[] { R.id.title, R.id.thumbnail }); + new String[] { URLColumns.TITLE }, + new int[] { R.id.title }); mTopSitesAdapter.setViewBinder(new TopSitesViewBinder()); mTopSitesGrid.setAdapter(mTopSitesAdapter); @@ -260,6 +263,9 @@ public class AboutHomeContent extends ScrollView mTopSitesAdapter.changeCursor(mCursor); } + if (mTopSitesAdapter.getCount() > 0) + loadTopSitesThumbnails(resolver); + updateLayout(syncIsSetup); // Free the old Cursor in the right thread now. @@ -275,6 +281,97 @@ public class AboutHomeContent extends ScrollView }); } + private List getTopSitesUrls() { + List urls = new ArrayList(); + + Cursor c = mTopSitesAdapter.getCursor(); + if (c == null || !c.moveToFirst()) + return urls; + + do { + final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); + urls.add(url); + } while (c.moveToNext()); + + return urls; + } + + private void displayThumbnail(View view, Bitmap thumbnail) { + ImageView thumbnailView = (ImageView) view.findViewById(R.id.thumbnail); + + if (thumbnail == null) { + thumbnailView.setImageResource(R.drawable.abouthome_thumbnail_bg); + thumbnailView.setScaleType(ImageView.ScaleType.FIT_CENTER); + } else { + try { + thumbnailView.setImageBitmap(thumbnail); + thumbnailView.setScaleType(ImageView.ScaleType.CENTER_CROP); + } catch (OutOfMemoryError oom) { + Log.e(LOGTAG, "Unable to load thumbnail bitmap", oom); + thumbnailView.setImageResource(R.drawable.abouthome_thumbnail_bg); + thumbnailView.setScaleType(ImageView.ScaleType.FIT_CENTER); + } + } + } + + private void updateTopSitesThumbnails(Map thumbnails) { + for (int i = 0; i < mTopSitesGrid.getChildCount(); i++) { + final View view = mTopSitesGrid.getChildAt(i); + + Cursor c = (Cursor) mTopSitesGrid.getItemAtPosition(i); + final String url = c.getString(c.getColumnIndex(URLColumns.URL)); + + displayThumbnail(view, thumbnails.get(url)); + } + + mTopSitesGrid.invalidate(); + } + + public Map getTopSitesThumbnails(Cursor c) { + Map thumbnails = new HashMap(); + + try { + if (c == null || !c.moveToFirst()) + return thumbnails; + + do { + final String url = c.getString(c.getColumnIndexOrThrow(Images.URL)); + final byte[] b = c.getBlob(c.getColumnIndexOrThrow(Images.THUMBNAIL)); + if (b == null) + continue; + + Bitmap thumbnail = BitmapFactory.decodeByteArray(b, 0, b.length); + if (thumbnail == null) + continue; + + thumbnails.put(url, thumbnail); + } while (c.moveToNext()); + } finally { + if (c != null) + c.close(); + } + + return thumbnails; + } + + private void loadTopSitesThumbnails(final ContentResolver cr) { + final List urls = getTopSitesUrls(); + if (urls.size() == 0) + return; + + (new GeckoAsyncTask(GeckoApp.mAppContext, GeckoAppShell.getHandler()) { + @Override + public Cursor doInBackground(Void... params) { + return BrowserDB.getThumbnailsForUrls(cr, urls); + } + + @Override + public void onPostExecute(Cursor c) { + updateTopSitesThumbnails(getTopSitesThumbnails(c)); + } + }).execute(); + } + void update(final EnumSet flags) { GeckoAppShell.getHandler().post(new Runnable() { public void run() { @@ -642,28 +739,6 @@ public class AboutHomeContent extends ScrollView } class TopSitesViewBinder implements SimpleCursorAdapter.ViewBinder { - private boolean updateThumbnail(View view, Cursor cursor, int thumbIndex) { - byte[] b = cursor.getBlob(thumbIndex); - ImageView thumbnail = (ImageView) view; - - if (b == null) { - thumbnail.setImageResource(R.drawable.abouthome_thumbnail_bg); - thumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER); - } else { - try { - Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length); - thumbnail.setImageBitmap(bitmap); - thumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); - } catch (OutOfMemoryError oom) { - Log.e(LOGTAG, "Unable to load thumbnail bitmap", oom); - thumbnail.setImageResource(R.drawable.abouthome_thumbnail_bg); - thumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER); - } - } - - return true; - } - private boolean updateTitle(View view, Cursor cursor, int titleIndex) { String title = cursor.getString(titleIndex); TextView titleView = (TextView) view; @@ -686,11 +761,6 @@ public class AboutHomeContent extends ScrollView return updateTitle(view, cursor, titleIndex); } - int thumbIndex = cursor.getColumnIndexOrThrow(URLColumns.THUMBNAIL); - if (columnIndex == thumbIndex) { - return updateThumbnail(view, cursor, thumbIndex); - } - // Other columns are handled automatically return false; } diff --git a/mobile/android/base/db/LocalBrowserDB.java b/mobile/android/base/db/LocalBrowserDB.java index 75377ba8335..8526a9b65b9 100644 --- a/mobile/android/base/db/LocalBrowserDB.java +++ b/mobile/android/base/db/LocalBrowserDB.java @@ -194,8 +194,7 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface { return filterAllSites(cr, new String[] { Combined._ID, Combined.URL, - Combined.TITLE, - Combined.THUMBNAIL }, + Combined.TITLE }, "", limit, BrowserDB.ABOUT_PAGES_URL_FILTER); diff --git a/mobile/android/base/resources/values/styles.xml b/mobile/android/base/resources/values/styles.xml index 8a9484741c8..30cea98f0f5 100644 --- a/mobile/android/base/resources/values/styles.xml +++ b/mobile/android/base/resources/values/styles.xml @@ -218,7 +218,7 @@ @dimen/abouthome_icon_radius 0dip 0dip - centerCrop + fitCenter