new bookmark screen part 2

    specs here: https://docs.google.com/a/google.com/present/edit?id=0ARMpWryWB2oaY2RkbmZwdnBfODc0Y2diYnBoNDc&hl=en
    moved tabs to top
    added bread crumbs view for folder hierarchy
    changed thumbnail sizes for xlarge screens

Change-Id: I3035f299b343f9aa1ec0dd41772e5594cd6b21f5
diff --git a/res/drawable-mdpi/crumb_divider.9.png b/res/drawable-mdpi/crumb_divider.9.png
new file mode 100644
index 0000000..8c8fd43
--- /dev/null
+++ b/res/drawable-mdpi/crumb_divider.9.png
Binary files differ
diff --git a/res/drawable-mdpi/divider_vert.9.png b/res/drawable-mdpi/divider_vert.9.png
new file mode 100644
index 0000000..2c5646e
--- /dev/null
+++ b/res/drawable-mdpi/divider_vert.9.png
Binary files differ
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index d90620c..fa08353 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -14,47 +14,29 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
->
-
-    <LinearLayout android:id="@android:id/content"
+    android:layout_height="match_parent">
+    <GridView
+        android:id="@+id/grid"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical"
-    >
-
-        <Button android:id="@+id/up"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/defaultBookmarksUpButton"
-        />
-
-        <GridView android:id="@+id/grid"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-
-            android:horizontalSpacing="8dip"
-            android:verticalSpacing="14dip"
-            android:stretchMode="spacingWidth"
-            android:scrollbarStyle="insideInset"
-            android:listSelector="@android:drawable/gallery_thumb"
-            android:drawSelectorOnTop="true"
-            android:focusable="true"
-            android:focusableInTouchMode="true"
-            android:numColumns="auto_fit"
-        />
-    </LinearLayout>
-
-    <TextView android:id="@android:id/empty"
+        android:horizontalSpacing="16dip"
+        android:verticalSpacing="16dip"
+        android:stretchMode="spacingWidth"
+        android:scrollbarStyle="insideInset"
+        android:listSelector="@android:drawable/gallery_thumb"
+        android:drawSelectorOnTop="true"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        android:numColumns="auto_fit" />
+    <TextView
+        android:id="@android:id/empty"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:text="@string/empty_bookmarks_folder"
-        android:visibility="gone"
-    />
-
-</FrameLayout>
\ No newline at end of file
+        android:visibility="gone" />
+</FrameLayout>
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
index c0f4d8d..a89a2b9 100644
--- a/res/layout/bookmarks_history.xml
+++ b/res/layout/bookmarks_history.xml
@@ -13,21 +13,74 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:background="@color/black"
->
-    <ListView android:id="@android:id/list"
-        android:layout_width="0dip"
-        android:layout_height="match_parent"
-        android:layout_weight="20"
-    />
-
-    <FrameLayout android:id="@+id/fragment"
-        android:layout_width="0dip"
-        android:layout_height="match_parent"
-        android:layout_weight="80"
-    />
+    android:paddingTop="8dip"
+    android:paddingLeft="16dip"
+    android:paddingRight="16dip"
+    android:orientation="vertical"
+    android:background="@color/black">
+    <RelativeLayout
+        android:id="@+id/bar"
+        android:layout_width="match_parent"
+        android:layout_height="48dip">
+        <LinearLayout
+            android:id="@+id/tabs"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="16dip"
+            android:paddingRight="16dip">
+            <TextView
+                android:id="@+id/historytab"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:paddingLeft="32dip"
+                android:paddingRight="32dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center_vertical"
+                android:text="@string/tab_history"
+                android:drawableLeft="@drawable/ic_tab_history_selected"
+                android:drawablePadding="16dip" />
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:src="@drawable/divider_vert" />
+            <TextView
+                android:id="@+id/bmtab"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:paddingLeft="32dip"
+                android:paddingRight="32dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center_vertical"
+                android:text="@string/bookmarks"
+                android:drawableLeft="@drawable/ic_tab_bookmarks_selected"
+                android:drawablePadding="16dip" />
+            <com.android.browser.BreadCrumbView
+                android:id="@+id/crumbs"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:paddingLeft="16dip"
+                android:paddingRight="16dip" />
+        </LinearLayout>
+        <TextView
+            android:id="@+id/addbm"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:text="@string/add_new_bookmark"
+            android:layout_alignParentRight="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:gravity="center_vertical"
+            android:background="@null"
+            android:drawableLeft="@drawable/ic_favorite_off_normal"
+            android:drawablePadding="16dip" />
+    </RelativeLayout>
+    <FrameLayout
+        android:id="@+id/fragment"
+        android:paddingTop="8dip"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1.0" />
 </LinearLayout>
diff --git a/res/values-xlarge/dimensions.xml b/res/values-xlarge/dimensions.xml
index 602da0e..c335c19 100644
--- a/res/values-xlarge/dimensions.xml
+++ b/res/values-xlarge/dimensions.xml
@@ -11,6 +11,6 @@
     License.
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <dimen name="bookmarkThumbnailWidth">160dip</dimen>
-    <dimen name="bookmarkThumbnailHeight">180dip</dimen>
+    <dimen name="bookmarkThumbnailWidth">180dip</dimen>
+    <dimen name="bookmarkThumbnailHeight">120dip</dimen>
 </resources>
\ No newline at end of file
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 92717d3..c1bafd6 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -63,6 +63,8 @@
         implements View.OnClickListener, TextView.OnEditorActionListener,
         AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor> {
 
+    public static final long DEFAULT_FOLDER_ID = -1;
+
     private final String LOGTAG = "Bookmarks";
 
     // IDs for the CursorLoaders that are used.
@@ -194,7 +196,7 @@
     }
 
     private void descendInto(String foldername, long id) {
-        if (id != -1) {
+        if (id != DEFAULT_FOLDER_ID) {
             mCurrentFolder = id;
             mPaths.add(new Folder(foldername, id));
             updatePathString();
@@ -358,9 +360,9 @@
             url = mOriginalUrl = mMap.getString("url");
             mTouchIconUrl = mMap.getString("touch_icon_url");
             mThumbnail = (Bitmap) mMap.getParcelable("thumbnail");
-            mCurrentFolder = mMap.getLong(BrowserContract.Bookmarks.PARENT, -1);
+            mCurrentFolder = mMap.getLong(BrowserContract.Bookmarks.PARENT, DEFAULT_FOLDER_ID);
         }
-        if (mCurrentFolder == -1) {
+        if (mCurrentFolder == DEFAULT_FOLDER_ID) {
             mCurrentFolder = getBookmarksBarId(this);
         }
 
diff --git a/src/com/android/browser/BreadCrumbView.java b/src/com/android/browser/BreadCrumbView.java
new file mode 100644
index 0000000..d2a50c9
--- /dev/null
+++ b/src/com/android/browser/BreadCrumbView.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple bread crumb view
+ * Use setController to receive callbacks from user interactions
+ * Use pushView, popView, clear, and getTopData to change/access the view stack
+ */
+public class BreadCrumbView extends LinearLayout implements OnClickListener {
+
+    interface Controller {
+        public void onTop(int level, Object data);
+    }
+
+    private ImageButton mBackButton;
+    private Controller mController;
+    private List<Crumb> mCrumbs;
+    private boolean mUseBackButton;
+
+    /**
+     * @param context
+     * @param attrs
+     * @param defStyle
+     */
+    public BreadCrumbView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context);
+    }
+
+    /**
+     * @param context
+     * @param attrs
+     */
+    public BreadCrumbView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    /**
+     * @param context
+     */
+    public BreadCrumbView(Context context) {
+        super(context);
+        init(context);
+    }
+
+    private void init(Context ctx) {
+        mUseBackButton = false;
+        mCrumbs = new ArrayList<Crumb>();
+    }
+
+    public void setUseBackButton(boolean useflag) {
+        mUseBackButton = useflag;
+        if (mUseBackButton && (mBackButton == null)) {
+            addBackButton();
+        } else if (!mUseBackButton && (mBackButton != null)) {
+            removeView(mBackButton);
+            mBackButton = null;
+        }
+    }
+
+    public void setController(Controller ctl) {
+        mController = ctl;
+    }
+
+    public Object getTopData() {
+        Crumb c = getTopCrumb();
+        if (c != null) {
+            return c.data;
+        }
+        return null;
+    }
+
+    public int size() {
+        return mCrumbs.size();
+    }
+
+    public void clear() {
+        while (mCrumbs.size() > 1) {
+            pop(false);
+        }
+        pop(true);
+    }
+
+    public void notifyController() {
+        if (mController != null) {
+            if (mCrumbs.size() > 0) {
+                mController.onTop(mCrumbs.size(), getTopCrumb().data);
+            } else {
+                mController.onTop(0, null);
+            }
+        }
+    }
+
+    public void pushView(String name, Object data) {
+        Crumb crumb = new Crumb(name, true, data);
+        pushCrumb(crumb);
+    }
+
+    public void pushView(View view, Object data) {
+        Crumb crumb = new Crumb(view, true, data);
+        pushCrumb(crumb);
+    }
+
+    public void popView() {
+        pop(true);
+    }
+
+    private void addBackButton() {
+        mBackButton = new ImageButton(mContext);
+        mBackButton.setImageResource(R.drawable.ic_back_normal);
+        mBackButton.setBackgroundResource(R.drawable.browserbarbutton);
+        mBackButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                LayoutParams.MATCH_PARENT));
+        mBackButton.setOnClickListener(this);
+        mBackButton.setVisibility(View.GONE);
+        addView(mBackButton, 0);
+    }
+
+    private void pushCrumb(Crumb crumb) {
+        if (!mUseBackButton || (mCrumbs.size() > 0)) {
+            addSeparator();
+        }
+        mCrumbs.add(crumb);
+        addView(crumb.crumbView);
+        if (mUseBackButton) {
+            mBackButton.setVisibility(crumb.canGoBack ? View.VISIBLE : View.GONE);
+        }
+        crumb.crumbView.setOnClickListener(this);
+    }
+
+    private void addSeparator() {
+        ImageView sep = new ImageView(mContext);
+        sep.setImageResource(R.drawable.crumb_divider);
+        sep.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                LayoutParams.MATCH_PARENT));
+        addView(sep);
+    }
+
+    private void pop(boolean notify) {
+        int n = mCrumbs.size();
+        if (n > 0) {
+            removeLastView();
+            if (!mUseBackButton || (n > 1)) {
+                // remove separator
+                removeLastView();
+            }
+            mCrumbs.remove(n - 1);
+            if (mUseBackButton) {
+                Crumb top = getTopCrumb();
+                if (top != null) {
+                    mBackButton.setVisibility(top.canGoBack ? View.VISIBLE : View.GONE);
+                } else {
+                    mBackButton.setVisibility(View.GONE);
+                }
+            }
+            if (notify) {
+                notifyController();
+            }
+        }
+    }
+
+    private void removeLastView() {
+        int ix = getChildCount();
+        if (ix > 0) {
+            removeViewAt(ix-1);
+        }
+    }
+
+    private Crumb getTopCrumb() {
+        Crumb crumb = null;
+        if (mCrumbs.size() > 0) {
+            crumb = mCrumbs.get(mCrumbs.size() - 1);
+        }
+        return crumb;
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (mBackButton == v) {
+            popView();
+            notifyController();
+        } else {
+            // pop until view matches crumb view
+            while (v != getTopCrumb().crumbView) {
+                pop(false);
+            }
+            notifyController();
+        }
+    }
+
+    class Crumb {
+
+        public View crumbView;
+        public boolean canGoBack;
+        public Object data;
+
+        public Crumb(String title, boolean backEnabled, Object tag) {
+            init(makeCrumbView(title), backEnabled, tag);
+        }
+
+        public Crumb(View view, boolean backEnabled, Object tag) {
+            init(view, backEnabled, tag);
+        }
+
+        private void init(View view, boolean back, Object tag) {
+            canGoBack = back;
+            crumbView = view;
+            data = tag;
+        }
+
+        private TextView makeCrumbView(String name) {
+            TextView tv = new TextView(mContext);
+            tv.setTextAppearance(mContext, android.R.style.TextAppearance_Medium);
+            tv.setPadding(16, 0, 16, 0);
+            tv.setGravity(Gravity.CENTER_VERTICAL);
+            tv.setText(name);
+            tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                    LayoutParams.MATCH_PARENT));
+            return tv;
+        }
+
+    }
+
+}
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index a507daa..ec4a78a 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -67,6 +67,7 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.provider.Browser;
+import android.provider.BrowserContract;
 import android.provider.BrowserContract.Images;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Intents.Insert;
@@ -949,7 +950,6 @@
         if (mActiveTabsPage != null) {
             removeActiveTabPage(true);
         }
-        removeComboView();
 
         cancelStopToast();
 
@@ -1289,8 +1289,11 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        // menu remains active, so ensure comboview is dismissed
-        removeComboView();
+        if (item.getGroupId() != R.id.CONTEXT_MENU) {
+            // menu remains active, so ensure comboview is dismissed
+            // if main menu option is selected
+            removeComboView();
+        }
         // check the action bar button before mCanChord check, as the prepare call
         // doesn't come for action bar buttons
         if (item.getItemId() == R.id.newtab) {
@@ -1341,7 +1344,7 @@
                 break;
 
             case R.id.add_bookmark_menu_id:
-                bookmarkCurrentPage();
+                bookmarkCurrentPage(AddBookmarkPage.DEFAULT_FOLDER_ID);
                 break;
 
             case R.id.stop_reload_menu_id:
@@ -1497,7 +1500,11 @@
         return true;
     }
 
-    /* package */ void bookmarkCurrentPage() {
+    /**
+     * add the current page as a bookmark to the given folder id
+     * @param folderId use -1 for the default folder
+     */
+    /* package */ void bookmarkCurrentPage(long folderId) {
         Intent i = new Intent(BrowserActivity.this,
                 AddBookmarkPage.class);
         WebView w = getTopWindow();
@@ -1506,6 +1513,8 @@
         i.putExtra("touch_icon_url", w.getTouchIconUrl());
         i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this),
                 getDesiredThumbnailHeight(this)));
+        i.putExtra(BrowserContract.Bookmarks.PARENT,
+                folderId);
         // Put the dialog at the upper right of the screen, covering the
         // star on the title bar.
         i.putExtra("gravity", Gravity.RIGHT | Gravity.TOP);
@@ -2231,7 +2240,9 @@
                         // if tab page is showing, hide it
                         removeActiveTabPage(true);
                     } else if (mComboView != null) {
-                        removeComboView();
+                        if (!mComboView.onBackPressed()) {
+                            removeComboView();
+                        }
                     } else {
                         WebView subwindow = mTabControl.getCurrentSubWindow();
                         if (subwindow != null) {
@@ -3876,7 +3887,7 @@
     public boolean onMenuItemClick(MenuItem item) {
         switch(item.getItemId()) {
             case R.id.add_bookmark_menu_id:
-                bookmarkCurrentPage();
+                bookmarkCurrentPage(AddBookmarkPage.DEFAULT_FOLDER_ID);
                 return true;
             case R.id.shortcut_to_home_menu_id:
                 Tab current = mTabControl.getCurrentTab();
@@ -3920,7 +3931,7 @@
         builder.setItems(choices, new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int item) {
                 if (item == 0) {
-                    bookmarkCurrentPage();
+                    bookmarkCurrentPage(AddBookmarkPage.DEFAULT_FOLDER_ID);
                 } else if (item == 1) {
                 }
             }
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index be6f8f8..fdd6c87 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -40,31 +40,26 @@
 import android.provider.BrowserContract;
 import android.provider.BrowserContract.Accounts;
 import android.text.TextUtils;
-import android.util.Pair;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.LayoutInflater;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.webkit.WebIconDatabase.IconListener;
 import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.Button;
 import android.widget.GridView;
 import android.widget.Toast;
 
-import java.util.Stack;
-
 /**
  *  View showing the user's bookmarks in the browser.
  */
 public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
-        LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener, OnClickListener,
+        LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
         OnItemSelectedListener {
 
     static final int BOOKMARKS_SAVE = 1;
@@ -91,14 +86,15 @@
     boolean mCanceled = false;
     boolean mCreateShortcut;
     View mEmptyView;
-    View mContentView;
-    Stack<Pair<String, Uri>> mFolderStack = new Stack<Pair<String, Uri>>();
-    Button mUpButton;
 
-    static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb, Bundle args) {
+    BreadCrumbView mCrumbs;
+
+    static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb,
+            BreadCrumbView crumbs, Bundle args) {
         BrowserBookmarksPage bbp = new BrowserBookmarksPage();
         bbp.mCallbacks = cb;
         bbp.setArguments(args);
+        bbp.mCrumbs = crumbs;
         return bbp;
     }
 
@@ -112,7 +108,14 @@
                     accountType = args.getString(BookmarksLoader.ARG_ACCOUNT_TYPE);
                     accountName = args.getString(BookmarksLoader.ARG_ACCOUNT_NAME);
                 }
-                return new BookmarksLoader(getActivity(), accountType, accountName);
+                BookmarksLoader bl = new BookmarksLoader(getActivity(), accountType, accountName);
+                if (mCrumbs != null) {
+                    Uri uri = (Uri) mCrumbs.getTopData();
+                    if (uri != null) {
+                        bl.setUri(uri);
+                    }
+                }
+                return bl;
             }
             case LOADER_ACCOUNTS_THEN_BOOKMARKS: {
                 return new CursorLoader(getActivity(), Accounts.CONTENT_URI,
@@ -136,23 +139,8 @@
                     mGrid.setVisibility(View.VISIBLE);
                 }
 
-                // Fill in the "up" button if needed
-                BookmarksLoader bl = (BookmarksLoader) loader;
-                String path = bl.getUri().getPath();
-                boolean rootFolder =
-                        BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER.getPath().equals(path);
-                if (rootFolder) {
-                    mUpButton.setText(R.string.defaultBookmarksUpButton);
-                    mUpButton.setEnabled(false);
-                } else {
-                    mUpButton.setText(mFolderStack.peek().first);
-                    mUpButton.setEnabled(true);
-                }
-                mUpButton.setVisibility(View.VISIBLE);
-
                 // Give the new data to the adapter
                 mAdapter.changeCursor(cursor);
-
                 break;
             }
 
@@ -218,15 +206,34 @@
         }
     }
 
-    @Override
-    public void onClick(View view) {
-        if (view == mUpButton) {
-            Pair<String, Uri> pair = mFolderStack.pop();
-            BookmarksLoader loader =
-                    (BookmarksLoader) ((Loader) getLoaderManager().getLoader(LOADER_BOOKMARKS));
-            loader.setUri(pair.second);
-            loader.forceLoad();
+    long getFolderId() {
+        LoaderManager manager = getLoaderManager();
+        BookmarksLoader loader =
+                (BookmarksLoader) ((Loader)(manager.getLoader(LOADER_BOOKMARKS)));
+
+        Uri uri = loader.getUri();
+        if (uri != null) {
+            try {
+                return ContentUris.parseId(uri);
+            } catch (NumberFormatException nfx) {
+                return -1;
+            }
         }
+        return -1;
+    }
+
+    public void onFolderChange(int level, Object data) {
+        Uri uri = (Uri) data;
+        if (uri == null) {
+            // top level
+            uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
+        }
+        LoaderManager manager = getLoaderManager();
+        BookmarksLoader loader =
+                (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
+        loader.setUri(uri);
+        loader.forceLoad();
+
     }
 
     @Override
@@ -358,7 +365,6 @@
 
         View root = inflater.inflate(R.layout.bookmarks, container, false);
         mEmptyView = root.findViewById(android.R.id.empty);
-        mContentView = root.findViewById(android.R.id.content);
 
         mGrid = (GridView) root.findViewById(R.id.grid);
         mGrid.setOnItemClickListener(this);
@@ -367,11 +373,6 @@
             mGrid.setOnCreateContextMenuListener(this);
         }
 
-        mUpButton = (Button) root.findViewById(R.id.up);
-        mUpButton.setEnabled(false);
-        mUpButton.setOnClickListener(this);
-        mUpButton.setVisibility(View.GONE);
-
         mAdapter = new BrowserBookmarksAdapter(getActivity());
         mGrid.setAdapter(mAdapter);
 
@@ -428,19 +429,16 @@
         if (!isFolder) {
             mCallbacks.onUrlSelected(getUrl(position), false);
         } else {
-            String title;
-            if (mFolderStack.size() != 0) {
-                title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
-            } else {
-                // TODO localize
-                title = "Bookmarks";
-            }
+            String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
             LoaderManager manager = getLoaderManager();
             BookmarksLoader loader =
                     (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
-            mFolderStack.push(new Pair(title, loader.getUri()));
             Uri uri = ContentUris.withAppendedId(
                     BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
+            if (mCrumbs != null) {
+                // update crumbs
+                mCrumbs.pushView(title, uri);
+            }
             loader.setUri(uri);
             loader.forceLoad();
         }
@@ -610,4 +608,5 @@
                 Context.CLIPBOARD_SERVICE);
         cm.setPrimaryClip(ClipData.newRawUri(null, null, Uri.parse(text.toString())));
     }
+
 }
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index b480209..c829079 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -16,25 +16,24 @@
 
 package com.android.browser;
 
+import com.android.browser.BreadCrumbView.Controller;
+
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.res.Resources;
-import android.database.MatrixCursor;
 import android.graphics.Bitmap;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.Browser;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.webkit.WebIconDatabase;
 import android.webkit.WebIconDatabase.IconListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
 import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
 
 import java.util.HashMap;
 import java.util.Vector;
@@ -46,7 +45,7 @@
 }
 
 public class CombinedBookmarkHistoryView extends LinearLayout
-        implements OnItemClickListener {
+        implements OnClickListener, Controller {
 
     final static String STARTING_FRAGMENT = "fragment";
 
@@ -59,6 +58,15 @@
 
     long mCurrentFragment;
 
+    View mTabs;
+    BreadCrumbView mCrumbs;
+    TextView mTabBookmarks;
+    TextView mTabHistory;
+    TextView mAddBookmark;
+
+    BrowserBookmarksPage mBookmarks;
+    BrowserHistoryPage mHistory;
+
     static class IconListenerSet implements IconListener {
         // Used to store favicons as we get them from the database
         // FIXME: We use a different method to get the Favicons in
@@ -105,17 +113,19 @@
 
 //        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
 
-        ListView list = (ListView) findViewById(android.R.id.list);
-        list.setOnItemClickListener(this);
-        MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
-        cursor.newRow().add(res.getString(R.string.bookmarks)).add(FRAGMENT_ID_BOOKMARKS);
-        cursor.newRow().add(res.getString(R.string.history)).add(FRAGMENT_ID_HISTORY);
-        list.setAdapter(new SimpleCursorAdapter(context,
-                android.R.layout.simple_list_item_1, cursor,
-                new String[] { "name" }, new int[] { android.R.id.text1 }));
+        mTabs = findViewById(R.id.tabs);
+        mCrumbs = (BreadCrumbView) findViewById(R.id.crumbs);
+        mCrumbs.setController(this);
 
+        mTabBookmarks = (TextView) findViewById(R.id.bmtab);
+        mTabHistory = (TextView) findViewById(R.id.historytab);
+        mAddBookmark = (TextView) findViewById(R.id.addbm);
+        mAddBookmark.setOnClickListener(this);
+        mTabHistory.setOnClickListener(this);
+        mTabBookmarks.setOnClickListener(this);
         // Start up the default fragment
-        loadFragment(startingFragment, mExtras);
+        initFragments(mExtras);
+        loadFragment(startingFragment, mExtras, false);
 
         // XXX: Must do this before launching the AsyncTask to avoid a
         // potential crash if the icon database has not been created.
@@ -134,15 +144,25 @@
 
     }
 
-    private void loadFragment(int id, Bundle extras) {
+    private void initFragments(Bundle extras) {
+        mBookmarks =  BrowserBookmarksPage.newInstance(mBrowserActivity, mCrumbs, extras);
+        mHistory = BrowserHistoryPage.newInstance(mBrowserActivity, extras);
+    }
+
+    private void loadFragment(int id, Bundle extras, boolean notify) {
         String fragmentClassName;
         Fragment fragment = null;
         switch (id) {
             case FRAGMENT_ID_BOOKMARKS:
-                fragment = BrowserBookmarksPage.newInstance(mBrowserActivity, extras);
+                fragment = mBookmarks;
+                mCrumbs.setVisibility(View.VISIBLE);
+                if (notify) {
+                    mCrumbs.notifyController();
+                }
                 break;
             case FRAGMENT_ID_HISTORY:
-                fragment = BrowserHistoryPage.newInstance(mBrowserActivity, extras);
+                fragment = mHistory;
+                mCrumbs.setVisibility(View.GONE);
                 break;
             default:
                 throw new IllegalArgumentException();
@@ -156,9 +176,38 @@
     }
 
     @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        if (id == mCurrentFragment) return;
-        loadFragment((int) id, mExtras);
+    public void onClick(View view) {
+        if ((mTabHistory == view) && (mCurrentFragment != FRAGMENT_ID_HISTORY)) {
+            loadFragment(FRAGMENT_ID_HISTORY, mExtras, false);
+        } else if (mTabBookmarks == view) {
+            if (mCurrentFragment != FRAGMENT_ID_BOOKMARKS) {
+                loadFragment(FRAGMENT_ID_BOOKMARKS, mExtras, true);
+            } else {
+                mCrumbs.clear();
+            }
+        } else if (mAddBookmark == view) {
+            mBrowserActivity.bookmarkCurrentPage(mBookmarks.getFolderId());
+        }
+    }
+
+    /**
+     * BreadCrumb controller callback
+     */
+    @Override
+    public void onTop(int level, Object data) {
+        mBookmarks.onFolderChange(level, data);
+    }
+
+    /**
+     * callback for back key presses
+     */
+    boolean onBackPressed() {
+        if ((mCurrentFragment == FRAGMENT_ID_BOOKMARKS) &&
+                (mCrumbs.size() > 0)) {
+            mCrumbs.popView();
+            return true;
+        }
+        return false;
     }
 
 }
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 1d970ea..354d694 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -35,7 +35,7 @@
         Bundle extras = new Bundle();
         extras.putBoolean(BrowserBookmarksPage.EXTRA_SHORTCUT, true);
         extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, true);
-        Fragment frag = BrowserBookmarksPage.newInstance(this, extras);
+        Fragment frag = BrowserBookmarksPage.newInstance(this, null, extras);
         transaction.add(android.R.id.content, frag);
         transaction.commit();
     }