Move the creation of the HistoryAdapter to the background.

Bug 2611964

Change-Id: I675bb2de91a0bafe10b49e84abed92aff4e14b08
diff --git a/src/com/android/browser/BrowserDownloadAdapter.java b/src/com/android/browser/BrowserDownloadAdapter.java
index 0f8f721..f22c9fe 100644
--- a/src/com/android/browser/BrowserDownloadAdapter.java
+++ b/src/com/android/browser/BrowserDownloadAdapter.java
@@ -26,6 +26,7 @@
 import android.drm.mobile1.DrmRawContent;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Handler;
 import android.provider.Downloads;
 import android.text.format.Formatter;
 import android.view.LayoutInflater;
@@ -55,8 +56,9 @@
     private int mMimetypeColumnId;
     private int mDateColumnId;
 
-    public BrowserDownloadAdapter(Context context, Cursor c, int index) {
-        super(context, c, index);
+    public BrowserDownloadAdapter(Context context, Cursor c, int index,
+            Handler handler) {
+        super(context, c, index, handler);
         mTitleColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE);
         mDescColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_DESCRIPTION);
         mStatusColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
diff --git a/src/com/android/browser/BrowserDownloadPage.java b/src/com/android/browser/BrowserDownloadPage.java
index 18faf8b..bbf1191 100644
--- a/src/com/android/browser/BrowserDownloadPage.java
+++ b/src/com/android/browser/BrowserDownloadPage.java
@@ -63,6 +63,7 @@
     // Only meaningful while a ContentObserver is registered.  The ContextMenu
     // will be reopened on this View.
     private View                    mSelectedView;
+    private Handler                 mHandler;
 
     private final static String LOGTAG = "BrowserDownloadPage";
     @Override 
@@ -85,7 +86,7 @@
                 Downloads.Impl._DATA,
                 Downloads.Impl.COLUMN_MIME_TYPE},
                 null, Downloads.Impl.COLUMN_LAST_MODIFICATION + " DESC");
-        
+        mHandler = new Handler();
         // only attach everything to the listbox if we can access
         // the download database. Otherwise, just show it empty
         if (mDownloadCursor != null) {
@@ -99,7 +100,7 @@
             // Create a list "controller" for the data
             mDownloadAdapter = new BrowserDownloadAdapter(this, 
                     mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow(
-                    Downloads.Impl.COLUMN_LAST_MODIFICATION));
+                    Downloads.Impl.COLUMN_LAST_MODIFICATION), mHandler);
 
             setListAdapter(mDownloadAdapter);
             mListView.setOnCreateContextMenuListener(this);
@@ -241,8 +242,8 @@
      */
     private class ChangeObserver extends ContentObserver {
         private final Uri mTrack;
-        public ChangeObserver(Uri track) {
-            super(new Handler());
+        public ChangeObserver(Uri track, Handler handler) {
+            super(handler);
             mTrack = track;
         }
 
@@ -313,7 +314,7 @@
                     getContentResolver().unregisterContentObserver(
                             mContentObserver);
                 }
-                mContentObserver = new ChangeObserver(track);
+                mContentObserver = new ChangeObserver(track, mHandler);
                 mSelectedView = v;
                 getContentResolver().registerContentObserver(track, false,
                         mContentObserver);
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 23080f8..0281087 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -25,7 +25,10 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.os.ServiceManager;
 import android.provider.Browser;
 import android.text.IClipboard;
@@ -92,47 +95,75 @@
         }
     }
 
+    private static final int ADAPTER_CREATED = 1000;
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ADAPTER_CREATED:
+                    mAdapter = (HistoryAdapter) msg.obj;
+                    setListAdapter(mAdapter);
+                    final ExpandableListView list = getExpandableListView();
+                    // Add an empty view late, so it does not claim an empty
+                    // history before the adapter is present
+                    View v = new ViewStub(BrowserHistoryPage.this,
+                            R.layout.empty_history);
+                    addContentView(v, new LayoutParams(
+                            LayoutParams.MATCH_PARENT,
+                            LayoutParams.MATCH_PARENT));
+                    list.setEmptyView(v);
+                    list.setOnCreateContextMenuListener(
+                            BrowserHistoryPage.this);
+                    // Do not post the runnable if there is nothing in the list.
+                    if (list.getExpandableListAdapter().getGroupCount() > 0) {
+                        list.post(new Runnable() {
+                            public void run() {
+                                // In case the history gets cleared before this
+                                // event happens
+                                if (list.getExpandableListAdapter()
+                                        .getGroupCount() > 0) {
+                                    list.expandGroup(0);
+                                }
+                            }
+                        });
+                    }
+                    break;
+            }
+        }
+    };
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setTitle(R.string.browser_history);
 
-        final String whereClause = Browser.BookmarkColumns.VISITS + " > 0"
-                // In AddBookmarkPage, where we save new bookmarks, we add
-                // three visits to newly created bookmarks, so that
-                // bookmarks that have not been visited will show up in the
-                // most visited, and higher in the goto search box.
-                // However, this puts the site in the history, unless we
-                // ignore sites with a DATE of 0, which the next line does.
-                + " AND " + Browser.BookmarkColumns.DATE + " > 0";
-        final String orderBy = Browser.BookmarkColumns.DATE + " DESC";
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... unused) {
+                final String whereClause = Browser.BookmarkColumns.VISITS
+                        + " > 0"
+                        // In AddBookmarkPage, where we save new bookmarks, we
+                        // add three visits to newly created bookmarks, so that
+                        // bookmarks that have not been visited will show up in
+                        // the most visited, and higher in the goto search box.
+                        // However, this puts the site in the history, unless
+                        // we ignore sites with a DATE of 0, which the next
+                        // line does.
+                        + " AND " + Browser.BookmarkColumns.DATE + " > 0";
+                final String orderBy = Browser.BookmarkColumns.DATE + " DESC";
 
-        Cursor cursor = managedQuery(
-                Browser.BOOKMARKS_URI,
-                Browser.HISTORY_PROJECTION,
-                whereClause, null, orderBy);
+                Cursor cursor = managedQuery(
+                        Browser.BOOKMARKS_URI,
+                        Browser.HISTORY_PROJECTION,
+                        whereClause, null, orderBy);
 
-        mAdapter = new HistoryAdapter(this, cursor,
-                Browser.HISTORY_PROJECTION_DATE_INDEX);
-        setListAdapter(mAdapter);
-        final ExpandableListView list = getExpandableListView();
-        list.setOnCreateContextMenuListener(this);
-        View v = new ViewStub(this, R.layout.empty_history);
-        addContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-        list.setEmptyView(v);
-        // Do not post the runnable if there is nothing in the list.
-        if (list.getExpandableListAdapter().getGroupCount() > 0) {
-            list.post(new Runnable() {
-                public void run() {
-                    // In case the history gets cleared before this event
-                    // happens.
-                    if (list.getExpandableListAdapter().getGroupCount() > 0) {
-                        list.expandGroup(0);
-                    }
-                }
-            });
-        }
+                HistoryAdapter adapter = new HistoryAdapter(
+                        BrowserHistoryPage.this, cursor,
+                        Browser.HISTORY_PROJECTION_DATE_INDEX, mHandler);
+                mHandler.obtainMessage(ADAPTER_CREATED, adapter).sendToTarget();
+                return null;
+            }
+        }.execute();
         mDisableNewWindow = getIntent().getBooleanExtra("disable_new_window",
                 false);
 
@@ -153,6 +184,7 @@
 
     @Override
     protected void onDestroy() {
+        mHandler.removeCallbacksAndMessages(null);
         super.onDestroy();
         CombinedBookmarkHistoryActivity.getIconListenerSet()
                 .removeListener(mIconReceiver);
@@ -181,7 +213,7 @@
                 // CombinedBookmarkHistoryActivity
                 ((CombinedBookmarkHistoryActivity) getParent())
                         .removeParentChildRelationShips();
-                mAdapter.refreshData();
+                if (mAdapter != null) mAdapter.refreshData();
                 return true;
                 
             default:
@@ -265,7 +297,7 @@
                 return true;
             case R.id.delete_context_menu_id:
                 Browser.deleteFromHistory(getContentResolver(), url);
-                mAdapter.refreshData();
+                if (mAdapter != null) mAdapter.refreshData();
                 return true;
             case R.id.homepage_context_menu_id:
                 BrowserSettings.getInstance().setHomePage(this, url);
@@ -297,8 +329,9 @@
     }
 
     private class HistoryAdapter extends DateSortedExpandableListAdapter {
-        HistoryAdapter(Context context, Cursor cursor, int index) {
-            super(context, cursor, index);
+        HistoryAdapter(Context context, Cursor cursor, int index,
+                Handler handler) {
+            super(context, cursor, index, handler);
             
         }
 
diff --git a/src/com/android/browser/DateSortedExpandableListAdapter.java b/src/com/android/browser/DateSortedExpandableListAdapter.java
index 1d04493..f8261d8 100644
--- a/src/com/android/browser/DateSortedExpandableListAdapter.java
+++ b/src/com/android/browser/DateSortedExpandableListAdapter.java
@@ -51,8 +51,8 @@
     private Context mContext;
 
     private class ChangeObserver extends ContentObserver {
-        public ChangeObserver() {
-            super(new Handler());
+        public ChangeObserver(Handler handler) {
+            super(handler);
         }
 
         @Override
@@ -67,13 +67,13 @@
     }
 
     public DateSortedExpandableListAdapter(Context context, Cursor cursor,
-            int dateIndex) {
+            int dateIndex, Handler handler) {
         mContext = context;
         mDateSorter = new DateSorter(context);
         mObservers = new Vector<DataSetObserver>();
         mCursor = cursor;
         mIdIndex = cursor.getColumnIndexOrThrow(BaseColumns._ID);
-        cursor.registerContentObserver(new ChangeObserver());
+        cursor.registerContentObserver(new ChangeObserver(handler));
         mDateIndex = dateIndex;
         buildMap();
     }