Add actionbar to Dialer

Initial changes to replace the fake actionbar affordances in Dialer
with an actual actionBar. This puts the dialer in an intermediate
hybrid state where we are now using the system actionbar for search,
but the searchview is not yet themed to look like our old search
bar, so this is definitely still WIP UI.

This CL retains the fake action bar at the bottom of the screen to
continue allowing quick access to call history while other changes
are underway, but replaces the searchview and the overflow menu
with framework provided actionbar functionality.

Other related changes:
* The searchview (in the top actionbar) is hidden when scrolling to
devote the entire screen area to the speeddial list
https://folio.googleplex.com/phone/L/0407/#/03.png
* Functionality provided by the fake overflow menu has been moved to
 the real actionbar overflow menu
* Various modifications to child fragments/listviews to take into
account the existence of an actionbar
* Cleaned up unneeded styles and related-dead code

Bug: 13933082

Change-Id: Ifd855bd67af7bf2d2a403ef9556ade54e8d57ee6
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 509960c..ab3d2e3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -68,7 +68,7 @@
              dialpad screen. -->
         <activity android:name=".DialtactsActivity"
             android:label="@string/launcherDialer"
-            android:theme="@style/DialtactsThemeHiddenActionBar"
+            android:theme="@style/DialtactsTheme"
             android:launchMode="singleTask"
             android:clearTaskOnLaunch="true"
             android:icon="@mipmap/ic_launcher_phone"
@@ -122,11 +122,16 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.TAB" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.SEARCH" />
+            </intent-filter>
+            <meta-data android:name="android.app.searchable"
+                android:resource="@xml/searchable"/>
         </activity>
 
         <activity android:name="com.android.dialer.calllog.CallLogActivity"
             android:label="@string/call_log_activity_title"
-            android:theme="@style/DialtactsThemeWithActionBarOverlay"
+            android:theme="@style/DialtactsThemeWithoutActionBarOverlay"
             android:screenOrientation="portrait"
             android:icon="@mipmap/ic_launcher_phone">
             <intent-filter>
@@ -139,7 +144,7 @@
 
         <activity android:name="com.android.dialer.list.AllContactsActivity"
             android:label="@string/show_all_contacts_title"
-            android:theme="@style/DialtactsThemeWithActionBarOverlay"
+            android:theme="@style/DialtactsTheme"
             android:screenOrientation="portrait">
         </activity>
 
diff --git a/res/layout/all_contacts_activity.xml b/res/layout/all_contacts_activity.xml
index a913027..50cba1e 100644
--- a/res/layout/all_contacts_activity.xml
+++ b/res/layout/all_contacts_activity.xml
@@ -17,7 +17,6 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_marginTop="?android:attr/actionBarSize"
     android:id="@+id/all_contacts_frame">
     <fragment android:name="com.android.dialer.list.AllContactsFragment"
               android:id="@+id/all_contacts_fragment"
diff --git a/res/layout/call_log_activity.xml b/res/layout/call_log_activity.xml
index f9806e8..5a50823 100644
--- a/res/layout/call_log_activity.xml
+++ b/res/layout/call_log_activity.xml
@@ -17,11 +17,9 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_marginTop="?android:attr/actionBarSize"
     android:id="@+id/calllog_frame">
     <android.support.v4.view.ViewPager
         android:id="@+id/call_log_pager"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginTop="?android:attr/actionBarSize" />
+        android:layout_height="match_parent"/>
 </FrameLayout>
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
index dfe5c7c..d285cc3 100644
--- a/res/layout/dialpad_fragment.xml
+++ b/res/layout/dialpad_fragment.xml
@@ -49,7 +49,7 @@
             android:layout_width="match_parent"
             android:layout_height="10dp" />
 
-        <include layout="@layout/dialpad_digits"/>
+        <include layout="@layout/dialpad_digits" />
 
         <Space
             android:layout_width="match_parent"
@@ -59,10 +59,6 @@
 
         <Space
             android:layout_width="match_parent"
-            android:layout_height="8dp" />
-
-        <Space
-            android:layout_width="match_parent"
             android:layout_height="2dp"
             android:background="@color/dialpad_separator_line_color" />
 
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
index 2860886..2513216 100644
--- a/res/layout/dialtacts_activity.xml
+++ b/res/layout/dialtacts_activity.xml
@@ -15,143 +15,109 @@
 -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/dialtacts_mainlayout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:focusable="true"
     android:orientation="vertical"
+    android:focusable="true"
     android:focusableInTouchMode="true"
     android:clipChildren="false"
     android:background="@color/background_dialer_light"
     >
-
-    <FrameLayout
+    <RelativeLayout
         android:id="@+id/dialtacts_container"
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:layout_weight="1">
-
-        <LinearLayout
-            android:layout_width="match_parent"
+        android:layout_weight="1"
+        android:clipChildren="false">
+        <!-- The main contacts grid -->
+        <FrameLayout
             android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            android:id="@+id/dialtacts_frame"
             android:clipChildren="false"
-            android:orientation="vertical" >
-
-            <!-- Search entry box and remove view -->
-            <FrameLayout
+            >
+        </FrameLayout>
+        <!-- Search entry box and remove view -->
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:id="@+id/search_and_remove_view_container"
+            android:visibility="gone"
+            >
+            <!--  TODO: This is set to visibility:gone for now, should be removed entirely -->
+            <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:id="@+id/search_and_remove_view_container"
+                android:layout_height="@dimen/search_box_height"
+                android:id="@+id/search_view_container"
+                android:orientation="horizontal"
+                android:layout_marginTop="@dimen/search_top_margin"
+                android:layout_marginBottom="@dimen/search_bottom_margin"
+                android:layout_marginLeft="@dimen/search_margin_horizontal"
+                android:layout_marginRight="@dimen/search_margin_horizontal"
+                android:paddingLeft="@dimen/search_box_left_padding"
+                android:paddingRight="@dimen/search_box_right_padding"
+                android:background="@drawable/search_bg"
+                android:gravity="center_vertical"
+                android:visibility="gone"
                 >
-                <LinearLayout
+                <EditText
+                    android:id="@+id/search_view"
                     android:layout_width="match_parent"
-                    android:layout_height="@dimen/search_box_height"
-                    android:id="@+id/search_view_container"
-                    android:orientation="horizontal"
-                    android:layout_marginTop="@dimen/search_top_margin"
-                    android:layout_marginBottom="@dimen/search_bottom_margin"
-                    android:layout_marginLeft="@dimen/search_margin_horizontal"
-                    android:layout_marginRight="@dimen/search_margin_horizontal"
-                    android:paddingLeft="@dimen/search_box_left_padding"
-                    android:paddingRight="@dimen/search_box_right_padding"
-                    android:background="@drawable/search_bg"
-                    android:gravity="center_vertical"
-                    >
-                    <EditText
-                        android:id="@+id/search_view"
-                        android:layout_width="match_parent"
-                        android:layout_height="@dimen/search_box_icon_size"
-                        android:layout_weight="1"
-                        android:layout_marginLeft="@dimen/search_box_text_left_margin"
-                        android:textSize="@dimen/search_text_size"
-                        android:fontFamily="@string/search_font_family"
-                        android:textColor="@color/searchbox_text_color"
-                        android:textColorHint="@color/searchbox_hint_text_color"
-                        android:inputType="textFilter"/>
-                    <ImageView
-                        android:id="@+id/search_close_button"
-                        android:layout_height="@dimen/search_box_icon_size"
-                        android:layout_width="@dimen/search_box_icon_size"
-                        android:padding="6dp"
-                        android:src="@drawable/ic_close_dk"
-                        android:clickable="true"
-                        android:background="?android:attr/selectableItemBackground"
-                        android:contentDescription="@string/description_clear_search"
-                        android:visibility="gone" />
-                    <ImageView
-                        android:id="@+id/voice_search_button"
-                        android:layout_height="@dimen/search_box_icon_size"
-                        android:layout_width="@dimen/search_box_icon_size"
-                        android:padding="@dimen/search_box_icon_padding"
-                        android:src="@drawable/ic_voice_search"
-                        android:clickable="true"
-                        android:contentDescription="@string/description_start_voice_search"
-                        android:background="?android:attr/selectableItemBackground" />
-                </LinearLayout>
-                <com.android.dialer.list.RemoveView
-                    android:layout_width="match_parent"
-                    android:layout_height="56dp"
-                    android:id="@+id/remove_view_container"
-                    android:orientation="horizontal"
-                    android:gravity="center"
-                    android:visibility="gone">
-                    <ImageView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:id="@+id/remove_view_icon"
-                        android:src="@drawable/ic_remove"
-                        android:contentDescription="@string/remove_contact"
-                        />
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:id="@+id/remove_view_text"
-                        android:textSize="@dimen/remove_text_size"
-                        android:textColor="@color/remove_text_color"
-                        android:text="@string/remove_contact"
-                        />
-                </com.android.dialer.list.RemoveView>
-            </FrameLayout>
-
-            <!-- Relative Layout is used to contain the main contacts grid and the thin translucent
-                 horizontal divider line at the bottom of the contacts grid above the menu bar. -->
-            <RelativeLayout android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
-                android:clipChildren="false"
-                >
-                <!-- The main contacts grid -->
-                <FrameLayout
-                    android:layout_height="match_parent"
-                    android:layout_width="match_parent"
-                    android:id="@+id/dialtacts_frame"
-                    android:clipChildren="false"
-                    android:layout_alignParentBottom="true"
-                    android:layout_alignParentTop="true"
-                    android:layout_alignParentLeft="true"
-                    android:layout_alignParentRight="true"
-                    >
-                </FrameLayout>
-                <!-- Thin translucent horizontal line at the bottom of the contacts grid. Floats
-                     above the contacts grid and has a translucent color. -->
-                <View
-                    android:layout_height="2dp"
-                    android:layout_width="match_parent"
-                    android:background="@color/contacts_grid_bottom_border_color"
-                    android:layout_alignParentBottom="true"
-                    android:layout_alignParentLeft="true"
-                    android:layout_alignParentRight="true"
+                    android:layout_height="@dimen/search_box_icon_size"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/search_box_text_left_margin"
+                    android:textSize="@dimen/search_text_size"
+                    android:fontFamily="@string/search_font_family"
+                    android:textColor="@color/searchbox_text_color"
+                    android:textColorHint="@color/searchbox_hint_text_color"
+                    android:inputType="textFilter"/>
+                <ImageView
+                    android:id="@+id/search_close_button"
+                    android:layout_height="@dimen/search_box_icon_size"
+                    android:layout_width="@dimen/search_box_icon_size"
+                    android:padding="6dp"
+                    android:src="@drawable/ic_close_dk"
+                    android:clickable="true"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:contentDescription="@string/description_clear_search"
+                    android:visibility="gone" />
+                <ImageView
+                    android:id="@+id/voice_search_button"
+                    android:layout_height="@dimen/search_box_icon_size"
+                    android:layout_width="@dimen/search_box_icon_size"
+                    android:padding="@dimen/search_box_icon_padding"
+                    android:src="@drawable/ic_voice_search"
+                    android:clickable="true"
+                    android:contentDescription="@string/description_start_voice_search"
+                    android:background="?android:attr/selectableItemBackground" />
+            </LinearLayout>
+            <com.android.dialer.list.RemoveView
+                android:layout_width="match_parent"
+                android:layout_height="56dp"
+                android:id="@+id/remove_view_container"
+                android:orientation="horizontal"
+                android:gravity="center">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/remove_view_icon"
+                    android:src="@drawable/ic_remove"
+                    android:contentDescription="@string/remove_contact"
                     />
-            </RelativeLayout>
-            <Space
-                android:id="@+id/contact_tile_frame_spacer"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:layout_alignParentBottom="true"
-                android:visibility="gone"/>
-        </LinearLayout>
-    </FrameLayout>
-
-    <!-- Fake action bar -->
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/remove_view_text"
+                    android:textSize="@dimen/remove_text_size"
+                    android:textColor="@color/remove_text_color"
+                    android:text="@string/remove_contact"
+                    />
+            </com.android.dialer.list.RemoveView>
+        </FrameLayout>
+    </RelativeLayout>
+    <!-- TODO: To be removed entirely and replaced with a floating action button -->
     <FrameLayout
         android:layout_height="@dimen/fake_action_bar_height"
         android:layout_width="match_parent"
@@ -175,18 +141,19 @@
             android:src="@drawable/ic_menu_dialpad_lt"/>
         <ImageButton
             android:id="@+id/dial_button"
-            android:layout_width="@dimen/fake_menu_button_min_width"
-            android:layout_height="match_parent"
+            android:layout_width="@dimen/fake_action_bar_height"
+            android:layout_height="@dimen/fake_action_bar_height"
             android:layout_gravity="bottom|center"
             android:background="@drawable/btn_call"
             android:contentDescription="@string/description_dial_button"
             android:src="@drawable/ic_dial_action_call"
             android:visibility="gone" />
         <ImageButton
-            android:id="@+id/overflow_menu"
+            android:id="@+id/overflow_menu_button"
             android:layout_width="@dimen/fake_menu_button_min_width"
             android:layout_height="match_parent"
             android:layout_gravity="bottom|end"
+            android:visibility="gone"
             android:src="@drawable/ic_menu_overflow_lt"
             android:contentDescription="@string/action_menu_overflow_description"
             android:background="?android:attr/selectableItemBackground"/>
diff --git a/res/layout/phone_favorites_fragment.xml b/res/layout/phone_favorites_fragment.xml
index 4992486..91acb90 100644
--- a/res/layout/phone_favorites_fragment.xml
+++ b/res/layout/phone_favorites_fragment.xml
@@ -35,7 +35,7 @@
             android:id="@+id/contact_tile_list"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:paddingTop="@dimen/contact_tile_list_padding_top"
+            android:paddingTop="?android:attr/actionBarSize"
             android:clipToPadding="false"
             android:fadingEdge="none"
             android:divider="@null" />
diff --git a/res/menu/dialtacts_options.xml b/res/menu/dialtacts_options.xml
index 7e84818..71d095a 100644
--- a/res/menu/dialtacts_options.xml
+++ b/res/menu/dialtacts_options.xml
@@ -15,6 +15,16 @@
 -->
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
+        android:id="@+id/menu_search"
+        android:title="@string/description_search_button"
+        android:showAsAction="always"
+        android:actionViewClass="android.widget.SearchView"/>
+    <item
+        android:id="@+id/menu_history"
+        android:icon="@drawable/ic_menu_history_lt"
+        android:title="@string/action_menu_call_history_description"
+        android:showAsAction="ifRoom"/>
+    <item
         android:id="@+id/menu_import_export"
         android:title="@string/menu_import_export" />
     <item
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 78c1cc7..71859f0 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -19,7 +19,8 @@
            parent="android:Theme.Quantum.Light">
         <item name="android:textColorPrimary">@color/dialtacts_primary_text_color</item>
         <item name="android:textColorSecondary">@color/dialtacts_secondary_text_color</item>
-        <item name="android:windowActionBarOverlay">false</item>
+        <item name="android:windowActionBarOverlay">true</item>
+        <item name="android:windowActionModeOverlay">true</item>
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
         <!-- Style for the tabs (for the tabs) -->
         <item name="android:actionBarTabStyle">@style/DialtactsActionBarTabStyle</item>
@@ -29,8 +30,6 @@
         <item name="android:actionBarTabTextStyle">@style/DialtactsActionBarTabTextStyle</item>
         <!-- Style for the overflow button in the actionbar. -->
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
-        <!-- The "Up" icon in the action bar. -->
-        <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <item name="android:windowContentOverlay">@null</item>
         <!--  Searchbox Style -->
         <item name="android:editTextStyle">@style/DialtactsSearchboxStyle</item>
@@ -77,23 +76,6 @@
         <item name="favorites_padding_bottom">?android:attr/actionBarSize</item>
     </style>
 
-    <!-- An extension of the main DialtactsTheme used when the the launcher activity is shown.
-         Ensures that there is no actionbar showing during the load of the dialer app. -->
-    <style name="DialtactsThemeHiddenActionBar" parent="DialtactsTheme">
-        <item name="android:actionBarStyle">@style/DialtactsHiddenActionBarStyle</item>
-    </style>
-
-    <!-- A "hidden" action bar style.  Used when loading the launcher activity so that the
-         default actionbar is effectively hidden. -->
-    <style name="DialtactsHiddenActionBarStyle" parent="DialtactsActionBarStyle">
-        <item name="android:background">@color/background_dialer_light</item>
-        <item name="android:titleTextStyle">@style/DialtactsHiddenActionBarTextStyle</item>
-    </style>
-
-    <style name="DialtactsHiddenActionBarTextStyle" parent="@android:style/TextAppearance">
-        <item name="android:textColor">@color/background_dialer_light</item>
-    </style>
-
     <!-- Action bar overflow menu icon. -->
     <style name="DialtactsActionBarOverflow"
            parent="@android:style/Widget.Quantum.Light.ActionButton.Overflow">
@@ -104,8 +86,8 @@
         <item name="android:textColorPrimary">#FFFFFF</item>
     </style>
 
-    <style name="DialtactsThemeWithActionBarOverlay" parent="DialtactsTheme">
-        <item name="android:windowActionBarOverlay">true</item>
+    <style name="DialtactsThemeWithoutActionBarOverlay" parent="DialtactsTheme">
+        <item name="android:windowActionBarOverlay">false</item>
     </style>
 
     <style name="CallDetailActivityTheme" parent="android:Theme.Quantum.Light">
@@ -114,7 +96,6 @@
         <item name="android:listViewStyle">@style/ListViewStyle</item>
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
-        <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <!-- CallLog -->
         <item name="call_log_primary_text_color">#333333</item>
         <item name="call_log_primary_background_color">#FFFFFF</item>
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
new file mode 100644
index 0000000..0e8242d
--- /dev/null
+++ b/res/xml/searchable.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.
+-->
+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
+    android:label="@string/applicationLabel"
+    android:hint="@string/dialer_hint_find_contact"
+    android:inputType="textNoSuggestions"
+    android:imeOptions="actionSearch"
+    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
+    />
\ No newline at end of file
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index afc1b44..c59db95 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -23,34 +23,39 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
+import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.graphics.Outline;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents;
 import android.speech.RecognizerIntent;
 import android.telephony.TelephonyManager;
-import android.text.Editable;
 import android.text.TextUtils;
-import android.text.TextWatcher;
 import android.util.Log;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.AbsListView.OnScrollListener;
-import android.widget.EditText;
 import android.widget.LinearLayout;
 import android.widget.PopupMenu;
+import android.widget.SearchView;
+import android.widget.SearchView.OnQueryTextListener;
 import android.widget.Toast;
 
 import com.android.contacts.common.CallUtil;
@@ -84,7 +89,7 @@
  * The dialer tab's title is 'phone', a more common name (see strings.xml).
  */
 public class DialtactsActivity extends TransactionSafeActivity implements View.OnClickListener,
-        DialpadFragment.OnDialpadQueryChangedListener, PopupMenu.OnMenuItemClickListener,
+        DialpadFragment.OnDialpadQueryChangedListener,
         OnListFragmentScrolledListener,
         DialpadFragment.HostInterface,
         PhoneFavoriteFragment.OnShowAllContactsListener,
@@ -121,7 +126,7 @@
 
     private static final int ACTIVITY_REQUEST_CODE_VOICE_SEARCH = 1;
 
-    private static final int ANIMATION_DURATION = 200;
+    private static final int ANIMATION_DURATION = 250;
 
     /**
      * The main fragment displaying the user's favorites and frequent contacts
@@ -143,17 +148,13 @@
      */
     private SmartDialSearchFragment mSmartDialSearchFragment;
 
-    private View mMenuButton;
     private View mFakeActionBar;
+    private View mMenuButton;
     private View mCallHistoryButton;
     private View mDialpadButton;
     private View mDialButton;
-    private PopupMenu mOverflowMenu;
     private PopupMenu mDialpadOverflowMenu;
 
-    // Padding view used to shift the fragment frame up when the dialpad is shown so that
-    // the contents of the fragment frame continue to exist in a layout of the same height
-    private View mFragmentsSpacer;
     private View mFragmentsFrame;
 
     private boolean mInDialpadSearch;
@@ -169,33 +170,24 @@
      * True when this activity has been launched for the first time.
      */
     private boolean mFirstLaunch;
-    private View mSearchViewContainer;
-    private RemoveView mRemoveViewContainer;
+
     // This view points to the Framelayout that houses both the search view and remove view
     // containers.
     private View mSearchAndRemoveViewContainer;
-    private View mSearchViewCloseButton;
-    private View mVoiceSearchButton;
-    private EditText mSearchView;
+    private SearchView mSearchView;
+    /**
+     * View that contains the "Remove" dialog that shows up when the user long presses a contact.
+     * If the user releases a contact when hovering on top of this, the contact is unfavorited and
+     * removed from the speed dial list.
+     */
+    private RemoveView mRemoveViewContainer;
 
+    final Interpolator hideActionBarInterpolator = new AccelerateInterpolator(1.5f);
+    final Interpolator showActionBarInterpolator = new DecelerateInterpolator(1.5f);
     private String mSearchQuery;
 
     private DialerDatabaseHelper mDialerDatabaseHelper;
 
-    private class OverflowPopupMenu extends PopupMenu {
-        public OverflowPopupMenu(Context context, View anchor) {
-            super(context, anchor);
-        }
-
-        @Override
-        public void show() {
-            final Menu menu = getMenu();
-            final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
-            clearFrequents.setVisible(mPhoneFavoriteFragment.hasFrequents());
-            super.show();
-        }
-    }
-
     /**
      * Listener used when one of phone numbers in search UI is selected. This will initiate a
      * phone call using the phone number.
@@ -232,32 +224,30 @@
     /**
      * Listener used to send search queries to the phone search fragment.
      */
-    private final TextWatcher mPhoneSearchQueryTextListener = new TextWatcher() {
+    private final OnQueryTextListener mPhoneSearchQueryTextListener = new OnQueryTextListener() {
             @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            public boolean onQueryTextSubmit(String query) {
+                return false;
             }
 
             @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-                final String newText = s.toString();
+            public boolean onQueryTextChange(String newText) {
                 if (newText.equals(mSearchQuery)) {
                     // If the query hasn't changed (perhaps due to activity being destroyed
                     // and restored, or user launching the same DIAL intent twice), then there is
                     // no need to do anything here.
-                    return;
+                    return true;
                 }
                 mSearchQuery = newText;
                 if (DEBUG) {
-                    Log.d(TAG, "onTextChange for mSearchView called with new query: " + s);
+                    Log.d(TAG, "onTextChange for mSearchView called with new query: " + newText);
                 }
                 final boolean dialpadSearch = isDialpadShowing();
 
                 // Show search result with non-empty text. Show a bare list otherwise.
                 if (TextUtils.isEmpty(newText) && getInSearchUi()) {
                     exitSearchUi();
-                    mSearchViewCloseButton.setVisibility(View.GONE);
-                    mVoiceSearchButton.setVisibility(View.VISIBLE);
-                    return;
+                    return true;
                 } else if (!TextUtils.isEmpty(newText)) {
                     final boolean sameSearchMode = (dialpadSearch && mInDialpadSearch) ||
                             (!dialpadSearch && mInRegularSearch);
@@ -272,14 +262,9 @@
                     } else if (mRegularSearchFragment != null) {
                         mRegularSearchFragment.setQueryString(newText, false);
                     }
-                    mSearchViewCloseButton.setVisibility(View.VISIBLE);
-                    mVoiceSearchButton.setVisibility(View.GONE);
-                    return;
+                    return true;
                 }
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
+                return true;
             }
     };
 
@@ -295,7 +280,8 @@
         setContentView(R.layout.dialtacts_activity);
         getWindow().setBackgroundDrawable(null);
 
-        getActionBar().hide();
+        getActionBar().setDisplayShowHomeEnabled(false);
+        getActionBar().setDisplayShowTitleEnabled(false);
 
         // Add the favorites fragment, and the dialpad fragment, but only if savedInstanceState
         // is null. Otherwise the fragment manager takes care of recreating these fragments.
@@ -312,28 +298,21 @@
         }
 
         mFragmentsFrame = findViewById(R.id.dialtacts_frame);
-        mFragmentsSpacer = findViewById(R.id.contact_tile_frame_spacer);
+
+        mFakeActionBar = findViewById(R.id.fake_action_bar);
+
+        mCallHistoryButton = findViewById(R.id.call_history_button);
+        mCallHistoryButton.setOnClickListener(this);
+        mDialButton = findViewById(R.id.dial_button);
+        mDialButton.setOnClickListener(this);
+        mDialpadButton = findViewById(R.id.dialpad_button);
+        mDialpadButton.setOnClickListener(this);
+        mMenuButton = findViewById(R.id.overflow_menu_button);
+        mMenuButton.setOnClickListener(this);
 
         mRemoveViewContainer = (RemoveView) findViewById(R.id.remove_view_container);
         mSearchAndRemoveViewContainer = findViewById(R.id.search_and_remove_view_container);
 
-        // When the first global layout pass is completed (and mSearchAndRemoveViewContainer has
-        // been assigned a valid height), assign that height to mFragmentsSpacer as well.
-        mSearchAndRemoveViewContainer.getViewTreeObserver().addOnGlobalLayoutListener(
-                new OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mSearchAndRemoveViewContainer.getViewTreeObserver()
-                                .removeOnGlobalLayoutListener(this);
-                        mFragmentsSpacer.setLayoutParams(
-                                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
-                                        mSearchAndRemoveViewContainer.getHeight()));
-                    }
-                });
-
-        setupFakeActionBarItems();
-        prepareSearchView();
-
         mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this);
         SmartDialPrefix.initializeNanpSettings(this);
     }
@@ -347,7 +326,6 @@
             hideDialpadFragment(false, true);
             mInCallDialpadUp = false;
         }
-        prepareVoiceSearchButton();
         mFirstLaunch = false;
         mDialerDatabaseHelper.startSmartDialUpdateThread();
     }
@@ -394,43 +372,12 @@
         } else if (fragment instanceof PhoneFavoriteFragment) {
             mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment;
             mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener);
+            if (mFragmentsFrame != null) {
+                mFragmentsFrame.setAlpha(1.0f);
+            }
         }
     }
 
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.menu_import_export:
-                // We hard-code the "contactsAreAvailable" argument because doing it properly would
-                // involve querying a {@link ProviderStatusLoader}, which we don't want to do right
-                // now in Dialtacts for (potential) performance reasons. Compare with how it is
-                // done in {@link PeopleActivity}.
-                ImportExportDialogFragment.show(getFragmentManager(), true,
-                        DialtactsActivity.class);
-                return true;
-            case R.id.menu_clear_frequents:
-                ClearFrequentsDialog.show(getFragmentManager());
-                return true;
-            case R.id.menu_add_contact:
-                try {
-                    startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-                } catch (ActivityNotFoundException e) {
-                    Toast toast = Toast.makeText(this,
-                            R.string.add_contact_not_available,
-                            Toast.LENGTH_SHORT);
-                    toast.show();
-                }
-                return true;
-            case R.id.menu_call_settings:
-                handleMenuSettings();
-                return true;
-            case R.id.menu_all_contacts:
-                onShowAllContacts();
-                return true;
-        }
-        return false;
-    }
-
     protected void handleMenuSettings() {
         openTelephonySetting(this);
     }
@@ -443,14 +390,9 @@
     @Override
     public void onClick(View view) {
         switch (view.getId()) {
-            case R.id.overflow_menu: {
-                if (isDialpadShowing()) {
-                    mDialpadOverflowMenu.show();
-                } else {
-                    mOverflowMenu.show();
-                }
+            case R.id.overflow_menu_button:
+                mDialpadOverflowMenu.show();
                 break;
-            }
             case R.id.dialpad_button:
                 // Reset the boolean flag that tracks whether the dialpad was up because
                 // we were in call. Regardless of whether it was true before, we want to
@@ -459,21 +401,21 @@
                 mInCallDialpadUp = false;
                 showDialpadFragment(true);
                 break;
-            case R.id.dial_button:
-                // Dial button was pressed; tell the Dialpad fragment
-                mDialpadFragment.dialButtonPressed();
-                break;
             case R.id.call_history_button:
                 // Use explicit CallLogActivity intent instead of ACTION_VIEW +
                 // CONTENT_TYPE, so that we always open our call log from our dialer
                 final Intent intent = new Intent(this, CallLogActivity.class);
                 startActivity(intent);
                 break;
+            case R.id.dial_button:
+                // Dial button was pressed; tell the Dialpad fragment
+                mDialpadFragment.dialButtonPressed();
+                break;
             case R.id.search_close_button:
                 // Clear the search field
-                if (!TextUtils.isEmpty(mSearchView.getText())) {
+                if (!TextUtils.isEmpty(mSearchView.getQuery())) {
                     mDialpadFragment.clearDialpad();
-                    mSearchView.setText("");
+                    mSearchView.setQuery("", false);
                 }
                 break;
             case R.id.voice_search_button:
@@ -493,6 +435,48 @@
     }
 
     @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_history:
+                // Use explicit CallLogActivity intent instead of ACTION_VIEW +
+                // CONTENT_TYPE, so that we always open our call log from our dialer
+                final Intent intent = new Intent(this, CallLogActivity.class);
+                startActivity(intent);
+                break;
+            case R.id.menu_add_contact:
+                try {
+                    startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
+                } catch (ActivityNotFoundException e) {
+                    Toast toast = Toast.makeText(this,
+                            R.string.add_contact_not_available,
+                            Toast.LENGTH_SHORT);
+                    toast.show();
+                }
+                break;
+            case R.id.menu_import_export:
+                // We hard-code the "contactsAreAvailable" argument because doing it properly would
+                // involve querying a {@link ProviderStatusLoader}, which we don't want to do right
+                // now in Dialtacts for (potential) performance reasons. Compare with how it is
+                // done in {@link PeopleActivity}.
+                ImportExportDialogFragment.show(getFragmentManager(), true,
+                        DialtactsActivity.class);
+                return true;
+            case R.id.menu_clear_frequents:
+                // TODO: This should be enabled/disabled based on
+                // PhoneFavoritesFragments.hasFrequents
+                ClearFrequentsDialog.show(getFragmentManager());
+                return true;
+            case R.id.menu_call_settings:
+                handleMenuSettings();
+                return true;
+            case R.id.menu_all_contacts:
+                onShowAllContacts();
+                return true;
+        }
+        return false;
+    }
+
+    @Override
     public boolean onLongClick(View view) {
         switch (view.getId()) {
             case R.id.dial_button: {
@@ -516,7 +500,7 @@
                         RecognizerIntent.EXTRA_RESULTS);
                 if (matches.size() > 0) {
                     final String match = matches.get(0);
-                    mSearchView.setText(match);
+                    mSearchView.setQuery(match, false);
                 } else {
                     Log.e(TAG, "Voice search - nothing heard");
                 }
@@ -537,14 +521,6 @@
         }
         ft.show(mDialpadFragment);
         ft.commit();
-        mDialButton.setVisibility(shouldShowOnscreenDialButton() ? View.VISIBLE : View.GONE);
-        mDialpadButton.setVisibility(View.GONE);
-
-        if (mDialpadOverflowMenu == null) {
-            mDialpadOverflowMenu = mDialpadFragment.buildOptionsMenu(mMenuButton);
-        }
-
-        mMenuButton.setOnTouchListener(mDialpadOverflowMenu.getDragToOpenListener());
     }
 
     public void hideDialpadFragment(boolean animate, boolean clearDialpad) {
@@ -560,32 +536,6 @@
         }
         ft.hide(mDialpadFragment);
         ft.commit();
-        mDialButton.setVisibility(View.GONE);
-        mDialpadButton.setVisibility(View.VISIBLE);
-        mMenuButton.setOnTouchListener(mOverflowMenu.getDragToOpenListener());
-    }
-
-    private void prepareSearchView() {
-        mSearchViewContainer = findViewById(R.id.search_view_container);
-        mSearchViewCloseButton = findViewById(R.id.search_close_button);
-        mSearchViewCloseButton.setOnClickListener(this);
-
-        mSearchView = (EditText) findViewById(R.id.search_view);
-        mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener);
-        mSearchView.setHint(getString(R.string.dialer_hint_find_contact));
-
-        prepareVoiceSearchButton();
-    }
-
-    private void prepareVoiceSearchButton() {
-        mVoiceSearchButton = findViewById(R.id.voice_search_button);
-        final Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
-        if (canIntentBeHandled(voiceIntent)) {
-            mVoiceSearchButton.setVisibility(View.VISIBLE);
-            mVoiceSearchButton.setOnClickListener(this);
-        } else {
-            mVoiceSearchButton.setVisibility(View.GONE);
-        }
     }
 
     final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
@@ -605,94 +555,79 @@
     }
 
     private void hideDialpadAndSearchUi() {
-        mSearchView.setText(null);
+        mSearchView.setQuery("", false);
         hideDialpadFragment(false, true);
     }
 
-    public void hideSearchBar() {
-        final int height = mSearchAndRemoveViewContainer.getHeight();
+    /**
+     * Callback from child DialpadFragment when the dialpad is shown.
+     */
+    public void onDialpadShown() {
+        mDialButton.setVisibility(View.VISIBLE);
+        mDialpadButton.setVisibility(View.GONE);
+        mMenuButton.setVisibility(View.VISIBLE);
+        if (mDialpadOverflowMenu == null) {
+            mDialpadOverflowMenu = mDialpadFragment.buildOptionsMenu(mMenuButton);
+            mMenuButton.setOnTouchListener(mDialpadOverflowMenu.getDragToOpenListener());
+        }
 
-        mSearchAndRemoveViewContainer.animate().cancel();
-        mSearchAndRemoveViewContainer.setAlpha(1);
-        mSearchAndRemoveViewContainer.setTranslationY(0);
-        mSearchAndRemoveViewContainer.animate().withLayer().alpha(0)
-                .translationY(-height).setDuration(ANIMATION_DURATION)
-                .setListener(mHideListener);
+        SearchFragment fragment = null;
+        if (mInDialpadSearch) {
+            fragment = mSmartDialSearchFragment;
+        } else if (mInRegularSearch) {
+            fragment = mRegularSearchFragment;
+        }
+        if (fragment != null && fragment.isVisible()) {
+            fragment.getListView().animate().translationY(-getActionBar().getHeight())
+                    .setInterpolator(hideActionBarInterpolator).setDuration(ANIMATION_DURATION);
+        }
 
-        mFragmentsFrame.animate().withLayer()
-                .translationY(-height).setDuration(ANIMATION_DURATION).setListener(
-                new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        mFragmentsFrame.setTranslationY(0);
-                        // Display the fragments spacer (which has the same height as the
-                        // search box) now that the search box is hidden, so that
-                        // mFragmentsFrame always retains the same height
-                        mFragmentsSpacer.setVisibility(View.VISIBLE);
-                    }
-                });
-
-        if (!mInDialpadSearch && !mInRegularSearch) {
+        if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isVisible()) {
             // If the favorites fragment is showing, fade to blank.
             mFragmentsFrame.animate().alpha(0.0f);
         }
+        getActionBar().hide();
     }
 
-    public void showSearchBar() {
-        final int height = mSearchAndRemoveViewContainer.getHeight();
-        mSearchAndRemoveViewContainer.animate().cancel();
-        mSearchAndRemoveViewContainer.setAlpha(0);
-        mSearchAndRemoveViewContainer.setTranslationY(-height);
-        mSearchAndRemoveViewContainer.animate().withLayer().alpha(1).translationY(0)
-                .setDuration(ANIMATION_DURATION).setListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationStart(Animator animation) {
-                            mSearchAndRemoveViewContainer.setVisibility(View.VISIBLE);
-                        }
-                    });
+    /**
+     * Callback from child DialpadFragment when the dialpad is hidden.
+     */
+    public void onDialpadHidden() {
+        mDialButton.setVisibility(View.GONE);
+        mDialpadButton.setVisibility(View.VISIBLE);
+        mMenuButton.setVisibility(View.GONE);
 
-        mFragmentsFrame.setTranslationY(-height);
-        mFragmentsFrame.animate().withLayer().translationY(0).setDuration(ANIMATION_DURATION)
-                .alpha(1.0f)
-                .setListener(
-                        new AnimatorListenerAdapter() {
-                            @Override
-                            public void onAnimationStart(Animator animation) {
-                                // Hide the fragment spacer now that the search box will
-                                // be displayed again
-                                mFragmentsSpacer.setVisibility(View.GONE);
-                            }
-                        });
-    }
-
-    private void setupFakeActionBarItems() {
-        mMenuButton = findViewById(R.id.overflow_menu);
-        if (mMenuButton != null) {
-            mMenuButton.setOnClickListener(this);
-            if (mOverflowMenu == null) {
-                mOverflowMenu = buildOptionsMenu(mMenuButton);
-            }
-            mMenuButton.setOnTouchListener(mOverflowMenu.getDragToOpenListener());
+        SearchFragment fragment = null;
+        if (mInDialpadSearch) {
+            fragment = mSmartDialSearchFragment;
+        } else if (mInRegularSearch) {
+            fragment = mRegularSearchFragment;
+        }
+        if (fragment != null && fragment.isVisible()) {
+            fragment.getListView().animate().translationY(0)
+                    .setInterpolator(showActionBarInterpolator).setDuration(ANIMATION_DURATION);
         }
 
-        mFakeActionBar = findViewById(R.id.fake_action_bar);
-
-        mCallHistoryButton = findViewById(R.id.call_history_button);
-        mCallHistoryButton.setOnClickListener(this);
-
-        mDialButton = findViewById(R.id.dial_button);
-        mDialButton.setOnClickListener(this);
-        mDialButton.setOnLongClickListener(this);
-
-        mDialpadButton = findViewById(R.id.dialpad_button);
-        mDialpadButton.setOnClickListener(this);
+        if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isVisible()) {
+            mFragmentsFrame.animate().alpha(1.0f);
+        }
+        getActionBar().show();
     }
 
-    private PopupMenu buildOptionsMenu(View invoker) {
-        PopupMenu menu = new OverflowPopupMenu(this, invoker);
-        menu.inflate(R.menu.dialtacts_options);
-        menu.setOnMenuItemClickListener(this);
-        return menu;
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        if (DEBUG) {
+            Log.d(TAG, "onCreateOptionsMenu");
+        }
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.dialtacts_options, menu);
+        final MenuItem searchItem = menu.findItem(R.id.menu_search);
+        mSearchView = (SearchView) searchItem.getActionView();
+        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
+        mSearchView.setOnQueryTextListener(mPhoneSearchQueryTextListener);
+        mSearchView.setIconifiedByDefault(false);
+        return super.onCreateOptionsMenu(menu);
     }
 
     /**
@@ -842,6 +777,8 @@
                 fragment = new RegularSearchFragment();
             }
         }
+        // DialtactsActivity will provide the options menu
+        fragment.setHasOptionsMenu(false);
         transaction.replace(R.id.dialtacts_frame, fragment, tag);
         transaction.addToBackStack(null);
         fragment.setQueryString(query, false);
@@ -879,7 +816,7 @@
         if (mDialpadFragment != null && mDialpadFragment.isVisible()) {
             hideDialpadFragment(true, false);
         } else if (getInSearchUi()) {
-            mSearchView.setText(null);
+            mSearchView.setQuery(null, false);
             mDialpadFragment.clearDialpad();
         } else {
             super.onBackPressed();
@@ -893,7 +830,7 @@
         }
         final String normalizedQuery = SmartDialNameMatcher.normalizeNumber(query,
                 SmartDialNameMatcher.LATIN_SMART_DIAL_MAP);
-        if (!TextUtils.equals(mSearchView.getText(), normalizedQuery)) {
+        if (!TextUtils.equals(mSearchView.getQuery(), normalizedQuery)) {
             if (DEBUG) {
                 Log.d(TAG, "onDialpadQueryChanged - new query: " + query);
             }
@@ -905,8 +842,10 @@
                 // fragment manager correctly figure out whatever fragment was last displayed.
                 return;
             }
-            mDialpadOverflowMenu = mDialpadFragment.buildOptionsMenu(mMenuButton);
-            mSearchView.setText(normalizedQuery);
+            if (mDialpadFragment != null) {
+                mDialpadOverflowMenu = mDialpadFragment.buildOptionsMenu(mMenuButton);
+            }
+            mSearchView.setQuery(normalizedQuery, false);
         }
     }
 
@@ -919,6 +858,22 @@
     }
 
     @Override
+    public void onListFragmentScroll(int firstVisibleItem, int visibleItemCount,
+            int totalItemCount) {
+
+        // Hide the action bar when scrolling down in the speed dial list, and show it again when
+        // scrolling back up.
+        if (firstVisibleItem > mPreviousFirstVisibleItem) {
+            getActionBar().hide();
+        } else if (firstVisibleItem < mPreviousFirstVisibleItem) {
+            getActionBar().show();
+        }
+        mPreviousFirstVisibleItem = firstVisibleItem;
+    }
+
+    private int mPreviousFirstVisibleItem = 0;
+
+    @Override
     public void setDialButtonEnabled(boolean enabled) {
         if (mDialButton != null) {
             mDialButton.setEnabled(enabled);
@@ -956,17 +911,25 @@
         return resolveInfo != null && resolveInfo.size() > 0;
     }
 
+    /**
+     * Called when the user has long-pressed a contact tile to start a drag operation.
+     */
     @Override
     public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view) {
-        crossfadeViews(mRemoveViewContainer, mSearchViewContainer, ANIMATION_DURATION);
+        getActionBar().hide();
+        mSearchAndRemoveViewContainer.setVisibility(View.VISIBLE);
     }
 
     @Override
     public void onDragHovered(int itemIndex, int x, int y) {}
 
+    /**
+     * Called when the user has released a contact tile after long-pressing it.
+     */
     @Override
     public void onDragFinished(int x, int y) {
-        crossfadeViews(mSearchViewContainer, mRemoveViewContainer, ANIMATION_DURATION);
+        getActionBar().show();
+        mSearchAndRemoveViewContainer.setVisibility(View.GONE);
     }
 
     @Override
@@ -980,27 +943,4 @@
     public void setDragDropController(DragDropController dragController) {
         mRemoveViewContainer.setDragDropController(dragController);
     }
-
-    /**
-     * Crossfades two views so that the first one appears while the other one is fading
-     * out of view.
-     */
-    private void crossfadeViews(final View fadeIn, final View fadeOut, int duration) {
-        fadeOut.animate().alpha(0).setDuration(duration)
-        .setListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                fadeOut.setVisibility(View.GONE);
-            }
-        });
-
-        fadeIn.setVisibility(View.VISIBLE);
-        fadeIn.setAlpha(0);
-        fadeIn.animate().alpha(1).setDuration(ANIMATION_DURATION)
-                .setListener(null);
-    }
-
-    private boolean shouldShowOnscreenDialButton() {
-        return getResources().getBoolean(R.bool.config_show_onscreen_dial_button);
-    }
 }
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index defd658..703c277 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -1671,9 +1671,9 @@
         final DialtactsActivity activity = (DialtactsActivity) getActivity();
         if (activity == null) return;
         if (hidden) {
-            activity.showSearchBar();
+            activity.onDialpadHidden();
         } else {
-            activity.hideSearchBar();
+            activity.onDialpadShown();
             mDigits.requestFocus();
         }
     }
diff --git a/src/com/android/dialer/list/OnListFragmentScrolledListener.java b/src/com/android/dialer/list/OnListFragmentScrolledListener.java
index cc5f3cd..5ed3a64 100644
--- a/src/com/android/dialer/list/OnListFragmentScrolledListener.java
+++ b/src/com/android/dialer/list/OnListFragmentScrolledListener.java
@@ -21,4 +21,6 @@
  */
 public interface OnListFragmentScrolledListener {
     public void onListFragmentScrollStateChange(int scrollState);
+    public void onListFragmentScroll(int firstVisibleItem, int visibleItemCount,
+            int totalItemCount);
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index 9af0cb2..a56c3c5 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -177,6 +177,10 @@
         @Override
         public void onScroll(AbsListView view,
                 int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+            if (mActivityScrollListener != null) {
+                mActivityScrollListener.onListFragmentScroll(firstVisibleItem, visibleItemCount,
+                    totalItemCount);
+            }
         }
 
         @Override
@@ -255,7 +259,6 @@
         final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
         mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this,
                 new ContactInfoHelper(getActivity(), currentCountryIso), false, false);
-        setHasOptionsMenu(true);
     }
 
     @Override
diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java
index 209cdf8..19553fb 100644
--- a/src/com/android/dialer/list/SearchFragment.java
+++ b/src/com/android/dialer/list/SearchFragment.java
@@ -20,6 +20,7 @@
 import android.text.TextUtils;
 import android.widget.AbsListView;
 import android.widget.AbsListView.OnScrollListener;
+import android.widget.ListView;
 
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactListItemView;
@@ -63,7 +64,16 @@
         if (isSearchMode()) {
             getAdapter().setHasHeader(0, false);
         }
-        getListView().setOnScrollListener(new OnScrollListener() {
+
+        final ListView listView = getListView();
+        listView.setPaddingRelative(
+                listView.getPaddingStart(),
+                getActivity().getActionBar().getHeight(),
+                listView.getPaddingEnd(),
+                listView.getPaddingBottom());
+        listView.setClipToPadding(false);
+
+        listView.setOnScrollListener(new OnScrollListener() {
             @Override
             public void onScrollStateChanged(AbsListView view, int scrollState) {
                 mActivityScrollListener.onListFragmentScrollStateChange(scrollState);
@@ -74,6 +84,10 @@
                     int totalItemCount) {
             }
         });
+
+        if (!getActivity().getActionBar().isShowing()) {
+            listView.setTranslationY(-getActivity().getActionBar().getHeight());
+        }
     }
 
     @Override