Switch the bookmarks and history over to fragments.

Change-Id: If4edc97d1115bfd261136d5b8cfc82afa21f8ced
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
new file mode 100644
index 0000000..c7f57fd
--- /dev/null
+++ b/res/layout/bookmarks_history.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+>
+    <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"
+    />
+</LinearLayout>
diff --git a/res/layout/empty_history.xml b/res/layout/empty_history.xml
deleted file mode 100644
index 4484a16..0000000
--- a/res/layout/empty_history.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/empty_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:text="@string/empty_history"
-    android:background="@color/black"
-    android:textColor="@color/white"
-    android:gravity="center"
-    android:textStyle="bold"
-    />
diff --git a/res/layout/history.xml b/res/layout/history.xml
new file mode 100644
index 0000000..f6e844a
--- /dev/null
+++ b/res/layout/history.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+>
+
+    <ExpandableListView android:id="@android:id/list"
+        android:layout_width="match_parent" 
+        android:layout_height="match_parent"
+        android:drawSelectorOnTop="false"
+    />
+
+    <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_history"
+        android:visibility="gone"
+    />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/tabs.xml b/res/layout/tabs.xml
deleted file mode 100644
index c212547..0000000
--- a/res/layout/tabs.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/tabhost"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <TabWidget android:id="@android:id/tabs"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-        />
-
-        <FrameLayout android:id="@android:id/tabcontent"
-            android:layout_width="match_parent"
-            android:layout_height="0dip"
-            android:layout_weight="1"
-        />
-    </LinearLayout>
-</TabHost>
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 99bf017..4461cf0 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -3915,8 +3915,8 @@
         intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
         intent.putExtra("touch_icon_url", current.getTouchIconUrl());
         if (startWithHistory) {
-            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
-                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
+            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_FRAGMENT,
+                    CombinedBookmarkHistoryActivity.FRAGMENT_ID_HISTORY);
         }
         if (newTabMode) {
             intent.putExtra(CombinedBookmarkHistoryActivity.NEWTAB_MODE, true);
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index a01f6fa..f9dc5e0 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.app.Fragment;
 import android.app.LoaderManager;
 import android.content.ClipboardManager;
 import android.content.ClippedData;
@@ -37,6 +38,7 @@
 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;
@@ -54,7 +56,7 @@
 /**
  *  View showing the user's bookmarks in the browser.
  */
-public class BrowserBookmarksPage extends Activity implements View.OnCreateContextMenuListener,
+public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
         LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener, OnClickListener {
 
     static final int BOOKMARKS_SAVE = 1;
@@ -62,6 +64,7 @@
 
     static final int LOADER_BOOKMARKS = 1;
 
+    BookmarksHistoryCallbacks mCallbacks;
     GridView mGrid;
     BrowserBookmarksAdapter mAdapter;
     boolean mDisableNewWindow;
@@ -81,7 +84,7 @@
                 if (args != null) {
                     args.getInt(BookmarksLoader.ARG_ROOT_FOLDER, 0);
                 }
-                return new BookmarksLoader(this, rootFolder);
+                return new BookmarksLoader(getActivity(), rootFolder);
             }
         }
         throw new UnsupportedOperationException("Unknown loader id " + id);
@@ -127,6 +130,7 @@
 
     @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) {
@@ -147,7 +151,7 @@
             editBookmark(i.position);
             break;
         case R.id.shortcut_context_menu_id:
-            sendBroadcast(createShortcutIntent(i.position));
+            activity.sendBroadcast(createShortcutIntent(i.position));
             break;
         case R.id.delete_context_menu_id:
             displayRemoveBookmarkDialog(i.position);
@@ -157,7 +161,7 @@
             break;
         case R.id.share_link_context_menu_id: {
             Cursor cursor = (Cursor) mAdapter.getItem(i.position);
-            BrowserActivity.sharePage(BrowserBookmarksPage.this,
+            BrowserActivity.sharePage(activity,
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
                     cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
                     getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
@@ -168,10 +172,8 @@
             copy(getUrl(i.position));
             break;
         case R.id.homepage_context_menu_id: {
-            BrowserSettings.getInstance().setHomePage(this,
-                    getUrl(i.position));
-            Toast.makeText(this, R.string.homepage_set,
-                    Toast.LENGTH_LONG).show();
+            BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position));
+            Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
             break;
         }
         // Only for the Most visited page
@@ -181,7 +183,7 @@
             String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
             // If the site is bookmarked, the item becomes remove from
             // bookmarks.
-            Bookmarks.removeFromBookmarks(this, getContentResolver(), url, name);
+            Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
             break;
         }
         default:
@@ -202,7 +204,8 @@
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         
-        MenuInflater inflater = getMenuInflater();
+        final Activity activity = getActivity();
+        MenuInflater inflater = activity.getMenuInflater();
         inflater.inflate(R.menu.bookmarkscontext, menu);
 
         if (mDisableNewWindow) {
@@ -210,7 +213,7 @@
         }
 
         if (mContextHeader == null) {
-            mContextHeader = new BookmarkItem(BrowserBookmarksPage.this);
+            mContextHeader = new BookmarkItem(activity);
         } else if (mContextHeader.getParent() != null) {
             ((ViewGroup) mContextHeader.getParent()).removeView(mContextHeader);
         }
@@ -237,33 +240,39 @@
      *  Create a new BrowserBookmarksPage.
      */
     @Override
-    protected void onCreate(Bundle icicle) {
+    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        Intent intent = getIntent();
-        if (Intent.ACTION_CREATE_SHORTCUT.equals(intent.getAction())) {
-            mCreateShortcut = true;
-            setTitle(R.string.browser_bookmarks_page_bookmarks_text);
-        }
-        mDisableNewWindow = intent.getBooleanExtra("disable_new_window", false);
+        Bundle args = getArguments();
+        mCreateShortcut = args == null ? false : args.getBoolean("create_shortcut", false);
+        mDisableNewWindow = args == null ? false : args.getBoolean("disable_new_window", false);
+    }
 
-        setContentView(R.layout.bookmarks);
-        mEmptyView = findViewById(android.R.id.empty);
-        mContentView = findViewById(android.R.id.content);
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        mCallbacks = (BookmarksHistoryCallbacks) activity;
+    }
+    
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        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) findViewById(R.id.grid);
+        mGrid = (GridView) root.findViewById(R.id.grid);
         mGrid.setOnItemClickListener(this);
-        mGrid.setColumnWidth(
-                BrowserActivity.getDesiredThumbnailWidth(this));
+        mGrid.setColumnWidth(BrowserActivity.getDesiredThumbnailWidth(getActivity()));
         if (!mCreateShortcut) {
             mGrid.setOnCreateContextMenuListener(this);
         }
 
-        mUpButton = (Button) findViewById(R.id.up);
+        mUpButton = (Button) root.findViewById(R.id.up);
         mUpButton.setEnabled(false);
         mUpButton.setOnClickListener(this);
 
-        mAdapter = new BrowserBookmarksAdapter(this);
+        mAdapter = new BrowserBookmarksAdapter(getActivity());
         mGrid.setAdapter(mAdapter);
 
         // Start the loader for the bookmark data
@@ -271,8 +280,10 @@
 
         // Add our own listener in case there are favicons that have yet to be loaded.
         CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(this);
-    }
 
+        return root;
+    }
+    
     @Override
     public void onReceivedIcon(String url, Bitmap icon) {
         // A new favicon has been loaded, so let anything attached to the adapter know about it
@@ -289,15 +300,15 @@
             return;
         }
         if (mCreateShortcut) {
-            setResultToParent(RESULT_OK, createShortcutIntent(position));
-            finish();
+            // TODO handle this
+            createShortcutIntent(position);
             return;
         }
 
         Cursor cursor = (Cursor) mAdapter.getItem(position);
         boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
         if (!isFolder) {
-            loadUrl(position);
+            mCallbacks.onUrlSelected(getUrl(position), false);
         } else {
             String title;
             if (mFolderStack.size() != 0) {
@@ -323,25 +334,19 @@
         String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
         Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
         Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
-        return BookmarkUtils.createAddToHomeIntent(this, url, title, touchIcon, favicon);
+        return BookmarkUtils.createAddToHomeIntent(getActivity(), url, title, touchIcon, favicon);
     }
 
     private void loadUrl(int position) {
-        Cursor cursor = (Cursor) mAdapter.getItem(position);
-        Intent intent = new Intent(cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
-        setResultToParent(RESULT_OK, intent);
-        finish();
+        mCallbacks.onUrlSelected(getUrl(position), false);
     }
 
     private void openInNewWindow(int position) {
-        Bundle b = new Bundle();
-        b.putBoolean("new_window", true);
-        setResultToParent(RESULT_OK, (new Intent(getUrl(position))).putExtras(b));
-        finish();
+        mCallbacks.onUrlSelected(getUrl(position), true);
     }
 
     private void editBookmark(int position) {
-        Intent intent = new Intent(this, AddBookmarkPage.class);
+        Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
         Cursor cursor = (Cursor) mAdapter.getItem(position);
         Bundle item = new Bundle();
         item.putString(Browser.BookmarkColumns.TITLE, 
@@ -359,10 +364,10 @@
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         switch(requestCode) {
             case BOOKMARKS_SAVE:
-                if (resultCode == RESULT_OK) {
+                if (resultCode == Activity.RESULT_OK) {
                     Bundle extras;
                     if (data != null && (extras = data.getExtras()) != null) {
                         // If there are extras, then we need to save
@@ -415,7 +420,7 @@
         }
 
         if (values.size() > 0) {
-            getContentResolver().update(
+            getActivity().getContentResolver().update(
                     ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id),
                     values, null, null);
         }
@@ -425,10 +430,11 @@
         // Put up a dialog asking if the user really wants to
         // delete the bookmark
         Cursor cursor = (Cursor) mAdapter.getItem(position);
-        new AlertDialog.Builder(this)
+        Context context = getActivity();
+        new AlertDialog.Builder(context)
                 .setTitle(R.string.delete_bookmark)
                 .setIcon(android.R.drawable.ic_dialog_alert)
-                .setMessage(getText(R.string.delete_bookmark_warning).toString().replace(
+                .setMessage(context.getText(R.string.delete_bookmark_warning).toString().replace(
                         "%s", cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)))
                 .setPositiveButton(R.string.ok,
                         new DialogInterface.OnClickListener() {
@@ -446,7 +452,8 @@
     }
     
     private void copy(CharSequence text) {
-        ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
+                Context.CLIPBOARD_SERVICE);
         cm.setPrimaryClip(new ClippedData(null, null, new ClippedData.Item(text)));
     }
 
@@ -457,28 +464,6 @@
         Cursor cursor = (Cursor) mAdapter.getItem(position);
         String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
         String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
-        Bookmarks.removeFromBookmarks(null, getContentResolver(), url, title);
+        Bookmarks.removeFromBookmarks(null, getActivity().getContentResolver(), url, title);
     }
-
-    @Override
-    public void onBackPressed() {
-        setResultToParent(RESULT_CANCELED, null);
-        mCanceled = true;
-        super.onBackPressed();
-    }
-
-    // This Activity is generally a sub-Activity of
-    // CombinedBookmarkHistoryActivity. In that situation, we need to pass our
-    // result code up to our parent. However, if someone calls this Activity
-    // directly, then this has no parent, and it needs to set it on itself.
-    private void setResultToParent(int resultCode, Intent data) {
-        Activity parent = getParent();
-        if (parent == null) {
-            setResult(resultCode, data);
-        } else {
-            ((CombinedBookmarkHistoryActivity) parent).setResultFromChild(
-                    resultCode, data);
-        }
-    }
-
 }
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 8116b97..2295804 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -17,7 +17,7 @@
 package com.android.browser;
 
 import android.app.Activity;
-import android.app.ExpandableListActivity;
+import android.app.Fragment;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.ClipboardManager;
 import android.content.Context;
@@ -34,27 +34,30 @@
 import android.provider.BrowserContract.History;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewStub;
 import android.webkit.WebIconDatabase.IconListener;
 import android.widget.ExpandableListView;
 import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
+import android.widget.ExpandableListView.OnChildClickListener;
 import android.widget.Toast;
 
 /**
  * Activity for displaying the browser's history, divided into
  * days of viewing.
  */
-public class BrowserHistoryPage extends ExpandableListActivity
-        implements LoaderCallbacks<Cursor> {
+public class BrowserHistoryPage extends Fragment
+        implements LoaderCallbacks<Cursor>, OnChildClickListener {
 
     static final int LOADER_HISTORY = 1;
 
+    BookmarksHistoryCallbacks mCallbacks;
+    ExpandableListView mList;
+    View mEmptyView;
     HistoryAdapter mAdapter;
     boolean mDisableNewWindow;
     HistoryItem mContextHeader;
@@ -86,24 +89,9 @@
         static final int INDEX_FAVICON = 4;
     }
 
-    /**
-     * Report back to the calling activity to load a site.
-     * @param url   Site to load.
-     * @param newWindow True if the URL should be loaded in a new window
-     */
-    private void loadUrl(String url, boolean newWindow) {
-        Intent intent = new Intent().setAction(url);
-        if (newWindow) {
-            Bundle b = new Bundle();
-            b.putBoolean("new_window", true);
-            intent.putExtras(b);
-        }
-        setResultToParent(RESULT_OK, intent);
-        finish();
-    }
-    
     private void copy(CharSequence text) {
-        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
+        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
+                Context.CLIPBOARD_SERVICE);
         cm.setText(text);
     }
 
@@ -111,7 +99,7 @@
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         switch (id) {
             case LOADER_HISTORY: {
-                CursorLoader loader = new CursorLoader(this, History.CONTENT_URI,
+                CursorLoader loader = new CursorLoader(getActivity(), History.CONTENT_URI,
                         HistoryQuery.PROJECTION, null, null, null);
                 return loader;
             }
@@ -130,23 +118,17 @@
 
                 // Add an empty view late, so it does not claim an empty
                 // history before the adapter is present
-                final ExpandableListView list = getExpandableListView();
-                View v = new ViewStub(this, R.layout.empty_history);
-                addContentView(v, new LayoutParams(
-                        LayoutParams.MATCH_PARENT,
-                        LayoutParams.MATCH_PARENT));
-                list.setEmptyView(v);
+                mList.setEmptyView(mEmptyView);
 
                 // Do not post the runnable if there is nothing in the list.
-                if (list.getExpandableListAdapter().getGroupCount() > 0) {
-                    list.post(new Runnable() {
+                if (mList.getExpandableListAdapter().getGroupCount() > 0) {
+                    mList.post(new Runnable() {
                         @Override
                         public void run() {
                             // In case the history gets cleared before this
                             // event happens
-                            if (list.getExpandableListAdapter()
-                                    .getGroupCount() > 0) {
-                                list.expandGroup(0);
+                            if (mList.getExpandableListAdapter().getGroupCount() > 0) {
+                                mList.expandGroup(0);
                             }
                         }
                     });
@@ -159,68 +141,69 @@
             }
         }
     }
-    
+
     @Override
-    protected void onCreate(Bundle icicle) {
+    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        setTitle(R.string.browser_history);
 
-        getExpandableListView().setOnCreateContextMenuListener(this);
-        
-        mAdapter = new HistoryAdapter(this);
-        setListAdapter(mAdapter);
+        setHasOptionsMenu(true);
 
-        mDisableNewWindow = getIntent().getBooleanExtra("disable_new_window", false);
+        Bundle args = getArguments();
+        mDisableNewWindow = args.getBoolean("disable_new_window", false);
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        mCallbacks = (BookmarksHistoryCallbacks) activity;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View root = inflater.inflate(R.layout.history, container, false);
+        mList = (ExpandableListView) root.findViewById(android.R.id.list);
+        mList.setOnCreateContextMenuListener(this);
+        mList.setOnChildClickListener(this);
+        mAdapter = new HistoryAdapter(getActivity());
+        mList.setAdapter(mAdapter);
+
+        mEmptyView = root.findViewById(android.R.id.empty);
+
+        // Start the loader
+        getLoaderManager().initLoader(LOADER_HISTORY, null, this);
 
         // Register to receive icons in case they haven't all been loaded.
         CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(mIconReceiver);
 
-        Activity parent = getParent();
-        if (null == parent
-                || !(parent instanceof CombinedBookmarkHistoryActivity)) {
-            throw new AssertionError("history page can only be viewed as a tab"
-                    + "in CombinedBookmarkHistoryActivity");
-        }
-
-        // initialize the result to canceled, so that if the user just presses
-        // back then it will have the correct result
-        setResultToParent(RESULT_CANCELED, null);
-
-        // Start the loader
-        getLoaderManager().initLoader(LOADER_HISTORY, null, this);
+        return root;
     }
 
     @Override
-    protected void onDestroy() {
+    public void onDestroy() {
         super.onDestroy();
-        CombinedBookmarkHistoryActivity.getIconListenerSet()
-                .removeListener(mIconReceiver);
+        CombinedBookmarkHistoryActivity.getIconListenerSet().removeListener(mIconReceiver);
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-        MenuInflater inflater = getMenuInflater();
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         inflater.inflate(R.menu.history, menu);
-        return true;
     }
 
     @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
+    public void onPrepareOptionsMenu(Menu menu) {
         menu.findItem(R.id.clear_history_menu_id).setVisible(
-                Browser.canClearHistory(this.getContentResolver()));
-        return true;
+                Browser.canClearHistory(getActivity().getContentResolver()));
     }
     
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.clear_history_menu_id:
-                Browser.clearHistory(getContentResolver());
+                Browser.clearHistory(getActivity().getContentResolver());
                 // BrowserHistoryPage is always a child of
                 // CombinedBookmarkHistoryActivity
-                ((CombinedBookmarkHistoryActivity) getParent())
-                        .removeParentChildRelationShips();
+                mCallbacks.onRemoveParentChildRelationShips();
                 return true;
                 
             default:
@@ -230,24 +213,23 @@
     }
 
     @Override
-    public void onCreateContextMenu(ContextMenu menu, View v,
-            ContextMenuInfo menuInfo) {
-        ExpandableListContextMenuInfo i = 
-            (ExpandableListContextMenuInfo) menuInfo;
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        ExpandableListContextMenuInfo i = (ExpandableListContextMenuInfo) menuInfo;
         // Do not allow a context menu to come up from the group views.
         if (!(i.targetView instanceof HistoryItem)) {
             return;
         }
 
         // Inflate the menu
-        MenuInflater inflater = getMenuInflater();
+        Activity parent = getActivity();
+        MenuInflater inflater = parent.getMenuInflater();
         inflater.inflate(R.menu.historycontext, menu);
 
         HistoryItem historyItem = (HistoryItem) i.targetView;
 
         // Setup the header
         if (mContextHeader == null) {
-            mContextHeader = new HistoryItem(this);
+            mContextHeader = new HistoryItem(parent);
         } else if (mContextHeader.getParent() != null) {
             ((ViewGroup) mContextHeader.getParent()).removeView(mContextHeader);
         }
@@ -264,7 +246,7 @@
             item.setTitle(R.string.remove_from_bookmarks);
         }
         // decide whether to show the share link option
-        PackageManager pm = getPackageManager();
+        PackageManager pm = parent.getPackageManager();
         Intent send = new Intent(Intent.ACTION_SEND);
         send.setType("text/plain");
         ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
@@ -280,35 +262,35 @@
         HistoryItem historyItem = (HistoryItem) i.targetView;
         String url = historyItem.getUrl();
         String title = historyItem.getName();
+        Activity activity = getActivity();
         switch (item.getItemId()) {
             case R.id.open_context_menu_id:
-                loadUrl(url, false);
+                mCallbacks.onUrlSelected(url, false);
                 return true;
             case R.id.new_window_context_menu_id:
-                loadUrl(url, true);
+                mCallbacks.onUrlSelected(url, true);
                 return true;
             case R.id.save_to_bookmarks_menu_id:
                 if (historyItem.isBookmark()) {
-                    Bookmarks.removeFromBookmarks(this, getContentResolver(),
+                    Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(),
                             url, title);
                 } else {
-                    Browser.saveBookmark(this, title, url);
+                    Browser.saveBookmark(activity, title, url);
                 }
                 return true;
             case R.id.share_link_context_menu_id:
-                Browser.sendString(this, url,
-                        getText(R.string.choosertitle_sharevia).toString());
+                Browser.sendString(activity, url,
+                        activity.getText(R.string.choosertitle_sharevia).toString());
                 return true;
             case R.id.copy_url_context_menu_id:
                 copy(url);
                 return true;
             case R.id.delete_context_menu_id:
-                Browser.deleteFromHistory(getContentResolver(), url);
+                Browser.deleteFromHistory(activity.getContentResolver(), url);
                 return true;
             case R.id.homepage_context_menu_id:
-                BrowserSettings.getInstance().setHomePage(this, url);
-                Toast.makeText(this, R.string.homepage_set,
-                    Toast.LENGTH_LONG).show();
+                BrowserSettings.getInstance().setHomePage(activity, url);
+                Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
                 return true;
             default:
                 break;
@@ -320,20 +302,12 @@
     public boolean onChildClick(ExpandableListView parent, View v,
             int groupPosition, int childPosition, long id) {
         if (v instanceof BookmarkItem) {
-            loadUrl(((BookmarkItem) v).getUrl(), false);
+            mCallbacks.onUrlSelected(((BookmarkItem) v).getUrl(), false);
             return true;
         }
         return false;
     }
 
-    // This Activity is always a sub-Activity of
-    // CombinedBookmarkHistoryActivity. Therefore, we need to pass our
-    // result code up to our parent.
-    private void setResultToParent(int resultCode, Intent data) {
-        ((CombinedBookmarkHistoryActivity) getParent()).setResultFromChild(
-                resultCode, data);
-    }
-
     private class HistoryAdapter extends DateSortedExpandableListAdapter {
         HistoryAdapter(Context context) {
             super(context, HistoryQuery.INDEX_DATE_LAST_VISITED);
@@ -344,7 +318,7 @@
                 View convertView, ViewGroup parent) {
             BookmarkItem item;
             if (null == convertView || !(convertView instanceof BookmarkItem)) {
-                item = new BookmarkItem(BrowserHistoryPage.this);
+                item = new BookmarkItem(getContext());
                 // Add padding on the left so it will be indented from the
                 // arrows on the group views.
                 item.setPadding(item.getPaddingLeft() + 10,
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
index 78fcb4b..35267c0 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryActivity.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
@@ -17,22 +17,39 @@
 package com.android.browser;
 
 import android.app.Activity;
-import android.app.TabActivity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
 import android.content.Intent;
-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.View;
 import android.webkit.WebIconDatabase;
 import android.webkit.WebIconDatabase.IconListener;
-import android.widget.TabHost;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
 
 import java.util.HashMap;
 import java.util.Vector;
 
-public class CombinedBookmarkHistoryActivity extends TabActivity
-        implements TabHost.OnTabChangeListener {
+interface BookmarksHistoryCallbacks {
+    public void onUrlSelected(String url, boolean newWindow);
+    public void onRemoveParentChildRelationShips();
+}
+
+public class CombinedBookmarkHistoryActivity extends Activity
+        implements BookmarksHistoryCallbacks, OnItemClickListener {
+    final static String NEWTAB_MODE = "newtab_mode";
+    final static String STARTING_FRAGMENT = "fragment";
+
+    final static int FRAGMENT_ID_BOOKMARKS = 1;
+    final static int FRAGMENT_ID_HISTORY = 2;
+
     /**
      * Used to inform BrowserActivity to remove the parent/child relationships
      * from all the tabs.
@@ -53,11 +70,7 @@
      */
     private boolean mNewTabMode;
 
-    /* package */ static String BOOKMARKS_TAB = "bookmark";
-    /* package */ static String HISTORY_TAB = "history";
-    /* package */ static String STARTING_TAB = "tab";
-
-    final static String NEWTAB_MODE = "newtab_mode";
+    long mCurrentFragment;
 
     static class IconListenerSet implements IconListener {
         // Used to store favicons as we get them from the database
@@ -70,6 +83,7 @@
             mUrlsToIcons = new HashMap<String, Bitmap>();
             mListeners = new Vector<IconListener>();
         }
+        @Override
         public void onReceivedIcon(String url, Bitmap icon) {
             mUrlsToIcons.put(url, icon);
             for (IconListener listener : mListeners) {
@@ -83,9 +97,10 @@
             mListeners.remove(listener);
         }
         public Bitmap getFavicon(String url) {
-            return (Bitmap) mUrlsToIcons.get(url);
+            return mUrlsToIcons.get(url);
         }
     }
+
     private static IconListenerSet sIconListenerSet;
     static IconListenerSet getIconListenerSet() {
         if (null == sIconListenerSet) {
@@ -97,75 +112,77 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.tabs);
+        setContentView(R.layout.bookmarks_history);
 
         setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
 
-        getTabHost().setOnTabChangedListener(this);
+        ListView list = (ListView) findViewById(android.R.id.list);
+        list.setOnItemClickListener(this);
+        MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
+        cursor.newRow().add(getString(R.string.bookmarks)).add(FRAGMENT_ID_BOOKMARKS);
+        cursor.newRow().add(getString(R.string.history)).add(FRAGMENT_ID_HISTORY);
+        list.setAdapter(new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
+                new String[] { "name" }, new int[] { android.R.id.text1 }));
 
+        int startingFragment = FRAGMENT_ID_BOOKMARKS; 
         Bundle extras = getIntent().getExtras();
-
         if (extras != null) {
             mNewTabMode = extras.getBoolean(NEWTAB_MODE);
+            startingFragment = extras.getInt(STARTING_FRAGMENT, FRAGMENT_ID_BOOKMARKS);
         }
 
-        Intent bookmarksIntent = new Intent(this, BrowserBookmarksPage.class);
-        if (extras != null) {
-            bookmarksIntent.putExtras(extras);
-        }
-        createTab(bookmarksIntent, R.string.tab_bookmarks,
-                R.drawable.browser_bookmark_tab, BOOKMARKS_TAB);
-
-        Intent historyIntent = new Intent(this, BrowserHistoryPage.class);
-        String defaultTab = null;
-        if (extras != null) {
-            historyIntent.putExtras(extras);
-            defaultTab = extras.getString(STARTING_TAB);
-        }
-        createTab(historyIntent, R.string.tab_history,
-                R.drawable.browser_history_tab, HISTORY_TAB);
-
-        if (defaultTab != null) {
-            getTabHost().setCurrentTab(2);
-        }
+        // Start up the default fragment
+        loadFragment(startingFragment);
 
         // XXX: Must do this before launching the AsyncTask to avoid a
         // potential crash if the icon database has not been created.
         WebIconDatabase.getInstance();
+
         // Do this every time we launch the activity in case a new favicon was
         // added to the webkit db.
         (new AsyncTask<Void, Void, Void>() {
+            @Override
             public Void doInBackground(Void... v) {
                 Browser.requestAllIcons(getContentResolver(),
-                    Browser.BookmarkColumns.FAVICON + " is NULL",
-                    getIconListenerSet());
+                        Browser.BookmarkColumns.FAVICON + " is NULL", getIconListenerSet());
                 return null;
             }
         }).execute();
     }
 
-    private void createTab(Intent intent, int labelResId, int iconResId,
-            String tab) {
-        Resources resources = getResources();
-        TabHost tabHost = getTabHost();
-        tabHost.addTab(tabHost.newTabSpec(tab).setIndicator(
-                resources.getText(labelResId), resources.getDrawable(iconResId))
-                .setContent(intent));
-    }
-    // Copied from DialTacts Activity
-    /** {@inheritDoc} */
-    public void onTabChanged(String tabId) {
-        Activity activity = getLocalActivityManager().getActivity(tabId);
-        if (activity != null) {
-            activity.onWindowFocusChanged(true);
+    private void loadFragment(int id) {
+        String fragmentClassName;
+        switch (id) {
+            case FRAGMENT_ID_BOOKMARKS:
+                fragmentClassName = BrowserBookmarksPage.class.getName();
+                break;
+            case FRAGMENT_ID_HISTORY:
+                fragmentClassName = BrowserHistoryPage.class.getName();
+                break;
+            default:
+                throw new IllegalArgumentException();
         }
+        mCurrentFragment = id;
+
+        FragmentManager fm = getFragmentManager();
+        FragmentTransaction transaction = fm.openTransaction();
+        Fragment frag = Fragment.instantiate(this, fragmentClassName, getIntent().getExtras());
+        transaction.replace(R.id.fragment, frag);
+        transaction.commit();
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        if (id == mCurrentFragment) return;
+        loadFragment((int) id);
     }
 
     /**
      * Store extra data in the Intent to return to the calling Activity to tell
      * it to clear the parent/child relationships from all tabs.
      */
-    /* package */ void removeParentChildRelationShips() {
+    @Override
+    public void onRemoveParentChildRelationShips() {
         mExtraData = BrowserSettings.PREF_CLEAR_HISTORY;
     }
 
@@ -175,7 +192,7 @@
      * @param resultCode Uses same codes as Activity.setResult
      * @param data Intent returned to onActivityResult.
      */
-    /* package */ void setResultFromChild(int resultCode, Intent data) {
+    private void setResultFromChild(int resultCode, Intent data) {
         mResultCode = resultCode;
         mResultData = data;
     }
@@ -194,4 +211,19 @@
         setResult(mResultCode, mResultData);
         super.finish();
     }
+
+    /**
+     * Report back to the calling activity to load a site.
+     * @param url   Site to load.
+     * @param newWindow True if the URL should be loaded in a new window
+     */
+    @Override
+    public void onUrlSelected(String url, boolean newWindow) {
+        Intent intent = new Intent().setAction(url);
+        if (newWindow) {
+            intent.putExtra("new_window", true);
+        }
+        setResultFromChild(RESULT_OK, intent);
+        finish();
+    }
 }
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index ab24c03..d8eeee3 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -97,12 +97,12 @@
 
         // Bookmarks
         HashMap<String, String> map = BOOKMARKS_PROJECTION_MAP;
+        map.put(Bookmarks._ID, qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID));
         map.put(Bookmarks.TITLE, Bookmarks.TITLE);
         map.put(Bookmarks.URL, Bookmarks.URL);
         map.put(Bookmarks.FAVICON, Bookmarks.FAVICON);
         map.put(Bookmarks.THUMBNAIL, Bookmarks.THUMBNAIL);
         map.put(Bookmarks.TOUCH_ICON, Bookmarks.TOUCH_ICON);
-        map.put(Bookmarks._ID, TABLE_BOOKMARKS + "._id AS _id");
         map.put(Bookmarks.IS_FOLDER, Bookmarks.IS_FOLDER);
         map.put(Bookmarks.PARENT, Bookmarks.PARENT);
         map.put(Bookmarks.POSITION, Bookmarks.POSITION);