Use custom ViewPagerTabs

Use the custom ViewPagerTabs from contacts common.
In portrait, the tabs are below the toolbar. In landscape
the tabs are inside the toolbar.

Bug: 16158921
Bug: 15616182
Change-Id: I6c2067fdc10fa15ebd6e0fa93aa1c4f8e7cd45a7
diff --git a/res/drawable/action_bar_tab.xml b/res/drawable/action_bar_tab.xml
deleted file mode 100644
index 3982a3b..0000000
--- a/res/drawable/action_bar_tab.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2013 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.
--->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/tab_pressed_color">
-    <item>
-        <selector>
-            <item android:drawable="@drawable/tab_selected"
-                    android:state_focused="false"
-                    android:state_pressed="false"
-                    android:state_selected="true" />
-            <item android:drawable="@drawable/tab_selected_focused"
-                    android:state_focused="true"
-                    android:state_pressed="false"
-                    android:state_selected="true" />
-            <item android:drawable="@drawable/tab_unselected_focused"
-                    android:state_focused="true"
-                    android:state_pressed="false"
-                    android:state_selected="false" />
-            <item android:drawable="@drawable/tab_selected"
-                    android:state_selected="true" />
-            <item android:drawable="@color/tab_default_color" />
-        </selector>
-    </item>
-</ripple>
\ No newline at end of file
diff --git a/res/drawable/tab_selected.xml b/res/drawable/tab_selected.xml
deleted file mode 100644
index 9eec3c4..0000000
--- a/res/drawable/tab_selected.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2013 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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-    <!-- Tab selected underline -->
-    <item android:drawable="@color/tab_selected_color" />
-    <!-- Tab background -->
-    <item android:drawable="@color/tab_default_color"
-        android:bottom="@dimen/tab_selected_underline_height" />
-</layer-list>
\ No newline at end of file
diff --git a/res/drawable/tab_selected_focused.xml b/res/drawable/tab_selected_focused.xml
deleted file mode 100644
index ba5162a..0000000
--- a/res/drawable/tab_selected_focused.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2013 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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-    <!-- Tab selected underline -->
-    <item android:drawable="@color/tab_selected_color" />
-    <!-- Tab background -->
-    <item android:drawable="@color/tab_default_color"
-        android:bottom="@dimen/tab_selected_underline_height" />
-    <!-- Focus rectangle -->
-    <item>
-        <shape android:shape="rectangle" >
-            <stroke
-                android:width="@dimen/tab_focused_stroke_width"
-                android:color="@color/focus_color" />
-        </shape>
-    </item>
-</layer-list>
\ No newline at end of file
diff --git a/res/drawable/tab_unselected_focused.xml b/res/drawable/tab_unselected_focused.xml
deleted file mode 100644
index 1e4c6c3..0000000
--- a/res/drawable/tab_unselected_focused.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2013 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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Tab background -->
-    <item android:drawable="@color/tab_default_color" />
-    <!-- Focus rectangle -->
-    <item>
-        <shape android:shape="rectangle" >
-            <stroke
-                android:width="@dimen/tab_focused_stroke_width"
-                android:color="@color/focus_color" />
-        </shape>
-    </item>
-</layer-list>
\ No newline at end of file
diff --git a/res/drawable/view_pager_tab_background.xml b/res/drawable/view_pager_tab_background.xml
new file mode 100644
index 0000000..1ba6c57
--- /dev/null
+++ b/res/drawable/view_pager_tab_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 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
+  -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/tab_ripple_color">
+    <item android:id="@android:id/mask">
+        <color android:color="@android:color/white" />
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/res/layout-land/people_activity_toolbar.xml b/res/layout-land/people_activity_toolbar.xml
new file mode 100644
index 0000000..1f86879
--- /dev/null
+++ b/res/layout-land/people_activity_toolbar.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Need to set a non null background on Toolbar in order for MenuItem ripples to be drawn on
+     this view, instead of another. This will *not* cause an additional draw since the
+     background is transparent.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/toolbar_parent"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:background="#00000000"
+    android:elevation="@dimen/tab_elevation"
+    android:layout_height="wrap_content" >
+
+    <Toolbar
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:background="@color/actionbar_background_color"
+        android:id="@+id/toolbar"
+        style="@style/ContactsToolbarStyle" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/people_activity.xml b/res/layout/people_activity.xml
index 6b65945..2624818 100644
--- a/res/layout/people_activity.xml
+++ b/res/layout/people_activity.xml
@@ -19,6 +19,10 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <include
+        layout="@layout/people_activity_toolbar"
+        android:id="@+id/toolbar_parent" />
+
     <!--
         ViewPager for swiping between tabs.  We put StrequentContactListFragment,
         DefaultContactBrowseListFragment and GroupBrowseListFragment at runtime.
@@ -30,6 +34,7 @@
         android:id="@+id/tab_pager"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
+        android:layout_below="@id/toolbar_parent"
         />
 
     <FrameLayout
diff --git a/res/layout/people_activity_tabs_lands.xml b/res/layout/people_activity_tabs_lands.xml
new file mode 100644
index 0000000..525ac3c
--- /dev/null
+++ b/res/layout/people_activity_tabs_lands.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<com.android.contacts.common.list.ViewPagerTabs
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/lists_pager_header"
+    android:layout_width="@dimen/people_activity_landscape_tabs_width"
+    android:layout_height="match_parent"
+    android:textAllCaps="true"
+    android:orientation="horizontal"
+    android:layout_gravity="top"
+    android:layout_weight="0"
+    android:textSize="@dimen/people_activity_landscape_tabs_text_size"
+    style="@style/ContactsActionBarTabTextStyle" />
diff --git a/res/layout/people_activity_toolbar.xml b/res/layout/people_activity_toolbar.xml
new file mode 100644
index 0000000..fe5be04
--- /dev/null
+++ b/res/layout/people_activity_toolbar.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Need to set a non null background on Toolbar in order for MenuItem ripples to be drawn on
+     this view, instead of another. This will *not* cause an additional draw since the
+     background is transparent.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/toolbar_parent"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:background="#00000000"
+    android:elevation="@dimen/tab_elevation"
+    android:layout_height="wrap_content" >
+
+    <Toolbar
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:background="@color/actionbar_background_color"
+        android:id="@+id/toolbar"
+        style="@style/ContactsToolbarStyle" />
+
+    <com.android.contacts.common.list.ViewPagerTabs
+        android:id="@+id/lists_pager_header"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:textAllCaps="true"
+        android:orientation="horizontal"
+        android:layout_gravity="top"
+        android:layout_weight="0"
+        android:layout_below="@id/toolbar"
+        style="@style/ContactsActionBarTabTextStyle" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values-w470dp/dimens.xml b/res/values-w470dp/dimens.xml
new file mode 100644
index 0000000..2c04e5d
--- /dev/null
+++ b/res/values-w470dp/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+
+    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
+         470dp is the height of a "normal" screen. We should leave 240dp for
+         the title and menu items -->
+    <dimen name="people_activity_landscape_tabs_width">230dip</dimen>
+    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
+         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
+         In portrait mode, the tabs look okay when overflowing their allocated space.
+         We have to be more careful in landscape. -->
+    <dimen name="people_activity_landscape_tabs_text_size">9dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/res/values-w590dp/dimens.xml b/res/values-w590dp/dimens.xml
new file mode 100644
index 0000000..2fff6ca
--- /dev/null
+++ b/res/values-w590dp/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+
+    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
+         590dp is almost the height of a "large" screen. We should leave 240dp for
+         the title and menu items -->
+    <dimen name="people_activity_landscape_tabs_width">350dip</dimen>
+    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
+         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
+         In portrait mode, the tabs look okay when overflowing their allocated space.
+         We have to be more careful in landscape. -->
+    <dimen name="people_activity_landscape_tabs_text_size">14dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 562241e..beedf6a 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -61,8 +61,4 @@
 
     <!-- Background color of pinned header items. -->
     <color name="list_item_pinned_header_color">#f5f5f5</color>
-
-    <color name="tab_default_color">@color/actionbar_background_color</color>
-    <color name="tab_pressed_color">@color/tab_selected_color</color>
-    <color name="tab_selected_color">#ffeeff41</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 40adc95..d86d9d7 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -188,6 +188,15 @@
     <dimen name="expanding_entry_card_item_alternate_icon_margin_bottom">10dp</dimen>
 
     <dimen name="people_activity_card_elevation">2dp</dimen>
+    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
+         426dp is the height of a "small" screen. We should leave 240dp for
+         the title and menu items -->
+    <dimen name="people_activity_landscape_tabs_width">186dip</dimen>
+    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
+         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
+         In portrait mode, the tabs look okay when overflowing their allocated space.
+         We have to be more careful in landscape. -->
+    <dimen name="people_activity_landscape_tabs_text_size">8dp</dimen>
 
     <dimen name="expanding_entry_card_item_icon_height">24dp</dimen>
     <dimen name="expanding_entry_card_item_icon_width">24dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a1a01d1..1eae4d0 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,8 +50,6 @@
 
     <style name="PeopleTheme" parent="@android:style/Theme.Material.Light">
         <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
-        <!-- Style for the tabs -->
-        <item name="android:actionBarTabStyle">@style/ContactsActionBarTabStyle</item>
         <!-- Style for the tab bar (for the divider between tabs) -->
         <item name="android:actionBarTabBarStyle">@style/ContactsActionBarTabBarStyle</item>
         <!-- Style for the tab bar text (for text on tabs) -->
@@ -111,17 +109,17 @@
         <item name="android:icon">@android:color/transparent</item>
     </style>
 
+    <!-- When this style was added, android:toolbarStyle was private. Therefore, this style
+         must be directly applied to every toolbar -->
+    <style name="ContactsToolbarStyle" parent="@android:style/Widget.Toolbar">
+        <item name="android:titleTextAppearance">@style/ContactsActionBarTitleText</item>
+    </style>
+
     <style name="ContactsPickerActionBarStyle" parent="@style/ContactsActionBarStyle">
         <!-- when first loading, don't show title or up button -->
         <item name="android:displayOptions"></item>
     </style>
 
-    <!-- Styling for tabs. -->
-    <style name="ContactsActionBarTabStyle" parent="@android:style/Widget.Material.Light.ActionBar.TabView">
-        <item name="android:background">@drawable/action_bar_tab</item>
-        <item name="android:showDividers">none</item>
-    </style>
-
     <!-- Text in the action bar at the top of the screen -->
     <style name="ContactsActionBarTitleText"
            parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title">
@@ -160,10 +158,6 @@
         <item name="android:dropDownListViewStyle">@style/ListViewDropdownStyle</item>
     </style>
 
-    <style name="ContactsActionBarTabView" parent="@android:style/Widget.Holo.ActionBar.TabView">
-        <item name="android:background">@drawable/action_bar_tab</item>
-    </style>
-
     <style name="ListViewDropdownStyle" parent="@android:style/Widget.ListView.DropDown">
         <item name="android:listSelector">?android:attr/listChoiceBackgroundIndicator</item>
     </style>
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index ea05b73..e27419a 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -16,22 +16,25 @@
 
 package com.android.contacts.activities;
 
+import android.animation.ValueAnimator;
 import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
 import android.view.View.OnClickListener;
 import android.widget.EditText;
+import android.widget.Toolbar;
 
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
@@ -70,16 +73,22 @@
     private String mQueryString;
 
     private EditText mSearchView;
+    /** The view that represents tabs when we are in portrait mode **/
+    private View mPortraitTabs;
+    /** The view that represents tabs when we are in landscape mode **/
+    private View mLandscapeTabs;
     private View mSearchContainer;
 
+    private int mMaxPortraitTabHeight;
+    private int mMaxToolbarContentInsetStart;
+
     private final Context mContext;
     private final SharedPreferences mPrefs;
 
     private Listener mListener;
 
     private final ActionBar mActionBar;
-    private final int mActionBarNavigationMode;
-    private final MyTabListener mTabListener;
+    private final Toolbar mToolbar;
 
     private boolean mShowHomeIcon;
 
@@ -93,29 +102,38 @@
 
     private int mCurrentTab = TabState.DEFAULT;
 
-    public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar) {
+    public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar,
+            View portraitTabs, View landscapeTabs, Toolbar toolbar) {
         mContext = context;
         mListener = listener;
         mActionBar = actionBar;
         mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-
+        mPortraitTabs = portraitTabs;
+        mLandscapeTabs = landscapeTabs;
+        mToolbar = toolbar;
+        mMaxToolbarContentInsetStart = mToolbar.getContentInsetStart();
         mShowHomeIcon = mContext.getResources().getBoolean(R.bool.show_home_icon);
 
-        mActionBarNavigationMode = ActionBar.NAVIGATION_MODE_TABS;
-        mTabListener = new MyTabListener();
-
         setupSearchView();
-        setupTabs();
+        setupTabs(context);
     }
 
-    private void setupTabs() {
-        addTab(TabState.FAVORITES, R.string.favorites_tab_label);
-        addTab(TabState.ALL, R.string.all_contacts_tab_label);
+    private void setupTabs(Context context) {
+        final TypedArray attributeArray = context.obtainStyledAttributes(
+                new int[]{android.R.attr.actionBarSize});
+        mMaxPortraitTabHeight = attributeArray.getDimensionPixelSize(0, 0);
+        // Hide tabs initially
+        setPortraitTabHeight(0);
     }
 
     private void setupSearchView() {
-        mActionBar.setCustomView(R.layout.search_bar_expanded);
-        mSearchContainer = mActionBar.getCustomView();
+        final LayoutInflater inflater = (LayoutInflater) mToolbar.getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        mSearchContainer = inflater.inflate(R.layout.search_bar_expanded, mToolbar,
+                /* attachToRoot = */ false);
+        mSearchContainer.setVisibility(View.VISIBLE);
+        mToolbar.addView(mSearchContainer);
+
         mSearchContainer.setBackgroundColor(mContext.getResources().getColor(
                 R.color.searchbox_background_color));
         mSearchView = (EditText) mSearchContainer.findViewById(R.id.search_view);
@@ -137,7 +155,6 @@
                 }
             }
         });
-        mActionBar.setCustomView(mSearchContainer);
     }
 
     public void initialize(Bundle savedState, ContactsRequest request) {
@@ -170,34 +187,6 @@
         mListener = listener;
     }
 
-    private void addTab(int expectedTabIndex, int description) {
-        final Tab tab = mActionBar.newTab();
-        tab.setTabListener(mTabListener);
-        tab.setText(description);
-        mActionBar.addTab(tab);
-        if (expectedTabIndex != tab.getPosition()) {
-            throw new IllegalStateException("Tabs must be created in the right order");
-        }
-    }
-
-    private class MyTabListener implements ActionBar.TabListener {
-        /**
-         * If true, it won't call {@link #setCurrentTab} in {@link #onTabSelected}.
-         * This flag is used when we want to programmatically update the current tab without
-         * {@link #onTabSelected} getting called.
-         */
-        public boolean mIgnoreTabSelected;
-
-        @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { }
-        @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { }
-
-        @Override public void onTabSelected(Tab tab, FragmentTransaction ft) {
-            if (!mIgnoreTabSelected) {
-                setCurrentTab(tab.getPosition());
-            }
-        }
-    }
-
     private class SearchTextWatcher implements TextWatcher {
 
         @Override
@@ -223,14 +212,14 @@
     }
 
     /**
-     * Change the current tab, and notify the listener.
+     * Save the current tab selection, and notify the listener.
      */
     public void setCurrentTab(int tab) {
         setCurrentTab(tab, true);
     }
 
     /**
-     * Change the current tab
+     * Save the current tab selection.
      */
     public void setCurrentTab(int tab, boolean notifyListener) {
         if (tab == mCurrentTab) {
@@ -238,11 +227,6 @@
         }
         mCurrentTab = tab;
 
-        final int actionBarSelectedNavIndex = mActionBar.getSelectedNavigationIndex();
-        if (mCurrentTab != actionBarSelectedNavIndex) {
-            mActionBar.setSelectedNavigationItem(mCurrentTab);
-        }
-
         if (notifyListener && mListener != null) mListener.onSelectedTabChanged();
         saveLastTabPreference(mCurrentTab);
     }
@@ -295,7 +279,7 @@
         return mSearchMode; // Only shown on the search mode.
     }
 
-    private void updateDisplayOptions() {
+    private void updateDisplayOptionsInner() {
         // All the flags we may change in this method.
         final int MASK = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME
                 | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM;
@@ -310,10 +294,14 @@
         }
         if (mSearchMode) {
             newFlags |= ActionBar.DISPLAY_SHOW_CUSTOM;
+            mToolbar.setContentInsetsRelative(0, mToolbar.getContentInsetEnd());
         } else {
             newFlags |= ActionBar.DISPLAY_SHOW_TITLE;
+            mToolbar.setContentInsetsRelative(mMaxToolbarContentInsetStart,
+                    mToolbar.getContentInsetEnd());
         }
 
+
         if (current != newFlags) {
             // Pass the mask here to preserve other flags that we're not interested here.
             mActionBar.setDisplayOptions(newFlags, MASK);
@@ -322,21 +310,26 @@
 
     private void update(boolean skipAnimation) {
         final boolean isIconifiedChanging
-                = (mSearchContainer.getVisibility() == View.VISIBLE) != mSearchMode;
+                = (mSearchContainer.getParent() == null) == mSearchMode;
+        mToolbar.removeView(mLandscapeTabs);
         if (isIconifiedChanging && !skipAnimation) {
             if (mSearchMode) {
-                mSearchContainer.setVisibility(View.VISIBLE);
+                mToolbar.removeView(mLandscapeTabs);
+                addSearchContainer();
                 mSearchContainer.setAlpha(0);
                 mSearchContainer.animate().alpha(1);
-                updateDisplayOptionsAndNavigationMode(isIconifiedChanging);
+                animateTabHeightChange(mMaxPortraitTabHeight, 0);
+                updateDisplayOptions(isIconifiedChanging);
             } else {
                 mSearchContainer.setAlpha(1);
+                animateTabHeightChange(0, mMaxPortraitTabHeight);
                 mSearchContainer.animate().alpha(0).withEndAction(new Runnable() {
                     @Override
                     public void run() {
-                        updateDisplayOptions();
-                        mSearchContainer.setVisibility(View.GONE);
-                        updateDisplayOptionsAndNavigationMode(isIconifiedChanging);
+                        updateDisplayOptionsInner();
+                        updateDisplayOptions(isIconifiedChanging);
+                        addLandscapeViewPagerTabs();
+                        mToolbar.removeView(mSearchContainer);
                     }
                 });
             }
@@ -344,15 +337,31 @@
         }
         if (isIconifiedChanging && skipAnimation) {
             if (mSearchMode) {
-                mSearchContainer.setVisibility(View.VISIBLE);
+                setPortraitTabHeight(0);
+                mToolbar.removeView(mLandscapeTabs);
+                addSearchContainer();
             } else {
-                mSearchContainer.setVisibility(View.GONE);
+                setPortraitTabHeight(mMaxPortraitTabHeight);
+                mToolbar.removeView(mSearchContainer);
+                addLandscapeViewPagerTabs();
             }
         }
-        updateDisplayOptionsAndNavigationMode(isIconifiedChanging);
+        updateDisplayOptions(isIconifiedChanging);
     }
 
-    private void updateDisplayOptionsAndNavigationMode(boolean isIconifiedChanging) {
+    private void addLandscapeViewPagerTabs() {
+        if (mLandscapeTabs != null) {
+            mToolbar.removeView(mLandscapeTabs);
+            mToolbar.addView(mLandscapeTabs);
+        }
+    }
+
+    private void addSearchContainer() {
+        mToolbar.removeView(mSearchContainer);
+        mToolbar.addView(mSearchContainer);
+    }
+
+    private void updateDisplayOptions(boolean isIconifiedChanging) {
         if (mSearchMode) {
             setFocusOnSearchView();
             // Since we have the {@link SearchView} in a custom action bar, we must manually handle
@@ -364,35 +373,16 @@
                     mSearchView.setText(queryText);
                 }
             }
-            if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_STANDARD) {
-                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-            }
             if (mListener != null) {
                 mListener.onAction(Action.START_SEARCH_MODE);
             }
         } else {
-            final int currentNavigationMode = mActionBar.getNavigationMode();
-            if (mActionBarNavigationMode == ActionBar.NAVIGATION_MODE_TABS
-                    && currentNavigationMode != ActionBar.NAVIGATION_MODE_TABS) {
-                // setNavigationMode will trigger onTabSelected() with the tab which was previously
-                // selected.
-                // The issue is that when we're first switching to the tab navigation mode after
-                // screen orientation changes, onTabSelected() will get called with the first tab
-                // (i.e. favorite), which would results in mCurrentTab getting set to FAVORITES and
-                // we'd lose restored tab.
-                // So let's just disable the callback here temporarily.  We'll notify the listener
-                // after this anyway.
-                mTabListener.mIgnoreTabSelected = true;
-                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-                mActionBar.setSelectedNavigationItem(mCurrentTab);
-                mTabListener.mIgnoreTabSelected = false;
-            }
             if (mListener != null) {
                 mListener.onAction(Action.STOP_SEARCH_MODE);
                 mListener.onSelectedTabChanged();
             }
         }
-        updateDisplayOptions();
+        updateDisplayOptionsInner();
     }
 
     @Override
@@ -444,4 +434,28 @@
             return TabState.DEFAULT;
         }
     }
+
+    private void animateTabHeightChange(int start, int end) {
+        if (mPortraitTabs == null) {
+            return;
+        }
+        final ValueAnimator animator = ValueAnimator.ofInt(start, end);
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                int value = (Integer) valueAnimator.getAnimatedValue();
+                setPortraitTabHeight(value);
+            }
+        });
+        animator.setDuration(100).start();
+    }
+
+    private void setPortraitTabHeight(int height) {
+        if (mPortraitTabs == null) {
+            return;
+        }
+        ViewGroup.LayoutParams layoutParams = mPortraitTabs.getLayoutParams();
+        layoutParams.height = height;
+        mPortraitTabs.setLayoutParams(layoutParams);
+    }
 }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 5759350..7c0b14b 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -19,7 +19,9 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
+import android.content.Context;
 import android.content.Intent;
+import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
@@ -43,7 +45,9 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.widget.ImageButton;
+import android.widget.Toolbar;
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
@@ -67,6 +71,7 @@
 import com.android.contacts.list.OnContactsUnavailableActionListener;
 import com.android.contacts.list.ProviderStatusWatcher;
 import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
+import com.android.contacts.common.list.ViewPagerTabs;
 import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.common.util.AccountFilterUtil;
 import com.android.contacts.common.util.ViewUtil;
@@ -123,7 +128,9 @@
 
     /** ViewPager for swipe */
     private ViewPager mTabPager;
+    private ViewPagerTabs mViewPagerTabs;
     private TabPagerAdapter mTabPagerAdapter;
+    private String[] mTabTitles;
     private final TabPagerListener mTabPagerListener = new TabPagerListener();
 
     private boolean mEnableDebugMenuOptions;
@@ -277,6 +284,10 @@
     }
 
     private void createViewsAndFragments(Bundle savedState) {
+        // Disable the ActionBar so that we can use a Toolbar. This needs to be called before
+        // setContentView().
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+
         setContentView(R.layout.people_activity);
 
         final FragmentManager fragmentManager = getFragmentManager();
@@ -284,11 +295,29 @@
         // Hide all tabs (the current tab will later be reshown once a tab is selected)
         final FragmentTransaction transaction = fragmentManager.beginTransaction();
 
+        mTabTitles = new String[TabState.COUNT];
+        mTabTitles[TabState.FAVORITES] = getString(R.string.favorites_tab_label);
+        mTabTitles[TabState.ALL] = getString(R.string.all_contacts_tab_label);
         mTabPager = getView(R.id.tab_pager);
         mTabPagerAdapter = new TabPagerAdapter();
         mTabPager.setAdapter(mTabPagerAdapter);
         mTabPager.setOnPageChangeListener(mTabPagerListener);
 
+        // Configure toolbar and toolbar tabs. If in landscape mode, we  configure tabs differntly.
+        final Toolbar toolbar = getView(R.id.toolbar);
+        setActionBar(toolbar);
+        final ViewPagerTabs portraitViewPagerTabs
+                = (ViewPagerTabs) findViewById(R.id.lists_pager_header);
+        ViewPagerTabs landscapeViewPagerTabs = null;
+        if (portraitViewPagerTabs ==  null) {
+            landscapeViewPagerTabs = (ViewPagerTabs) getLayoutInflater().inflate(
+                    R.layout.people_activity_tabs_lands, toolbar, /* attachToRoot = */ false);
+            mViewPagerTabs = landscapeViewPagerTabs;
+        } else {
+            mViewPagerTabs = portraitViewPagerTabs;
+        }
+        mViewPagerTabs.setViewPager(mTabPager);
+
         final String FAVORITE_TAG = "tab-pager-favorite";
         final String ALL_TAG = "tab-pager-all";
 
@@ -326,8 +355,8 @@
         // Setting Properties after fragment is created
         mFavoritesFragment.setDisplayType(DisplayType.STREQUENT);
 
-        // Configure action bar
-        mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar());
+        mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar(),
+                portraitViewPagerTabs, landscapeViewPagerTabs, toolbar);
         mActionBarAdapter.initialize(savedState, mRequest);
 
         // Configure action button
@@ -572,10 +601,16 @@
 
         @Override
         public void onPageScrollStateChanged(int state) {
+            if (!mTabPagerAdapter.isSearchMode()) {
+                mViewPagerTabs.onPageScrollStateChanged(state);
+            }
         }
 
         @Override
         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            if (!mTabPagerAdapter.isSearchMode()) {
+                mViewPagerTabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
+            }
         }
 
         @Override
@@ -583,6 +618,7 @@
             // Make sure not in the search mode, in which case position != TabState.ordinal().
             if (!mTabPagerAdapter.isSearchMode()) {
                 mActionBarAdapter.setCurrentTab(position, false);
+                mViewPagerTabs.onPageSelected(position);
                 showEmptyStateForTab(position);
                 invalidateOptionsMenu();
             }
@@ -726,6 +762,11 @@
         @Override
         public void restoreState(Parcelable state, ClassLoader loader) {
         }
+
+        @Override
+        public CharSequence getPageTitle(int position) {
+            return mTabTitles[position];
+        }
     }
 
     private void setQueryTextToFragment(String query) {