Support horizontal swipe in combo activity

 Bug: 5145315

Change-Id: I1e9b4a6bae325244c7a3fb6159deadc3fcf170e6
diff --git a/Android.mk b/Android.mk
index b85a869..06b02d6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -5,7 +5,9 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
         android-common \
-        guava
+        guava \
+        android-support-v13 \
+        android-support-v4 \
 
 LOCAL_SRC_FILES := \
         $(call all-java-files-under, src) \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9a8a73b..e21c539 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -192,8 +192,7 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="ComboViewActivity"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize">
+        <activity android:name="ComboViewActivity">
         </activity>
 
         <!-- Bookmark thumbnail homescreen widget -->
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index e02e2ff..09b442e 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -14,39 +14,25 @@
      limitations under the License.
 -->
 
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/bookmarks"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
     android:paddingTop="@dimen/combo_paddingTop">
-
-    <FrameLayout
-        android:id="@+id/header_container"
+    <com.android.browser.view.BookmarkExpandableView
+        android:id="@+id/grid"
         android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center_horizontal"
+        android:childDivider="@android:color/transparent"
+        android:divider="@android:color/transparent"
+        android:dividerHeight="0dp" />
+    <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
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <com.android.browser.view.BookmarkExpandableView
-            android:id="@+id/grid"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center_horizontal"
-            android:childDivider="@android:color/transparent"
-            android:divider="@android:color/transparent"
-            android:dividerHeight="0dp" />
-        <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>
-
-</LinearLayout>
+</FrameLayout>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index 8fca68a..f1f9217 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -54,7 +54,7 @@
     <dimen name="widgetHorizontalSpacing">14dip</dimen>
     <dimen name="widgetVerticalSpacing">12dip</dimen>
     <!-- For the combined Bookmarks History view -->
-    <dimen name="combo_paddingTop">10dip</dimen>
+    <dimen name="combo_paddingTop">0dip</dimen>
     <dimen name="combo_horizontalSpacing">6dip</dimen>
     <dimen name="tab_view_thumbnail_height">76dip</dimen>
     <!-- Preference activity side margins -->
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index a03590b..46521cb 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -101,14 +101,6 @@
     HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
     BookmarkDragHandler mDragHandler;
 
-    static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb,
-            Bundle args, ViewGroup headerContainer) {
-        BrowserBookmarksPage bbp = new BrowserBookmarksPage();
-        bbp.mCallbacks = cb;
-        bbp.setArguments(args);
-        return bbp;
-    }
-
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         if (id == LOADER_ACCOUNTS) {
@@ -295,9 +287,6 @@
             String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
             item.setUrl(url);
             Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
-            if (bitmap == null) {
-                bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url);
-            }
             item.setFavicon(bitmap);
         }
     }
@@ -311,8 +300,37 @@
         Bundle args = getArguments();
         mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
         setHasOptionsMenu(true);
+        if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) {
+            mCallbacks = new CombinedBookmarksCallbackWrapper(
+                    (CombinedBookmarksCallbacks) getActivity());
+        }
     }
 
+    private static class CombinedBookmarksCallbackWrapper
+            implements BookmarksPageCallbacks {
+
+        private CombinedBookmarksCallbacks mCombinedCallback;
+
+        private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) {
+            mCombinedCallback = cb;
+        }
+
+        @Override
+        public boolean onOpenInNewWindow(String... urls) {
+            mCombinedCallback.openInNewTab(urls);
+            return true;
+        }
+
+        @Override
+        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+            if (isFolder) {
+                return false;
+            }
+            mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c));
+            return true;
+        }
+    };
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
@@ -520,10 +538,6 @@
         loader.forceLoad();
     }
 
-    public boolean onBackPressed() {
-        return false;
-    }
-
     public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
         mCallbacks = callbackListener;
     }
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 942a8fd..6625e55 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -61,8 +61,6 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.browser.CombinedBookmarkHistoryView.CombinedBookmarksCallbacks;
-
 /**
  * Activity for displaying the browser's history, divided into
  * days of viewing.
@@ -112,13 +110,6 @@
         cm.setText(text);
     }
 
-    static BrowserHistoryPage newInstance(CombinedBookmarksCallbacks cb, Bundle args) {
-        BrowserHistoryPage bhp = new BrowserHistoryPage();
-        bhp.mCallback = cb;
-        bhp.setArguments(args);
-        return bhp;
-    }
-
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
         Uri.Builder combinedBuilder = Combined.CONTENT_URI.buildUpon();
@@ -208,6 +199,7 @@
         mDisableNewWindow = args.getBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, false);
         int mvlimit = getResources().getInteger(R.integer.most_visits_limit);
         mMostVisitsLimit = Integer.toString(mvlimit);
+        mCallback = (CombinedBookmarksCallbacks) getActivity();
     }
 
     @Override
@@ -663,9 +655,6 @@
             if (data != null) {
                 item.setFavicon(BitmapFactory.decodeByteArray(data, 0,
                         data.length));
-            } else {
-                item.setFavicon(CombinedBookmarkHistoryView
-                        .getIconListenerSet().getFavicon(url));
             }
             item.setIsBookmark(cursor.getInt(HistoryQuery.INDEX_IS_BOOKMARK) == 1);
             return item;
diff --git a/src/com/android/browser/BrowserSnapshotPage.java b/src/com/android/browser/BrowserSnapshotPage.java
index 0953879..72aa1b9 100644
--- a/src/com/android/browser/BrowserSnapshotPage.java
+++ b/src/com/android/browser/BrowserSnapshotPage.java
@@ -43,7 +43,6 @@
 import android.widget.ResourceCursorAdapter;
 import android.widget.TextView;
 
-import com.android.browser.CombinedBookmarkHistoryView.CombinedBookmarksCallbacks;
 import com.android.browser.provider.SnapshotProvider.Snapshots;
 
 import java.text.DateFormat;
@@ -76,12 +75,10 @@
     SnapshotAdapter mAdapter;
     CombinedBookmarksCallbacks mCallback;
 
-    public static BrowserSnapshotPage newInstance(CombinedBookmarksCallbacks cb,
-            Bundle extras) {
-        BrowserSnapshotPage instance = new BrowserSnapshotPage();
-        instance.mCallback = cb;
-        instance.setArguments(extras);
-        return instance;
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mCallback = (CombinedBookmarksCallbacks) getActivity();
     }
 
     @Override
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
deleted file mode 100644
index 86afe1e..0000000
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ /dev/null
@@ -1,297 +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.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.Activity;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.res.Configuration;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup;
-import android.webkit.WebIconDatabase.IconListener;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-
-import com.android.browser.UI.ComboViews;
-
-import java.util.HashMap;
-import java.util.Vector;
-
-public class CombinedBookmarkHistoryView extends LinearLayout
-        implements OnTouchListener, TabListener {
-
-    final static String STARTING_FRAGMENT = "fragment";
-
-    final static int INVALID_ID = 0;
-    final static int FRAGMENT_ID_BOOKMARKS = 1;
-    final static int FRAGMENT_ID_HISTORY = 2;
-    final static int FRAGMENT_ID_SNAPSHOTS = 3;
-
-    private ActionBar mActionBar;
-    private FragmentManager mFragmentManager;
-
-    private Bundle mExtras;
-
-    int mCurrentFragment = INVALID_ID;
-
-    ActionBar.Tab mTabBookmarks;
-    ActionBar.Tab mTabHistory;
-    ActionBar.Tab mTabSnapshots;
-    ViewGroup mBookmarksHeader;
-
-    BrowserBookmarksPage mBookmarks;
-    BrowserHistoryPage mHistory;
-    BrowserSnapshotPage mSnapshots;
-    CombinedBookmarksCallbacks mCallback;
-
-    public static interface CombinedBookmarksCallbacks {
-        void openUrl(String url);
-        void openInNewTab(String... urls);
-        void openSnapshot(long id);
-        void close();
-    }
-
-    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(Activity activity,
-            CombinedBookmarksCallbacks cb, ComboViews startingView,
-            Bundle extras) {
-        super(activity);
-        mExtras = extras;
-        mActionBar = activity.getActionBar();
-        mCallback = cb;
-        mFragmentManager = activity.getFragmentManager();
-
-        View v = LayoutInflater.from(activity).inflate(R.layout.bookmarks_history, this);
-        v.setOnTouchListener(this);
-
-        mBookmarksHeader = new FrameLayout(activity);
-        mBookmarksHeader.setLayoutParams(new FrameLayout.LayoutParams(
-                FrameLayout.LayoutParams.WRAP_CONTENT,
-                FrameLayout.LayoutParams.MATCH_PARENT,
-                Gravity.CENTER_VERTICAL));
-
-        // Start up the default fragment
-        initFragments(mExtras);
-
-        setupActionBar(startingView);
-    }
-
-    void setupActionBar(ComboViews startingView) {
-        if (BrowserActivity.isTablet(mContext)) {
-            mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
-                    | ActionBar.DISPLAY_USE_LOGO);
-        } else {
-            mActionBar.setDisplayOptions(0);
-        }
-        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-        mActionBar.removeAllTabs();
-        mTabBookmarks = mActionBar.newTab();
-        mTabBookmarks.setText(R.string.tab_bookmarks);
-        mTabBookmarks.setTabListener(this);
-        mActionBar.addTab(mTabBookmarks, ComboViews.Bookmarks == startingView);
-        mTabHistory = mActionBar.newTab();
-        mTabHistory.setText(R.string.tab_history);
-        mTabHistory.setTabListener(this);
-        mActionBar.addTab(mTabHistory, ComboViews.History == startingView);
-        mTabSnapshots = mActionBar.newTab();
-        mTabSnapshots.setText(R.string.tab_snapshots);
-        mTabSnapshots.setTabListener(this);
-        mActionBar.addTab(mTabSnapshots, ComboViews.Snapshots == startingView);
-        mActionBar.setCustomView(mBookmarksHeader);
-        mActionBar.show();
-    }
-
-    void tearDownActionBar() {
-        if (mActionBar != null) {
-            mActionBar.removeAllTabs();
-            mTabBookmarks.setTabListener(null);
-            mTabHistory.setTabListener(null);
-            mTabSnapshots.setTabListener(null);
-            mTabBookmarks = null;
-            mTabHistory = null;
-            mTabSnapshots = null;
-            mActionBar = null;
-        }
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (mCurrentFragment == FRAGMENT_ID_HISTORY) {
-            // Warning, ugly hack below
-            // This is done because history uses orientation-specific padding
-            mHistory = BrowserHistoryPage.newInstance(mCallback, mHistory.getArguments());
-            mFragmentManager.beginTransaction().replace(R.id.fragment, mHistory).commit();
-        }
-    }
-
-    private BookmarksPageCallbacks mBookmarkCallbackWrapper = new BookmarksPageCallbacks() {
-        @Override
-        public boolean onOpenInNewWindow(String... urls) {
-            mCallback.openInNewTab(urls);
-            return true;
-        }
-
-        @Override
-        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
-            if (isFolder) {
-                return false;
-            }
-            mCallback.openUrl(BrowserBookmarksPage.getUrl(c));
-            return true;
-        }
-    };
-
-    private void initFragments(Bundle extras) {
-        mBookmarks = BrowserBookmarksPage.newInstance(mBookmarkCallbackWrapper,
-                extras, mBookmarksHeader);
-        mHistory = BrowserHistoryPage.newInstance(mCallback, extras);
-        mSnapshots = BrowserSnapshotPage.newInstance(mCallback, extras);
-    }
-
-    private void loadFragment(int id, FragmentTransaction ft) {
-        if (mCurrentFragment == id) return;
-
-        switch (id) {
-            case FRAGMENT_ID_BOOKMARKS:
-                ft.replace(R.id.fragment, mBookmarks);
-                break;
-            case FRAGMENT_ID_HISTORY:
-                ft.replace(R.id.fragment, mHistory);
-                break;
-            case FRAGMENT_ID_SNAPSHOTS:
-                ft.replace(R.id.fragment, mSnapshots);
-                break;
-            default:
-                throw new IllegalArgumentException();
-        }
-        mCurrentFragment = id;
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        tearDownActionBar();
-        if (mCurrentFragment != INVALID_ID) {
-            try {
-                FragmentTransaction transaction = mFragmentManager.beginTransaction();
-                if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
-                    transaction.remove(mBookmarks);
-                } else if (mCurrentFragment == FRAGMENT_ID_HISTORY) {
-                    transaction.remove(mHistory);
-                } else if (mCurrentFragment == FRAGMENT_ID_SNAPSHOTS) {
-                    transaction.remove(mSnapshots);
-                }
-                transaction.commit();
-            } catch (IllegalStateException ex) {
-                // This exception is thrown if the fragment isn't added
-                // This will happen if the activity is finishing, and the
-                // fragment was already removed before this view was detached
-                // Aka, success!
-            }
-            mCurrentFragment = INVALID_ID;
-        }
-    }
-
-    /**
-     * callback for back key presses
-     */
-    boolean onBackPressed() {
-        if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
-            return mBookmarks.onBackPressed();
-        }
-        return false;
-    }
-
-    /**
-     * capture touch events to prevent them from going to the underlying
-     * WebView
-     */
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        return true;
-    }
-
-    @Override
-    public void onTabReselected(Tab tab, FragmentTransaction ft) {
-        // Ignore
-    }
-
-    @Override
-    public void onTabSelected(Tab tab, FragmentTransaction ft) {
-        if (tab == mTabBookmarks) {
-            loadFragment(FRAGMENT_ID_BOOKMARKS, ft);
-        } else if (tab == mTabHistory) {
-            loadFragment(FRAGMENT_ID_HISTORY, ft);
-        } else if (tab == mTabSnapshots) {
-            loadFragment(FRAGMENT_ID_SNAPSHOTS, ft);
-        }
-    }
-
-    @Override
-    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-        // Ignore
-    }
-
-}
diff --git a/src/com/android/browser/CombinedBookmarksCallbacks.java b/src/com/android/browser/CombinedBookmarksCallbacks.java
new file mode 100644
index 0000000..cdffb6b
--- /dev/null
+++ b/src/com/android/browser/CombinedBookmarksCallbacks.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 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;
+
+public interface CombinedBookmarksCallbacks {
+    void openUrl(String url);
+    void openInNewTab(String... urls);
+    void openSnapshot(long id);
+    void close();
+}
\ No newline at end of file
diff --git a/src/com/android/browser/ComboViewActivity.java b/src/com/android/browser/ComboViewActivity.java
index cea1884..9bdce18 100644
--- a/src/com/android/browser/ComboViewActivity.java
+++ b/src/com/android/browser/ComboViewActivity.java
@@ -15,18 +15,26 @@
  */
 package com.android.browser;
 
+import android.app.ActionBar;
 import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.v13.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
 import android.view.Menu;
 import android.view.MenuItem;
 
-import com.android.browser.CombinedBookmarkHistoryView.CombinedBookmarksCallbacks;
 import com.android.browser.UI.ComboViews;
 
+import java.util.ArrayList;
+
 public class ComboViewActivity extends Activity implements CombinedBookmarksCallbacks {
 
+    private static final String STATE_SELECTED_TAB = "tab";
     public static final String EXTRA_COMBO_ARGS = "combo_args";
     public static final String EXTRA_INITIAL_VIEW = "initial_view";
 
@@ -34,8 +42,8 @@
     public static final String EXTRA_OPEN_ALL = "open_all";
     public static final String EXTRA_CURRENT_URL = "url";
     public static final String EXTRA_BOOKMARK_PAGE = "create_bookmark";
-
-    private CombinedBookmarkHistoryView mComboView;
+    private ViewPager mViewPager;
+    private TabsAdapter mTabsAdapter;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -47,9 +55,50 @@
         ComboViews startingView = svStr != null
                 ? ComboViews.valueOf(svStr)
                 : ComboViews.Bookmarks;
-        mComboView = new CombinedBookmarkHistoryView(this, this,
-                startingView, args);
-        setContentView(mComboView);
+        mViewPager = new ViewPager(this);
+        mViewPager.setId(R.id.tab_view);
+        setContentView(mViewPager);
+
+        final ActionBar bar = getActionBar();
+        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+        if (BrowserActivity.isTablet(this)) {
+            bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
+                    | ActionBar.DISPLAY_USE_LOGO);
+        } else {
+            bar.setDisplayOptions(0);
+        }
+
+        mTabsAdapter = new TabsAdapter(this, mViewPager);
+        mTabsAdapter.addTab(bar.newTab().setText(R.string.tab_bookmarks),
+                BrowserBookmarksPage.class, args);
+        mTabsAdapter.addTab(bar.newTab().setText(R.string.tab_history),
+                BrowserHistoryPage.class, args);
+        mTabsAdapter.addTab(bar.newTab().setText(R.string.tab_snapshots),
+                BrowserSnapshotPage.class, args);
+
+        if (savedInstanceState != null) {
+            bar.setSelectedNavigationItem(
+                    savedInstanceState.getInt(STATE_SELECTED_TAB, 0));
+        } else {
+            switch (startingView) {
+            case Bookmarks:
+                mViewPager.setCurrentItem(0);
+                break;
+            case History:
+                mViewPager.setCurrentItem(1);
+                break;
+            case Snapshots:
+                mViewPager.setCurrentItem(2);
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(STATE_SELECTED_TAB,
+                getActionBar().getSelectedNavigationIndex());
     }
 
     @Override
@@ -81,13 +130,6 @@
     }
 
     @Override
-    public void onBackPressed() {
-        if (!mComboView.onBackPressed()) {
-            super.onBackPressed();
-        }
-    }
-
-    @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.combined, menu);
         return super.onCreateOptionsMenu(menu);
@@ -107,4 +149,101 @@
         }
         return super.onOptionsItemSelected(item);
     }
+
+    /**
+     * This is a helper class that implements the management of tabs and all
+     * details of connecting a ViewPager with associated TabHost.  It relies on a
+     * trick.  Normally a tab host has a simple API for supplying a View or
+     * Intent that each tab will show.  This is not sufficient for switching
+     * between pages.  So instead we make the content part of the tab host
+     * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
+     * view to show as the tab content.  It listens to changes in tabs, and takes
+     * care of switch to the correct page in the ViewPager whenever the selected
+     * tab changes.
+     */
+    public static class TabsAdapter extends FragmentPagerAdapter
+            implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
+        private final Context mContext;
+        private final ActionBar mActionBar;
+        private final ViewPager mViewPager;
+        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+
+        static final class TabInfo {
+            private final Class<?> clss;
+            private final Bundle args;
+
+            TabInfo(Class<?> _class, Bundle _args) {
+                clss = _class;
+                args = _args;
+            }
+        }
+
+        public TabsAdapter(Activity activity, ViewPager pager) {
+            super(activity.getFragmentManager());
+            mContext = activity;
+            mActionBar = activity.getActionBar();
+            mViewPager = pager;
+            mViewPager.setAdapter(this);
+            mViewPager.setOnPageChangeListener(this);
+        }
+
+        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
+            TabInfo info = new TabInfo(clss, args);
+            tab.setTag(info);
+            tab.setTabListener(this);
+            mTabs.add(info);
+            mActionBar.addTab(tab);
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public int getCount() {
+            return mTabs.size();
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            TabInfo info = mTabs.get(position);
+            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
+        }
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            mActionBar.setSelectedNavigationItem(position);
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+        }
+
+        @Override
+        public void onTabSelected(android.app.ActionBar.Tab tab,
+                FragmentTransaction ft) {
+            Object tag = tab.getTag();
+            for (int i=0; i<mTabs.size(); i++) {
+                if (mTabs.get(i) == tag) {
+                    mViewPager.setCurrentItem(i);
+                }
+            }
+        }
+
+        @Override
+        public void onTabUnselected(android.app.ActionBar.Tab tab,
+                FragmentTransaction ft) {
+        }
+
+        @Override
+        public void onTabReselected(android.app.ActionBar.Tab tab,
+                FragmentTransaction ft) {
+        }
+    }
+
+    private static String makeFragmentName(int viewId, int index) {
+        return "android:switcher:" + viewId + ":" + index;
+    }
+
 }
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 134bf23..612116e 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -63,13 +63,6 @@
     }
 
     @Override
-    public void onBackPressed() {
-        if (!mBookmarks.onBackPressed()) {
-            super.onBackPressed();
-        }
-    }
-
-    @Override
     public void onClick(View v) {
         switch (v.getId()) {
         case R.id.cancel: