Initial pass at collapsable bookmarks

 Change bookmark view to show all bookmarks
 Group by account_name

Change-Id: I2c252c9f0e8d4df4271649dbe9bf3db336f921df
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 1dc2612..46197e9 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -16,7 +16,8 @@
 
 package com.android.browser;
 
-import com.android.browser.BreadCrumbView.Crumb;
+import com.android.browser.view.BookmarkExpandableGridView;
+import com.android.browser.view.BookmarkExpandableGridView.BookmarkContextMenuInfo;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -25,11 +26,11 @@
 import android.content.ClipboardManager;
 import android.content.ContentUris;
 import android.content.Context;
+import android.content.CursorLoader;
 import android.content.Intent;
 import android.content.Loader;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.Cursor;
@@ -40,6 +41,7 @@
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.provider.BrowserContract;
+import android.provider.BrowserContract.Accounts;
 import android.provider.BrowserContract.ChromeSyncColumns;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
@@ -50,116 +52,114 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.WebIconDatabase.IconListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.OnChildClickListener;
 import android.widget.ListView;
 import android.widget.PopupMenu.OnMenuItemClickListener;
 import android.widget.Toast;
 
+import java.util.HashMap;
+
 interface BookmarksPageCallbacks {
     // Return true if handled
     boolean onBookmarkSelected(Cursor c, boolean isFolder);
     // Return true if handled
     boolean onOpenInNewWindow(Cursor c);
-    void onFolderChanged(int level, Uri uri);
 }
 
 /**
  *  View showing the user's bookmarks in the browser.
  */
 public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
-        LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
-        BreadCrumbView.Controller, OnMenuItemClickListener, OnSharedPreferenceChangeListener {
+        LoaderManager.LoaderCallbacks<Cursor>, IconListener,
+        BreadCrumbView.Controller, OnMenuItemClickListener, OnChildClickListener {
 
     static final String LOGTAG = "browser";
 
-    static final int LOADER_BOOKMARKS = 1;
+    static final int LOADER_ACCOUNTS = 1;
+    static final int LOADER_BOOKMARKS = 100;
 
     static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
 
-    static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
-
     public static final String PREF_ACCOUNT_TYPE = "acct_type";
     public static final String PREF_ACCOUNT_NAME = "acct_name";
 
+    static final String ACCOUNT_TYPE = "account_type";
+    static final String ACCOUNT_NAME = "account_name";
+
     static final int VIEW_THUMBNAILS = 1;
     static final int VIEW_LIST = 2;
     static final String PREF_SELECTED_VIEW = "bookmarks_view";
 
     BookmarksPageCallbacks mCallbacks;
     View mRoot;
-    GridView mGrid;
+    BookmarkExpandableGridView mGrid;
     ListView mList;
-    BrowserBookmarksAdapter mAdapter;
     boolean mDisableNewWindow;
-    boolean mCanceled = false;
     boolean mEnableContextMenu = true;
-    boolean mShowRootFolder = false;
     View mEmptyView;
     int mCurrentView;
     View mHeader;
-    ViewGroup mHeaderContainer;
-    BreadCrumbView mCrumbs;
-    int mCrumbVisibility = View.VISIBLE;
-    int mCrumbMaxVisible = -1;
-    boolean mCrumbBackButton = false;
+    HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
 
     static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb,
             Bundle args, ViewGroup headerContainer) {
         BrowserBookmarksPage bbp = new BrowserBookmarksPage();
         bbp.mCallbacks = cb;
-        bbp.mHeaderContainer = headerContainer;
         bbp.setArguments(args);
         return bbp;
     }
 
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-        switch (id) {
-            case LOADER_BOOKMARKS: {
-                SharedPreferences prefs = PreferenceManager
-                        .getDefaultSharedPreferences(getActivity());
-                String accountType = prefs.getString(PREF_ACCOUNT_TYPE, null);
-                String accountName = prefs.getString(PREF_ACCOUNT_NAME, null);
-                BookmarksLoader bl = new BookmarksLoader(getActivity(),
-                        accountType, accountName);
-                if (mCrumbs != null) {
-                    Uri uri = (Uri) mCrumbs.getTopData();
-                    if (uri != null) {
-                        bl.setUri(uri);
-                    }
-                }
-                return bl;
-            }
+        if (id == LOADER_ACCOUNTS) {
+            return new AccountsLoader(getActivity());
+        } else if (id >= LOADER_BOOKMARKS) {
+            String accountType = args.getString(ACCOUNT_TYPE);
+            String accountName = args.getString(ACCOUNT_NAME);
+            BookmarksLoader bl = new BookmarksLoader(getActivity(),
+                    accountType, accountName);
+            return bl;
+        } else {
+            throw new UnsupportedOperationException("Unknown loader id " + id);
         }
-        throw new UnsupportedOperationException("Unknown loader id " + id);
     }
 
     @Override
     public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
-        switch (loader.getId()) {
-            case LOADER_BOOKMARKS: {
-                // Set the visibility of the empty vs. content views
-                if (cursor == null || cursor.getCount() == 0) {
-                    mEmptyView.setVisibility(View.VISIBLE);
-                    mGrid.setVisibility(View.GONE);
-                    mList.setVisibility(View.GONE);
-                } else {
-                    mEmptyView.setVisibility(View.GONE);
-                    setupBookmarkView();
-                }
-
-                // Give the new data to the adapter
-                mAdapter.changeCursor(cursor);
-                break;
+        if (loader.getId() == LOADER_ACCOUNTS) {
+            LoaderManager lm = getLoaderManager();
+            int id = LOADER_BOOKMARKS;
+            while (cursor.moveToNext()) {
+                String accountName = cursor.getString(0);
+                String accountType = cursor.getString(1);
+                Bundle args = new Bundle();
+                args.putString(ACCOUNT_NAME, accountName);
+                args.putString(ACCOUNT_TYPE, accountType);
+                BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
+                        getActivity(), mCurrentView);
+                mBookmarkAdapters.put(id, adapter);
+                mGrid.addAccount(accountName, adapter);
+                lm.restartLoader(id, args, this);
+                id++;
             }
+            // TODO: Figure out what a reload of these means
+            // Currently, a reload is triggered whenever bookmarks change
+            // This is less than ideal
+            // It also causes UI flickering as a new adapter is created
+            // instead of re-using an existing one when the account_name is the
+            // same.
+            // For now, this is a one-shot load
+            getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
+        } else if (loader.getId() >= LOADER_BOOKMARKS) {
+            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
+            adapter.changeCursor(cursor);
         }
     }
 
     @Override
     public void onLoaderReset(Loader<Cursor> loader) {
-        onLoadFinished(loader, null);
+        // TODO: Figure out what to do here (if anything?)
     }
 
     long getFolderId() {
@@ -181,37 +181,32 @@
     @Override
     public boolean onContextItemSelected(MenuItem item) {
         final Activity activity = getActivity();
-        // It is possible that the view has been canceled when we get to
-        // this point as back has a higher priority
-        if (mCanceled) {
-            return false;
-        }
-        AdapterView.AdapterContextMenuInfo i =
-            (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
+        BookmarkContextMenuInfo i = (BookmarkContextMenuInfo)item.getMenuInfo();
         // If we have no menu info, we can't tell which item was selected.
         if (i == null) {
             return false;
         }
+        BrowserBookmarksAdapter adapter = getChildAdapter(i.groupPosition);
 
         switch (item.getItemId()) {
         case R.id.open_context_menu_id:
-            loadUrl(i.position);
+            loadUrl(adapter, i.childPosition);
             break;
         case R.id.edit_context_menu_id:
-            editBookmark(i.position);
+            editBookmark(adapter, i.childPosition);
             break;
         case R.id.shortcut_context_menu_id:
-            Cursor c = mAdapter.getItem(i.position);
+            Cursor c = adapter.getItem(i.childPosition);
             activity.sendBroadcast(createShortcutIntent(getActivity(), c));
             break;
         case R.id.delete_context_menu_id:
-            displayRemoveBookmarkDialog(i.position);
+            displayRemoveBookmarkDialog(adapter, i.childPosition);
             break;
         case R.id.new_window_context_menu_id:
-            openInNewWindow(i.position);
+            openInNewWindow(adapter, i.childPosition);
             break;
         case R.id.share_link_context_menu_id: {
-            Cursor cursor = mAdapter.getItem(i.position);
+            Cursor cursor = adapter.getItem(i.childPosition);
             Controller.sharePage(activity,
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
@@ -220,16 +215,16 @@
             break;
         }
         case R.id.copy_url_context_menu_id:
-            copy(getUrl(i.position));
+            copy(getUrl(adapter, i.childPosition));
             break;
         case R.id.homepage_context_menu_id: {
-            BrowserSettings.getInstance().setHomePage(getUrl(i.position));
+            BrowserSettings.getInstance().setHomePage(getUrl(adapter, i.childPosition));
             Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
             break;
         }
         // Only for the Most visited page
         case R.id.save_to_bookmarks_menu_id: {
-            Cursor cursor = mAdapter.getItem(i.position);
+            Cursor cursor = adapter.getItem(i.childPosition);
             String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
             String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
             // If the site is bookmarked, the item becomes remove from
@@ -270,8 +265,9 @@
 
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
-        Cursor cursor = mAdapter.getItem(info.position);
+        BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
+        BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
+        Cursor cursor = adapter.getItem(info.childPosition);
         if (!canEdit(cursor)) {
             return;
         }
@@ -330,11 +326,11 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-
         SharedPreferences prefs = PreferenceManager
-                .getDefaultSharedPreferences(getActivity());
-        prefs.registerOnSharedPreferenceChangeListener(this);
+            .getDefaultSharedPreferences(getActivity());
         mCurrentView = prefs.getInt(PREF_SELECTED_VIEW, getDefaultView());
+        // TODO: Support list view
+        mCurrentView = VIEW_THUMBNAILS;
 
         Bundle args = getArguments();
         mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
@@ -345,40 +341,20 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        Context context = getActivity();
-
         mRoot = inflater.inflate(R.layout.bookmarks, container, false);
         mEmptyView = mRoot.findViewById(android.R.id.empty);
 
-        mGrid = (GridView) mRoot.findViewById(R.id.grid);
-        mGrid.setOnItemClickListener(this);
-        mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity()));
+        mGrid = (BookmarkExpandableGridView) mRoot.findViewById(R.id.grid);
+        mGrid.setOnChildClickListener(this);
+        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
+        mGrid.setBreadcrumbController(this);
         mList = (ListView) mRoot.findViewById(R.id.list);
-        mList.setOnItemClickListener(this);
+        // TODO: mList.setOnItemClickListener(this);
         setEnableContextMenu(mEnableContextMenu);
 
-        // Prep the header
-        ViewGroup hc = mHeaderContainer;
-        if (hc == null) {
-            hc = (ViewGroup) mRoot.findViewById(R.id.header_container);
-            hc.setVisibility(View.VISIBLE);
-        }
-        mHeader = inflater.inflate(R.layout.bookmarks_header, hc, false);
-        hc.addView(mHeader);
-        mCrumbs = (BreadCrumbView) mHeader.findViewById(R.id.crumbs);
-        mCrumbs.setController(this);
-        mCrumbs.setUseBackButton(mCrumbBackButton);
-        mCrumbs.setMaxVisible(mCrumbMaxVisible);
-        mCrumbs.setVisibility(mCrumbVisibility);
-        String name = getString(R.string.bookmarks);
-        mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
-        if (mCallbacks != null) {
-            mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
-        }
         // Start the loaders
         LoaderManager lm = getLoaderManager();
-        mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView);
-        lm.restartLoader(LOADER_BOOKMARKS, null, this);
+        lm.restartLoader(LOADER_ACCOUNTS, null, this);
 
         // Add our own listener in case there are favicons that have yet to be loaded.
         CombinedBookmarkHistoryView.getIconListenerSet().addListener(this);
@@ -386,7 +362,7 @@
         return mRoot;
     }
 
-     private int getDefaultView() {
+    private int getDefaultView() {
         if (BrowserActivity.isXlarge(getActivity())) {
             return VIEW_THUMBNAILS;
         }
@@ -396,16 +372,14 @@
     @Override
     public void onDestroyView() {
         super.onDestroyView();
-        SharedPreferences prefs = PreferenceManager
-                .getDefaultSharedPreferences(getActivity());
-        prefs.unregisterOnSharedPreferenceChangeListener(this);
-        if (mHeaderContainer != null) {
-            mHeaderContainer.removeView(mHeader);
+        mGrid.setBreadcrumbController(null);
+        LoaderManager lm = getLoaderManager();
+        lm.destroyLoader(LOADER_ACCOUNTS);
+        for (int id : mBookmarkAdapters.keySet()) {
+            lm.destroyLoader(id);
         }
-        mCrumbs.setController(null);
-        mCrumbs = null;
-        getLoaderManager().destroyLoader(LOADER_BOOKMARKS);
-        mAdapter = null;
+        mBookmarkAdapters.clear();
+
         CombinedBookmarkHistoryView.getIconListenerSet().removeListener(this);
     }
 
@@ -413,35 +387,52 @@
     public void onReceivedIcon(String url, Bitmap icon) {
         // A new favicon has been loaded, so let anything attached to the adapter know about it
         // so new icons will be loaded.
-        mAdapter.notifyDataSetChanged();
+        // TODO: Notify all of data set changed
+        // TODO: Wait, is this even needed? Won't this trigger a DB change anyway?
+    }
+
+    private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
+        if (mCurrentView == VIEW_THUMBNAILS) {
+            return mGrid.getChildAdapter(groupPosition);
+        } else {
+            // TODO: Support expandable list
+            return null;
+        }
+    }
+
+    private BreadCrumbView getBreadCrumbs(int groupPosition) {
+        if (mCurrentView == VIEW_THUMBNAILS) {
+            return mGrid.getBreadCrumbs(groupPosition);
+        } else {
+            // TODO: Support expandable list
+            return null;
+        }
     }
 
     @Override
-    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
-        // It is possible that the view has been canceled when we get to
-        // this point as back has a higher priority
-        if (mCanceled) {
-            android.util.Log.e(LOGTAG, "item clicked when dismissing");
-            return;
-        }
-
-        Cursor cursor = mAdapter.getItem(position);
+    public boolean onChildClick(ExpandableListView parent, View v,
+            int groupPosition, int childPosition, long id) {
+        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
+        Cursor cursor = adapter.getItem(childPosition);
         boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
         if (mCallbacks != null &&
                 mCallbacks.onBookmarkSelected(cursor, isFolder)) {
-            return;
+            return true;
         }
 
+        // TODO: Folder stuff
         if (isFolder) {
             String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
             Uri uri = ContentUris.withAppendedId(
                     BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
-            if (mCrumbs != null) {
+            BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
+            if (crumbs != null) {
                 // update crumbs
-                mCrumbs.pushView(title, uri);
+                crumbs.pushView(title, uri);
             }
-            loadFolder(uri);
+            loadFolder(groupPosition, uri);
         }
+        return true;
     }
 
     /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
@@ -452,15 +443,15 @@
         return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
     }
 
-    private void loadUrl(int position) {
-        if (mCallbacks != null && mAdapter != null) {
-            mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false);
+    private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
+        if (mCallbacks != null && adapter != null) {
+            mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
         }
     }
 
-    private void openInNewWindow(int position) {
+    private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
         if (mCallbacks != null) {
-            Cursor c = mAdapter.getItem(position);
+            Cursor c = adapter.getItem(position);
             boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
             if (isFolder) {
                 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
@@ -497,9 +488,9 @@
 
     }
 
-    private void editBookmark(int position) {
+    private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
         Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
-        Cursor cursor = mAdapter.getItem(position);
+        Cursor cursor = adapter.getItem(position);
         Bundle item = new Bundle();
         item.putString(BrowserContract.Bookmarks.TITLE,
                 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
@@ -520,18 +511,19 @@
         startActivity(intent);
     }
 
-    private void displayRemoveBookmarkDialog(final int position) {
+    private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
+            int position) {
         // Put up a dialog asking if the user really wants to
         // delete the bookmark
-        Cursor cursor = mAdapter.getItem(position);
+        Cursor cursor = adapter.getItem(position);
         long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
         String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
         Context context = getActivity();
         BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
     }
 
-    private String getUrl(int position) {
-        return getUrl(mAdapter.getItem(position));
+    private String getUrl(BrowserBookmarksAdapter adapter, int position) {
+        return getUrl(adapter.getItem(position));
     }
 
     /* package */ static String getUrl(Cursor c) {
@@ -563,6 +555,7 @@
         Resources res = getActivity().getResources();
         int horizontalSpacing = (int) res.getDimension(R.dimen.combo_horizontalSpacing);
         mGrid.setHorizontalSpacing(horizontalSpacing);
+        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
         int paddingLeftRight = (int) res.getDimension(R.dimen.combo_paddingLeftRight);
         int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
         mRoot.setPadding(paddingLeftRight, paddingTop,
@@ -577,10 +570,11 @@
     }
 
     void selectView(int view) {
+        // TODO: Support list view
+        view = mCurrentView;
         if (view == mCurrentView) {
             return;
         }
-        mCurrentView = view;
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
         Editor edit = prefs.edit();
         edit.putInt(PREF_SELECTED_VIEW, mCurrentView);
@@ -592,52 +586,53 @@
     }
 
     private void setupBookmarkView() {
-        mAdapter.selectView(mCurrentView);
-        switch (mCurrentView) {
-        case VIEW_THUMBNAILS:
-            mList.setAdapter(null);
-            if (mGrid.getAdapter() != mAdapter) {
-                mGrid.setAdapter(mAdapter);
-            }
-            mGrid.setVisibility(View.VISIBLE);
-            mList.setVisibility(View.GONE);
-            break;
-        case VIEW_LIST:
-            mGrid.setAdapter(null);
-            if (mList.getAdapter() != mAdapter) {
-                mList.setAdapter(mAdapter);
-            }
-            mGrid.setVisibility(View.GONE);
-            mList.setVisibility(View.VISIBLE);
-            break;
-        }
+        // TODO: Support list view
+//        mAdapter.selectView(mCurrentView);
+//        switch (mCurrentView) {
+//        case VIEW_THUMBNAILS:
+//            mList.setAdapter(null);
+//            SharedPreferences prefs = PreferenceManager
+//                    .getDefaultSharedPreferences(getActivity());
+//            String accountName = prefs.getString(PREF_ACCOUNT_NAME, null);
+//            mGrid.addAccount(accountName, mAdapter);
+//            mGrid.setVisibility(View.VISIBLE);
+//            mList.setVisibility(View.GONE);
+//            break;
+//        case VIEW_LIST:
+//            mGrid.clearAccounts();
+//            if (mList.getAdapter() != mAdapter) {
+//                mList.setAdapter(mAdapter);
+//            }
+//            mGrid.setVisibility(View.GONE);
+//            mList.setVisibility(View.VISIBLE);
+//            break;
+//        }
     }
 
     /**
      * BreadCrumb controller callback
      */
     @Override
-    public void onTop(int level, Object data) {
+    public void onTop(BreadCrumbView view, int level, Object data) {
+        int groupPosition = (Integer) view.getTag(R.id.group_position);
         Uri uri = (Uri) data;
         if (uri == null) {
             // top level
             uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
         }
-        loadFolder(uri);
+        loadFolder(groupPosition, uri);
     }
 
     /**
      * @param uri
      */
-    private void loadFolder(Uri uri) {
+    private void loadFolder(int groupPosition, Uri uri) {
         LoaderManager manager = getLoaderManager();
-        BookmarksLoader loader =
-                (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
+        // This assumes groups are ordered the same as loaders
+        BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
+                manager.getLoader(LOADER_BOOKMARKS + groupPosition));
         loader.setUri(uri);
         loader.forceLoad();
-        if (mCallbacks != null) {
-            mCallbacks.onFolderChanged(mCrumbs.getTopLevel(), uri);
-        }
     }
 
     @Override
@@ -654,18 +649,9 @@
     }
 
     public boolean onBackPressed() {
-        if (canGoBack()) {
-            mCrumbs.popView();
-            return true;
-        }
         return false;
     }
 
-    private boolean canGoBack() {
-        Crumb c = mCrumbs.getTopCrumb();
-        return c != null && c.canGoBack;
-    }
-
     public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
         mCallbacks = callbackListener;
     }
@@ -722,41 +708,17 @@
         }
     }
 
-    public void setBreadCrumbVisibility(int visibility) {
-        mCrumbVisibility = visibility;
-        if (mCrumbs != null) {
-            mCrumbs.setVisibility(mCrumbVisibility);
-        }
-    }
+    static class AccountsLoader extends CursorLoader {
 
-    public void setBreadCrumbUseBackButton(boolean use) {
-        mCrumbBackButton = use;
-        if (mCrumbs != null) {
-            mCrumbs.setUseBackButton(mCrumbBackButton);
-        }
-    }
+        static String[] ACCOUNTS_PROJECTION = new String[] {
+            Accounts.ACCOUNT_NAME,
+            Accounts.ACCOUNT_TYPE
+        };
 
-    public void setBreadCrumbMaxVisible(int max) {
-        mCrumbMaxVisible = max;
-        if (mCrumbs != null) {
-            mCrumbs.setMaxVisible(mCrumbMaxVisible);
+        public AccountsLoader(Context context) {
+            super(context, Accounts.CONTENT_URI, ACCOUNTS_PROJECTION, null, null,
+                    Accounts.ACCOUNT_NAME + " ASC");
         }
-    }
 
-    @Override
-    public void onSharedPreferenceChanged(
-            SharedPreferences sharedPreferences, String key) {
-        if (PREF_ACCOUNT_NAME.equals(key) || PREF_ACCOUNT_TYPE.equals(key)) {
-            mCrumbs.setController(null);
-            mCrumbs.clear();
-            LoaderManager lm = getLoaderManager();
-            lm.restartLoader(LOADER_BOOKMARKS, null, this);
-            mCrumbs.setController(this);
-            String name = getString(R.string.bookmarks);
-            mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
-            if (mCallbacks != null) {
-                mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
-            }
-        }
     }
 }