update bookmarks & history page

       convert combopage from activity to view
       embed combopage in main layout
       handle callbacks in BrowserActivity

Change-Id: Ie5f092f5de677a960181544e7519c2f7d5cb86c1
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 1263f3f..10ebb56 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -35,7 +35,6 @@
 import android.content.ContentProvider;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
-import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -68,9 +67,8 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.provider.Browser;
-import android.provider.BrowserContract;
-import android.provider.ContactsContract;
 import android.provider.BrowserContract.Images;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Intents.Insert;
 import android.provider.Downloads;
 import android.provider.MediaStore;
@@ -89,7 +87,6 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -131,8 +128,8 @@
 import java.util.regex.Pattern;
 
 public class BrowserActivity extends Activity
-    implements View.OnCreateContextMenuListener, DownloadListener,
-    PopupMenu.OnMenuItemClickListener {
+        implements View.OnCreateContextMenuListener, DownloadListener,
+        PopupMenu.OnMenuItemClickListener, BookmarksHistoryCallbacks {
 
     /* Define some aliases to make these debugging flags easier to refer to.
      * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
@@ -168,6 +165,8 @@
      */
     private FrameLayout mBrowserFrameLayout;
 
+    private CombinedBookmarkHistoryView mComboView;
+
     private boolean mXLargeScreenSize;
 
     private Boolean mIsProviderPresent = null;
@@ -973,6 +972,7 @@
         if (mActiveTabsPage != null) {
             removeActiveTabPage(true);
         }
+        removeComboView();
 
         cancelStopToast();
 
@@ -1312,6 +1312,8 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
+        // menu remains active, so ensure comboview is dismissed
+        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) {
@@ -1348,7 +1350,7 @@
                 break;
 
             case R.id.bookmarks_menu_id:
-                bookmarksOrHistoryPicker(false, false);
+                bookmarksOrHistoryPicker(false);
                 break;
 
             case R.id.active_tabs_menu_id:
@@ -1448,7 +1450,7 @@
                 break;
 
             case R.id.classic_history_menu_id:
-                bookmarksOrHistoryPicker(true, false);
+                bookmarksOrHistoryPicker(true);
                 break;
 
             case R.id.title_bar_share_page_url:
@@ -2226,8 +2228,9 @@
                     event.startTracking();
                     return true;
                 } else if (mCustomView == null && mActiveTabsPage == null
+                        && mComboView == null
                         && event.isLongPress()) {
-                    bookmarksOrHistoryPicker(true, false);
+                    bookmarksOrHistoryPicker(true);
                     return true;
                 }
                 break;
@@ -2250,6 +2253,8 @@
                     } else if (mActiveTabsPage != null) {
                         // if tab page is showing, hide it
                         removeActiveTabPage(true);
+                    } else if (mComboView != null) {
+                        removeComboView();
                     } else {
                         WebView subwindow = mTabControl.getCurrentSubWindow();
                         if (subwindow != null) {
@@ -2331,7 +2336,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case OPEN_BOOKMARKS:
-                    bookmarksOrHistoryPicker(false, false);
+                    bookmarksOrHistoryPicker(false);
                     break;
                 case FOCUS_NODE_HREF:
                 {
@@ -3780,46 +3785,57 @@
         }
     }
 
+    /**
+     * callback from ComboPage when bookmark/history selection
+     */
+    @Override
+    public void onUrlSelected(String url, boolean newTab) {
+        removeComboView();
+        if (!TextUtils.isEmpty(url)) {
+            if (newTab) {
+                openTab(url, false);
+            } else {
+                final Tab currentTab = mTabControl.getCurrentTab();
+                dismissSubWindow(currentTab);
+                loadUrl(getTopWindow(), url);
+            }
+        }
+    }
+
+    /**
+     * callback from ComboPage when dismissed
+     */
+    @Override
+    public void onComboCanceled() {
+        removeComboView();
+    }
+
+    /**
+     * dismiss the ComboPage
+     */
+    /* package */ void removeComboView() {
+        if (mComboView != null) {
+            mContentView.removeView(mComboView);
+            mTitleBar.setVisibility(View.VISIBLE);
+            mMenuState = R.id.MAIN_MENU;
+            attachTabToContentView(mTabControl.getCurrentTab());
+            getTopWindow().requestFocus();
+            mComboView = null;
+        }
+    }
+
+    /**
+     * callback from ComboPage when clear history is requested
+     */
+    public void onRemoveParentChildRelationships() {
+        mTabControl.removeParentChildRelationShips();
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode,
                                     Intent intent) {
         if (getTopWindow() == null) return;
-
         switch (requestCode) {
-            case COMBO_PAGE:
-                if (resultCode == RESULT_OK && intent != null) {
-                    String data = intent.getAction();
-                    Bundle extras = intent.getExtras();
-                    if (extras != null &&
-                            extras.getBoolean(
-                                    CombinedBookmarkHistoryActivity.EXTRA_OPEN_NEW_WINDOW,
-                                    false)) {
-                        openTab(data, false);
-                    } else if ((extras != null) &&
-                            extras.getBoolean(CombinedBookmarkHistoryActivity.NEWTAB_MODE)) {
-                        openTab(data, true);
-                    } else {
-                        final Tab currentTab = mTabControl.getCurrentTab();
-                        dismissSubWindow(currentTab);
-                        if (data != null && data.length() != 0) {
-                            loadUrl(getTopWindow(), data);
-                        }
-                    }
-                } else if (resultCode == RESULT_CANCELED) {
-                    if (intent != null) {
-                        float evtx = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_X, -1);
-                        float evty = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_Y, -1);
-                        long now = System.currentTimeMillis();
-                        MotionEvent evt = MotionEvent.obtain(now, now,
-                                MotionEvent.ACTION_DOWN, evtx, evty, 0);
-                        dispatchTouchEvent(evt);
-                        MotionEvent up = MotionEvent.obtain(evt);
-                        up.setAction(MotionEvent.ACTION_UP);
-                        dispatchTouchEvent(up);
-                    }
-                }
-                // Deliberately fall through to PREFERENCES_PAGE, since the
-                // same extra may be attached to the COMBO_PAGE
             case PREFERENCES_PAGE:
                 if (resultCode == RESULT_OK && intent != null) {
                     String action = intent.getStringExtra(Intent.EXTRA_TEXT);
@@ -3940,13 +3956,11 @@
      * @param startWithHistory If true, open starting on the history tab.
      *                         Otherwise, start with the bookmarks tab.
      */
-    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory, boolean newTabMode) {
+    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
         WebView current = mTabControl.getCurrentWebView();
         if (current == null) {
             return;
         }
-        Intent intent = new Intent(this,
-                CombinedBookmarkHistoryActivity.class);
         String title = current.getTitle();
         String url = current.getUrl();
         Bitmap thumbnail = createScreenshot(current, getDesiredThumbnailWidth(this),
@@ -3965,28 +3979,22 @@
         if (title == null) {
             title = url;
         }
-        intent.putExtra("title", title);
-        intent.putExtra("url", url);
-        intent.putExtra("thumbnail", thumbnail);
+        Bundle extras = new Bundle();
+        extras.putString("title", title);
+        extras.putString("url", url);
+        extras.putParcelable("thumbnail", thumbnail);
         // Disable opening in a new window if we have maxed out the windows
-        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
-        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
-        if (startWithHistory) {
-            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_FRAGMENT,
-                    CombinedBookmarkHistoryActivity.FRAGMENT_ID_HISTORY);
-        }
-        intent.putExtra(CombinedBookmarkHistoryActivity.NEWTAB_MODE, newTabMode);
-        int top = -1;
-        int height = -1;
-        if (mXLargeScreenSize) {
-            showFakeTitleBar();
-            int titleBarHeight = ((TitleBarXLarge)mFakeTitleBar).getHeightWithoutProgress();
-            top = mTabBar.getBottom() + titleBarHeight;
-            height = getTopWindow().getHeight() - titleBarHeight;
-        }
-        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_TOP, top);
-        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_HEIGHT, height);
-        startActivityForResult(intent, COMBO_PAGE);
+        extras.putBoolean("disable_new_window", !mTabControl.canCreateNewTab());
+        extras.putString("touch_icon_url", current.getTouchIconUrl());
+
+        mComboView = new CombinedBookmarkHistoryView(this,
+                startWithHistory ? CombinedBookmarkHistoryView.FRAGMENT_ID_HISTORY
+                        : CombinedBookmarkHistoryView.FRAGMENT_ID_BOOKMARKS,
+                extras);
+        removeTabFromContentView(mTabControl.getCurrentTab());
+        mTitleBar.setVisibility(View.GONE);
+        hideFakeTitleBar();
+        mContentView.addView(mComboView, COVER_SCREEN_PARAMS);
     }
 
     private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon,
@@ -4015,7 +4023,6 @@
         startActivity(intent);
     }
 
-
     // Called when loading from context menu or LOAD_URL message
     private void loadUrlFromContext(WebView view, String url) {
         // In case the user enters nothing.
@@ -4342,7 +4349,6 @@
     private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
 
     // activity requestCode
-    final static int COMBO_PAGE                 = 1;
     final static int PREFERENCES_PAGE           = 3;
     final static int FILE_SELECTED              = 4;
 
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 4630d4e..be6f8f8 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -77,7 +77,7 @@
     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";
 
@@ -95,6 +95,13 @@
     Stack<Pair<String, Uri>> mFolderStack = new Stack<Pair<String, Uri>>();
     Button mUpButton;
 
+    static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb, Bundle args) {
+        BrowserBookmarksPage bbp = new BrowserBookmarksPage();
+        bbp.mCallbacks = cb;
+        bbp.setArguments(args);
+        return bbp;
+    }
+
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         switch (id) {
@@ -107,7 +114,6 @@
                 }
                 return new BookmarksLoader(getActivity(), accountType, accountName);
             }
-
             case LOADER_ACCOUNTS_THEN_BOOKMARKS: {
                 return new CursorLoader(getActivity(), Accounts.CONTENT_URI,
                         new String[] { Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_NAME }, null, null,
@@ -328,7 +334,7 @@
         item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
         Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
         if (bitmap == null) {
-            bitmap = CombinedBookmarkHistoryActivity.getIconListenerSet().getFavicon(url);
+            bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url);
         }
         item.setFavicon(bitmap);
     }
@@ -346,12 +352,6 @@
     }
 
     @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        mCallbacks = (BookmarksHistoryCallbacks) activity;
-    }
-
-    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         Context context = getActivity();
@@ -395,7 +395,7 @@
         }
 
         // Add our own listener in case there are favicons that have yet to be loaded.
-        CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(this);
+        CombinedBookmarkHistoryView.getIconListenerSet().addListener(this);
 
         return root;
     }
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 2295804..72d8c28 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -95,6 +95,13 @@
         cm.setText(text);
     }
 
+    static BrowserHistoryPage newInstance(BookmarksHistoryCallbacks cb, Bundle args) {
+        BrowserHistoryPage bhp = new BrowserHistoryPage();
+        bhp.mCallbacks = cb;
+        bhp.setArguments(args);
+        return bhp;
+    }
+
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         switch (id) {
@@ -153,12 +160,6 @@
     }
 
     @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);
@@ -174,15 +175,14 @@
         getLoaderManager().initLoader(LOADER_HISTORY, null, this);
 
         // Register to receive icons in case they haven't all been loaded.
-        CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(mIconReceiver);
-
+        CombinedBookmarkHistoryView.getIconListenerSet().addListener(mIconReceiver);
         return root;
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        CombinedBookmarkHistoryActivity.getIconListenerSet().removeListener(mIconReceiver);
+        CombinedBookmarkHistoryView.getIconListenerSet().removeListener(mIconReceiver);
     }
 
     @Override
@@ -195,20 +195,18 @@
         menu.findItem(R.id.clear_history_menu_id).setVisible(
                 Browser.canClearHistory(getActivity().getContentResolver()));
     }
-    
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.clear_history_menu_id:
                 Browser.clearHistory(getActivity().getContentResolver());
-                // BrowserHistoryPage is always a child of
-                // CombinedBookmarkHistoryActivity
-                mCallbacks.onRemoveParentChildRelationShips();
+                mCallbacks.onRemoveParentChildRelationships();
                 return true;
-                
+
             default:
                 break;
-        }  
+        }
         return super.onOptionsItemSelected(item);
     }
 
@@ -251,13 +249,13 @@
         send.setType("text/plain");
         ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
         menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
-        
+
         super.onCreateContextMenu(menu, v, menuInfo);
     }
-    
+
     @Override
     public boolean onContextItemSelected(MenuItem item) {
-        ExpandableListContextMenuInfo i = 
+        ExpandableListContextMenuInfo i =
             (ExpandableListContextMenuInfo) item.getMenuInfo();
         HistoryItem historyItem = (HistoryItem) i.targetView;
         String url = historyItem.getUrl();
@@ -342,7 +340,7 @@
                 item.setFavicon(BitmapFactory.decodeByteArray(data, 0,
                         data.length));
             } else {
-                item.setFavicon(CombinedBookmarkHistoryActivity
+                item.setFavicon(CombinedBookmarkHistoryView
                         .getIconListenerSet().getFavicon(url));
             }
             return item;
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
deleted file mode 100644
index a98408c..0000000
--- a/src/com/android/browser/CombinedBookmarkHistoryActivity.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.Browser;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.WebIconDatabase;
-import android.webkit.WebIconDatabase.IconListener;
-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;
-
-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 EXTRA_OPEN_NEW_WINDOW = "new_window";
-    final static String STARTING_FRAGMENT = "fragment";
-    final static String EVT_X = "evt_x";
-    final static String EVT_Y = "evt_y";
-    final static String EXTRA_TOP = "top";
-    final static String EXTRA_HEIGHT = "height";
-
-
-    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.
-     */
-    private String mExtraData;
-    /**
-     * Intent to be passed to calling Activity when finished.  Keep a pointer to
-     * it locally so mExtraData can be added.
-     */
-    private Intent mResultData;
-    /**
-     * Result code to pass back to calling Activity when finished.
-     */
-    private int mResultCode;
-
-    /**
-     * Flag to inform the browser to force the result to open in a new tab.
-     */
-    private boolean mNewTabMode;
-
-    private int mRequestedTop;
-    private int mRequestedHeight;
-
-    long mCurrentFragment;
-
-    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
-        // BrowserBookmarksAdapter. They should probably be unified.
-        private HashMap<String, Bitmap> mUrlsToIcons;
-        private Vector<IconListener> mListeners;
-
-        public IconListenerSet() {
-            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) {
-                listener.onReceivedIcon(url, icon);
-            }
-        }
-        public void addListener(IconListener listener) {
-            mListeners.add(listener);
-        }
-        public void removeListener(IconListener listener) {
-            mListeners.remove(listener);
-        }
-        public Bitmap getFavicon(String url) {
-            return mUrlsToIcons.get(url);
-        }
-    }
-
-    private static IconListenerSet sIconListenerSet;
-    static IconListenerSet getIconListenerSet() {
-        if (null == sIconListenerSet) {
-            sIconListenerSet = new IconListenerSet();
-        }
-        return sIconListenerSet;
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.bookmarks_history);
-
-        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(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);
-            mRequestedTop = extras.getInt(EXTRA_TOP, -1);
-            mRequestedHeight = extras.getInt(EXTRA_HEIGHT, -1);
-            startingFragment = extras.getInt(STARTING_FRAGMENT, FRAGMENT_ID_BOOKMARKS);
-        }
-
-        // 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());
-                return null;
-            }
-        }).execute();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        if (mRequestedTop > -1) {
-            WindowManager.LayoutParams lp = getWindow().getAttributes();
-            lp.x = 0;
-            lp.y = mRequestedTop;
-            lp.height = mRequestedHeight;
-            lp.gravity = Gravity.TOP | Gravity.LEFT;
-            getWindow().setAttributes(lp);
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent evt) {
-        if (((evt.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) && (evt.getY() < 0)) {
-            Intent result = new Intent();
-            result.putExtra(EVT_X, evt.getRawX());
-            result.putExtra(EVT_Y, evt.getRawY());
-            setResultFromChild(Activity.RESULT_CANCELED, result);
-            finish();
-            return true;
-        }
-        return super.onTouchEvent(evt);
-    }
-
-    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.
-     */
-    @Override
-    public void onRemoveParentChildRelationShips() {
-        mExtraData = BrowserSettings.PREF_CLEAR_HISTORY;
-    }
-
-    /**
-     * Custom setResult() method so that the Intent can have extra data attached
-     * if necessary.
-     * @param resultCode Uses same codes as Activity.setResult
-     * @param data Intent returned to onActivityResult.
-     */
-    private void setResultFromChild(int resultCode, Intent data) {
-        mResultCode = resultCode;
-        mResultData = data;
-    }
-
-    @Override
-    public void finish() {
-        if (mExtraData != null) {
-            mResultCode = RESULT_OK;
-            if (mResultData == null) mResultData = new Intent();
-            mResultData.putExtra(Intent.EXTRA_TEXT, mExtraData);
-        }
-        if (mNewTabMode) {
-            if (mResultData == null) mResultData = new Intent();
-            mResultData.putExtra(NEWTAB_MODE, true);
-        }
-        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(EXTRA_OPEN_NEW_WINDOW, true);
-        }
-        setResultFromChild(RESULT_OK, intent);
-        finish();
-    }
-}
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
new file mode 100644
index 0000000..b480209
--- /dev/null
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+package com.android.browser;
+
+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.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 java.util.HashMap;
+import java.util.Vector;
+
+interface BookmarksHistoryCallbacks {
+    public void onUrlSelected(String url, boolean newWindow);
+    public void onRemoveParentChildRelationships();
+    public void onComboCanceled();
+}
+
+public class CombinedBookmarkHistoryView extends LinearLayout
+        implements OnItemClickListener {
+
+    final static String STARTING_FRAGMENT = "fragment";
+
+    final static int FRAGMENT_ID_BOOKMARKS = 1;
+    final static int FRAGMENT_ID_HISTORY = 2;
+
+    private BrowserActivity mBrowserActivity;
+
+    private Bundle mExtras;
+
+    long mCurrentFragment;
+
+    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
+        // BrowserBookmarksAdapter. They should probably be unified.
+        private HashMap<String, Bitmap> mUrlsToIcons;
+        private Vector<IconListener> mListeners;
+
+        public IconListenerSet() {
+            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) {
+                listener.onReceivedIcon(url, icon);
+            }
+        }
+        public void addListener(IconListener listener) {
+            mListeners.add(listener);
+        }
+        public void removeListener(IconListener listener) {
+            mListeners.remove(listener);
+        }
+        public Bitmap getFavicon(String url) {
+            return mUrlsToIcons.get(url);
+        }
+    }
+
+    private static IconListenerSet sIconListenerSet;
+    static IconListenerSet getIconListenerSet() {
+        if (null == sIconListenerSet) {
+            sIconListenerSet = new IconListenerSet();
+        }
+        return sIconListenerSet;
+    }
+
+    public CombinedBookmarkHistoryView(Context context, int startingFragment, Bundle extras) {
+        super(context);
+        mBrowserActivity = (BrowserActivity) context;
+        mExtras = extras;
+        View v = LayoutInflater.from(context).inflate(R.layout.bookmarks_history, this);
+        Resources res = context.getResources();
+
+//        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 }));
+
+        // Start up the default fragment
+        loadFragment(startingFragment, mExtras);
+
+        // 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 the view is created in case a new favicon was
+        // added to the webkit db.
+        (new AsyncTask<Void, Void, Void>() {
+            @Override
+            public Void doInBackground(Void... v) {
+                Browser.requestAllIcons(mBrowserActivity.getContentResolver(),
+                        Browser.BookmarkColumns.FAVICON + " is NULL", getIconListenerSet());
+                return null;
+            }
+        }).execute();
+
+    }
+
+    private void loadFragment(int id, Bundle extras) {
+        String fragmentClassName;
+        Fragment fragment = null;
+        switch (id) {
+            case FRAGMENT_ID_BOOKMARKS:
+                fragment = BrowserBookmarksPage.newInstance(mBrowserActivity, extras);
+                break;
+            case FRAGMENT_ID_HISTORY:
+                fragment = BrowserHistoryPage.newInstance(mBrowserActivity, extras);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        mCurrentFragment = id;
+
+        FragmentManager fm = mBrowserActivity.getFragmentManager();
+        FragmentTransaction transaction = fm.openTransaction();
+        transaction.replace(R.id.fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        if (id == mCurrentFragment) return;
+        loadFragment((int) id, mExtras);
+    }
+
+}
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 7994d0a..1d970ea 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -35,16 +35,11 @@
         Bundle extras = new Bundle();
         extras.putBoolean(BrowserBookmarksPage.EXTRA_SHORTCUT, true);
         extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, true);
-        Fragment frag = Fragment.instantiate(this, BrowserBookmarksPage.class.getName(), extras);
+        Fragment frag = BrowserBookmarksPage.newInstance(this, extras);
         transaction.add(android.R.id.content, frag);
         transaction.commit();
     }
 
-    /**
-     * not used for shortcuts
-     */
-    @Override
-    public void onRemoveParentChildRelationShips() {}
 
     /**
      * handle fragment startActivity
@@ -60,6 +55,20 @@
         super.finish();
     }
 
+    // BookmarksHistoryCallbacks
+
+    /**
+     * not used for shortcuts
+     */
+    @Override
+    public void onRemoveParentChildRelationships() {}
+
+    @Override
+    public void onComboCanceled() {
+        setResult(RESULT_CANCELED);
+        finish();
+    }
+
     /**
      * not used for shortcuts
      */
diff --git a/src/com/android/browser/TabBar.java b/src/com/android/browser/TabBar.java
index 9217ef2..696301e 100644
--- a/src/com/android/browser/TabBar.java
+++ b/src/com/android/browser/TabBar.java
@@ -121,6 +121,7 @@
     }
 
     public void onClick(View view) {
+        mBrowserActivity.removeComboView();
         if (mNewTab == view) {
             mBrowserActivity.openTabToHomePage();
         } else if (mTabs.getSelectedTab() == view) {
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index b652e15..57098a9 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -126,7 +126,7 @@
         } else if (mStar == v) {
             mBrowserActivity.promptAddOrInstallBookmark(mStar);
         } else if (mAllButton == v) {
-            mBrowserActivity.bookmarksOrHistoryPicker(false, false);
+            mBrowserActivity.bookmarksOrHistoryPicker(false);
         } else if (mSearchButton == v) {
             search();
         } else if (mStopButton == v) {