Load bookmarks asynchronously

 Bug: 5297900

Change-Id: I8b728cfe06799099e21c402d5da7087507209ffa
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
index fcc3f27..be3c211 100644
--- a/src/com/android/browser/BrowserBookmarksAdapter.java
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -19,19 +19,24 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
 import android.provider.BrowserContract.Bookmarks;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.CursorAdapter;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 import android.widget.TextView;
 
-public class BrowserBookmarksAdapter extends CursorAdapter {
+import com.android.browser.util.ThreadedCursorAdapter;
+import com.android.browser.view.BookmarkContainer;
+
+public class BrowserBookmarksAdapter extends
+        ThreadedCursorAdapter<BrowserBookmarksAdapterItem> {
+
     LayoutInflater mInflater;
     int mCurrentView;
+    Context mContext;
 
     /**
      *  Create a new BrowserBookmarksAdapter.
@@ -39,30 +44,53 @@
     public BrowserBookmarksAdapter(Context context, int defaultView) {
         // Make sure to tell the CursorAdapter to avoid the observer and auto-requery
         // since the Loader will do that for us.
-        super(context, null, 0);
+        super(context, null);
         mInflater = LayoutInflater.from(context);
+        mContext = context;
         selectView(defaultView);
     }
 
     @Override
-    public void bindView(View view, Context context, Cursor cursor) {
+    public View newView(Context context, ViewGroup parent) {
         if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
-            bindListView(view, context, cursor);
+            return mInflater.inflate(R.layout.bookmark_list, parent, false);
         } else {
-            bindGridView(view, context, cursor);
+            return mInflater.inflate(R.layout.bookmark_thumbnail, parent, false);
         }
     }
 
-    CharSequence getTitle(Cursor cursor, Context context) {
+    @Override
+    public void bindView(View view, BrowserBookmarksAdapterItem object) {
+        BookmarkContainer container = (BookmarkContainer) view;
+        container.setIgnoreRequestLayout(true);
+        if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+            bindListView(view, mContext, object);
+        } else {
+            bindGridView(view, mContext, object);
+        }
+        container.setIgnoreRequestLayout(false);
+    }
+
+    void clearView(View view) {
+        if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+            ImageView favicon = (ImageView) view.findViewById(R.id.favicon);
+            favicon.setImageBitmap(null);
+        } else {
+            ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
+            thumb.setImageBitmap(null);
+        }
+    }
+
+    CharSequence getTitle(Cursor cursor) {
         int type = cursor.getInt(BookmarksLoader.COLUMN_INDEX_TYPE);
         switch (type) {
         case Bookmarks.BOOKMARK_TYPE_OTHER_FOLDER:
-            return context.getText(R.string.other_bookmarks);
+            return mContext.getText(R.string.other_bookmarks);
         }
         return cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
     }
 
-    void bindGridView(View view, Context context, Cursor cursor) {
+    void bindGridView(View view, Context context, BrowserBookmarksAdapterItem item) {
         // We need to set this to handle rotation and other configuration change
         // events. If the padding didn't change, this is a no op.
         int padding = context.getResources()
@@ -72,63 +100,42 @@
         ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
         TextView tv = (TextView) view.findViewById(R.id.label);
 
-        tv.setText(getTitle(cursor, context));
-        if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
+        tv.setText(item.title);
+        if (item.is_folder) {
             // folder
             thumb.setImageResource(R.drawable.thumb_bookmark_widget_folder_holo);
             thumb.setScaleType(ScaleType.FIT_END);
-            thumb.setBackgroundDrawable(null);
+            thumb.setBackground(null);
         } else {
-            byte[] thumbData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_THUMBNAIL);
-            Bitmap thumbBitmap = null;
-            if (thumbData != null) {
-                thumbBitmap = BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length);
-            }
-
             thumb.setScaleType(ScaleType.CENTER_CROP);
-            if (thumbBitmap == null) {
+            if (item.thumbnail == null) {
                 thumb.setImageResource(R.drawable.browser_thumbnail);
             } else {
-                thumb.setImageBitmap(thumbBitmap);
+                thumb.setImageDrawable(item.thumbnail);
             }
             thumb.setBackgroundResource(R.drawable.border_thumb_bookmarks_widget_holo);
         }
     }
 
-    void bindListView(View view, Context context, Cursor cursor) {
+    void bindListView(View view, Context context, BrowserBookmarksAdapterItem item) {
         ImageView favicon = (ImageView) view.findViewById(R.id.favicon);
         TextView tv = (TextView) view.findViewById(R.id.label);
 
-        tv.setText(getTitle(cursor, context));
-        if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
+        tv.setText(item.title);
+        if (item.is_folder) {
             // folder
             favicon.setImageResource(R.drawable.ic_folder_holo_dark);
-            favicon.setBackgroundDrawable(null);
+            favicon.setBackground(null);
         } else {
-            byte[] faviconData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
-            Bitmap faviconBitmap = null;
-            if (faviconData != null) {
-                faviconBitmap = BitmapFactory.decodeByteArray(faviconData, 0, faviconData.length);
-            }
-
-            if (faviconBitmap == null) {
+            if (item.favicon == null) {
                 favicon.setImageResource(R.drawable.app_web_browser_sm);
             } else {
-                favicon.setImageBitmap(faviconBitmap);
+                favicon.setImageDrawable(item.favicon);
             }
             favicon.setBackgroundResource(R.drawable.bookmark_list_favicon_bg);
         }
     }
 
-    @Override
-    public View newView(Context context, Cursor cursor, ViewGroup parent) {
-        if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
-            return mInflater.inflate(R.layout.bookmark_list, parent, false);
-        } else {
-            return mInflater.inflate(R.layout.bookmark_thumbnail, parent, false);
-        }
-    }
-
     public void selectView(int view) {
         if (view != BrowserBookmarksPage.VIEW_LIST
                 && view != BrowserBookmarksPage.VIEW_THUMBNAILS) {
@@ -142,7 +149,34 @@
     }
 
     @Override
-    public Cursor getItem(int position) {
-        return (Cursor) super.getItem(position);
+    public BrowserBookmarksAdapterItem getRowObject(Cursor c,
+            BrowserBookmarksAdapterItem item) {
+        if (item == null) {
+            item = new BrowserBookmarksAdapterItem();
+        }
+        Bitmap favicon = item.favicon != null ? item.favicon.getBitmap() : null;
+        Bitmap thumbnail = item.thumbnail != null ? item.thumbnail.getBitmap() : null;
+        favicon = BrowserBookmarksPage.getBitmap(c,
+                BookmarksLoader.COLUMN_INDEX_FAVICON, favicon);
+        thumbnail = BrowserBookmarksPage.getBitmap(c,
+                BookmarksLoader.COLUMN_INDEX_THUMBNAIL, thumbnail);
+        if (favicon != null
+                && (item.favicon == null || item.favicon.getBitmap() != favicon)) {
+            item.favicon = new BitmapDrawable(mContext.getResources(), favicon);
+        }
+        if (thumbnail != null
+                && (item.thumbnail == null || item.thumbnail.getBitmap() != thumbnail)) {
+            item.thumbnail = new BitmapDrawable(mContext.getResources(), thumbnail);
+        }
+        item.is_folder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+        item.title = getTitle(c);
+        item.url = c.getString(BookmarksLoader.COLUMN_INDEX_URL);
+        return item;
+    }
+
+    @Override
+    public BrowserBookmarksAdapterItem getLoadingObject() {
+        BrowserBookmarksAdapterItem item = new BrowserBookmarksAdapterItem();
+        return item;
     }
 }