Merge "Add send message option to dialpad"
diff --git a/res/drawable-hdpi/ic_menu_overflow_dk.png b/res/drawable-hdpi/ic_menu_overflow_dk.png
deleted file mode 100644
index e9b0523..0000000
--- a/res/drawable-hdpi/ic_menu_overflow_dk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_overflow_lt.png b/res/drawable-hdpi/ic_menu_overflow_lt.png
deleted file mode 100644
index 57db353..0000000
--- a/res/drawable-hdpi/ic_menu_overflow_lt.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_overflow_dk.png b/res/drawable-mdpi/ic_menu_overflow_dk.png
deleted file mode 100644
index 67f281d..0000000
--- a/res/drawable-mdpi/ic_menu_overflow_dk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_overflow_lt.png b/res/drawable-mdpi/ic_menu_overflow_lt.png
deleted file mode 100644
index c699374..0000000
--- a/res/drawable-mdpi/ic_menu_overflow_lt.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_overflow_dk.png b/res/drawable-xhdpi/ic_menu_overflow_dk.png
deleted file mode 100644
index ec50c22..0000000
--- a/res/drawable-xhdpi/ic_menu_overflow_dk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_overflow_lt.png b/res/drawable-xhdpi/ic_menu_overflow_lt.png
deleted file mode 100644
index e538b98..0000000
--- a/res/drawable-xhdpi/ic_menu_overflow_lt.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_overflow_dk.png b/res/drawable-xxhdpi/ic_menu_overflow_dk.png
deleted file mode 100644
index 004f26b..0000000
--- a/res/drawable-xxhdpi/ic_menu_overflow_dk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_overflow_lt.png b/res/drawable-xxhdpi/ic_menu_overflow_lt.png
deleted file mode 100644
index 7f3f733..0000000
--- a/res/drawable-xxhdpi/ic_menu_overflow_lt.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/action_bar_tab.xml b/res/drawable/action_bar_tab.xml
deleted file mode 100644
index 8a3ea7a..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.
--->
-<touch-feedback  xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="@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>
-</touch-feedback>
\ No newline at end of file
diff --git a/res/drawable/background_all_contacts.xml b/res/drawable/background_all_contacts.xml
deleted file mode 100644
index c14886a..0000000
--- a/res/drawable/background_all_contacts.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="false">
-        <shape android:shape="rectangle" >
-            <solid android:color="@color/all_contacts_button_color" />
-        </shape>
-    </item>
-
-    <item android:state_pressed="true">
-        <shape android:shape="rectangle" >
-            <solid android:color="@color/all_contacts_button_pressed_color" />
-        </shape>
-    </item>
-</selector>
\ No newline at end of file
diff --git a/res/drawable/ic_voicemail_delete.xml b/res/drawable/ic_voicemail_delete.xml
new file mode 100644
index 0000000..e81da9a
--- /dev/null
+++ b/res/drawable/ic_voicemail_delete.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_delete_dk"
+    android:gravity="center"
+    android:tint="@color/actionbar_icon_color" />
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 5cddbe7..7b6aa28 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -68,6 +68,7 @@
             android:layout_height="match_parent"
             android:fadingEdge="none"
             android:scrollbarStyle="outsideOverlay"
+            android:background="@color/background_dialer_list_items"
             android:divider="@null"
             android:nestedScrollingEnabled="true"
             android:clipChildren="false"
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index ff6b7ba..9182bd7 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -19,6 +19,7 @@
     class="com.android.dialer.calllog.CallLogListItemView"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:paddingBottom="@dimen/call_log_outer_margin"
     android:id="@+id/call_log_list_item"
     android:orientation="vertical"
     android:clipChildren="false"
@@ -40,6 +41,7 @@
          information and the secondary action (call details / play voicemail). -->
     <LinearLayout
         android:id="@+id/call_log_row"
+        android:background="@color/background_dialer_list_items"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:baselineAligned="false"
@@ -53,7 +55,9 @@
             android:background="@drawable/call_log_background"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:padding="@dimen/call_log_outer_margin"
+            android:paddingLeft="@dimen/call_log_outer_margin"
+            android:paddingRight="@dimen/call_log_outer_margin"
+            android:paddingTop="@dimen/call_log_outer_margin"
             android:orientation="horizontal"
             android:gravity="center_vertical"
             android:focusable="true"
@@ -136,5 +140,4 @@
               android:layout="@layout/call_log_list_item_extra"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
-
 </view>
diff --git a/res/layout/phone_favorites_menu.xml b/res/layout/phone_favorites_menu.xml
deleted file mode 100644
index 0f7aa21..0000000
--- a/res/layout/phone_favorites_menu.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?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
-  -->
-
-<!-- The phone favorites menu appears on the main dialer screen above the favorite callers area,
-     and provides access to the All Contacts list. This is 1dp tall as a temporary hack to hide
-     it because it is no longer being used. It should be removed from its parent adapter entirely
-     eventually. -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@+id/phone_favorites_menu"
-                android:layout_width="match_parent"
-                android:layout_height="1dp"
-                android:paddingLeft="@dimen/favorites_menu_padding_horizontal"
-                android:paddingRight="@dimen/favorites_menu_padding_horizontal"
-                android:paddingTop="@dimen/favorites_menu_padding_top"
-                android:paddingBottom="@dimen/favorites_menu_padding_bottom"
-                android:background="@color/favorites_menu_background_color"
-        >
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/favorites_menu_speed_dial_height"
-            android:fontFamily="@string/favorites_menu_speed_dial_font_family"
-            android:text="@string/favorites_menu_speed_dial"
-            android:textSize="@dimen/favorites_menu_speed_dial_text_size"
-            android:textColor="@color/speed_dial_text_color"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:gravity="center"
-        />
-    <Button
-            android:id="@+id/all_contacts_button"
-            android:fontFamily="@string/favorites_menu_all_contacts_font_family"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/favorites_menu_all_contacts_height"
-            android:paddingLeft="@dimen/favorites_menu_padding_horizontal"
-            android:paddingRight="@dimen/favorites_menu_padding_horizontal"
-            android:text="@string/favorites_menu_all_contacts"
-            android:textSize="@dimen/favorites_menu_all_contacts_text_size"
-            android:background="@drawable/background_all_contacts"
-            android:textColor="@color/all_contacts_button_text_color"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:gravity="center"
-        />
-</RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/search_edittext.xml b/res/layout/search_edittext.xml
index 236d2bf..d18754a 100644
--- a/res/layout/search_edittext.xml
+++ b/res/layout/search_edittext.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
+<view class="com.android.dialer.widget.SearchEditTextLayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -14,6 +14,13 @@
     android:background="@drawable/search_bg"
     android:gravity="center_vertical"
     >
+    <ImageView
+        android:id="@+id/search_magnifying_glass"
+        android:layout_height="@dimen/search_box_icon_size"
+        android:layout_width="@dimen/search_box_icon_size"
+        android:layout_margin="@dimen/search_box_icon_margin"
+        android:padding="@dimen/search_box_search_icon_padding"
+        android:src="@drawable/ic_ab_search" />
     <EditText
         android:id="@+id/search_view"
         android:layout_width="0dp"
@@ -30,7 +37,7 @@
         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:layout_margin="@dimen/search_box_icon_margin"
         android:src="@drawable/ic_close_dk"
         android:clickable="true"
         android:background="?android:attr/selectableItemBackground"
@@ -40,9 +47,17 @@
         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:layout_margin="@dimen/search_box_icon_margin"
         android:src="@drawable/ic_voice_search"
         android:clickable="true"
         android:contentDescription="@string/description_start_voice_search"
         android:background="?android:attr/selectableItemBackground" />
-</LinearLayout>
\ No newline at end of file
+    <ImageButton
+        android:id="@+id/dialtacts_options_menu_button"
+        android:layout_width="@dimen/search_box_icon_size"
+        android:layout_height="@dimen/search_box_icon_size"
+        android:layout_margin="@dimen/search_box_icon_margin"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_overflow_menu"
+        android:tint="@color/searchbox_options_menu_color" />
+</view>
\ No newline at end of file
diff --git a/res/menu/call_details_options.xml b/res/menu/call_details_options.xml
index 39c8a67..c1daa6f 100644
--- a/res/menu/call_details_options.xml
+++ b/res/menu/call_details_options.xml
@@ -16,7 +16,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:id="@+id/menu_trash"
-        android:icon="@drawable/ic_menu_delete_dk"
+        android:icon="@drawable/ic_voicemail_delete"
         android:showAsAction="ifRoom"
         android:title="@string/recentCalls_trashVoicemail"
         android:onClick="onMenuTrashVoicemail"
diff --git a/res/values/animation_constants.xml b/res/values/animation_constants.xml
index 4e4bc36..7863060 100644
--- a/res/values/animation_constants.xml
+++ b/res/values/animation_constants.xml
@@ -27,4 +27,16 @@
     <dimen name="min_swipe">0dip</dimen>
     <dimen name="min_vert">10dip</dimen>
     <dimen name="min_lock">20dip</dimen>
+
+    <!-- Expand/collapse of call log entry duration. -->
+    <integer name="call_log_expand_collapse_duration">200</integer>
+
+    <!-- Start delay for the fade in of the call log actions. -->
+    <integer name="call_log_actions_fade_start">150</integer>
+
+    <!-- Duration of the fade in of the call log actions. -->
+    <integer name="call_log_actions_fade_in_duration">200</integer>
+
+    <!-- Duration of the fade out of the call log actions. -->
+    <integer name="call_log_actions_fade_out_duration">20</integer>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index f734aae..23f639f 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -31,4 +31,6 @@
         <attr name="call_log_voicemail_status_action_text_color" format="color" />
     </declare-styleable>
 
+    <declare-styleable name="SearchEditTextLayout" />
+
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 4874e1f..7d5ef71 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -59,6 +59,7 @@
     <color name="searchbox_text_color">#000000</color>
     <!-- Text color of the search box hint text  -->
     <color name="searchbox_hint_text_color">#d3d3d3</color>
+    <color name="searchbox_options_menu_color">#d5d5d5</color>
 
     <!-- Color of the contact name in favorite tiles -->
     <color name="contact_tile_name_color">#ffffff</color>
@@ -87,29 +88,9 @@
     <!-- Text color for the "Remove" text when a contact is dragged on top of the remove view -->
     <color name="remove_highlighted_text_color">#FF3F3B</color>
 
-    <!-- Text color for the "speed dial" label in the favorites menu. -->
-    <color name="speed_dial_text_color">#555555</color>
-
-    <!-- Background color for the "All Contacts" button in the favorites menu. -->
-    <color name="all_contacts_button_color">#999999</color>
-
-    <!-- Background color for the "All Contacts" button in the favorites menu when pressed. -->
-    <color name="all_contacts_button_pressed_color">#808080</color>
-
-    <!-- Background color for the favorites menu. -->
-    <color name="favorites_menu_background_color">#eeeeee</color>
-
-    <!-- Text color for the "All Contacts" button above the favorite callers -->
-    <color name="all_contacts_button_text_color">#ffffff</color>
-
     <!-- Color of the bottom border below the contacts grid on the main dialer screen. -->
     <color name="contacts_grid_bottom_border_color">#16000000</color>
 
-    <!-- Color of action bar text. Ensure this stays in sync with packages/Telephony
-         phone_settings_actionbar_text_color-->
-    <color name="actionbar_text_color">#ffffff</color>
-    <color name="actionbar_unselected_text_color">#a6ffffff</color>
-
     <!-- Color of actions in expanded call log entries.  This text color represents actions such
          as call back, play voicemail, etc. -->
     <color name="call_log_action_text">#1dc7db</color>
@@ -125,4 +106,7 @@
 
     <!-- Color for answered or outgoing call icons. -->
     <color name="answered_call">#2aad6f</color>
+
+    <!-- Color for icons in the actionbar -->
+    <color name="actionbar_icon_color">#ffffff</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ae65330..8ceda62 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -101,19 +101,19 @@
     <!-- Search box text size -->
     <dimen name="search_text_size">13.24sp</dimen>
     <!-- Search box interior padding - left -->
-    <dimen name="search_box_left_padding">16dp</dimen>
+    <dimen name="search_box_left_padding">8dp</dimen>
     <!-- Search box interior padding - right -->
     <dimen name="search_box_right_padding">8dp</dimen>
     <!-- Padding around the icon in the search box. -->
-    <dimen name="search_box_icon_padding">3dp</dimen>
+    <dimen name="search_box_icon_margin">4dp</dimen>
+    <dimen name="search_box_search_icon_padding">4dp</dimen>
     <!-- Left margin of the text field in the search box. -->
     <dimen name="search_box_text_left_margin">8dp</dimen>
     <!-- Size of the icon (voice search, close search) in the search box. -->
-    <dimen name="search_box_icon_size">37dp</dimen>
+    <dimen name="search_box_icon_size">28dp</dimen>
 
     <!-- Size of text in tabs. -->
     <dimen name="tab_height">43dp</dimen>
-    <dimen name="tab_text_size">14sp</dimen>
 
     <!-- Padding to the left and right of call log action buttons. -->
     <dimen name="call_log_action_horizontal_padding">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 04c951b..0f66131 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -657,10 +657,6 @@
          Do not translate. -->
     <string name="search_font_family">sans-serif</string>
 
-    <!-- The font-family to use for tab text.
-         Do not translate. -->
-    <string name="tab_font_family">sans-serif</string>
-
     <!-- Button text for the "call back" button displayed underneath an entry in the call log.
          Tapping causes a call to be placed to the caller represented by the call log entry.
          [CHAR LIMIT=30] -->
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index a3d7e50..3b68db9 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -40,12 +40,12 @@
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.DragEvent;
+import android.view.KeyEvent;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnDragListener;
 import android.view.animation.AccelerateInterpolator;
@@ -84,6 +84,7 @@
 import com.android.dialer.list.RemoveView;
 import com.android.dialer.list.SearchFragment;
 import com.android.dialer.list.SmartDialSearchFragment;
+import com.android.dialer.widget.SearchEditTextLayout;
 import com.android.dialerbind.DatabaseHelperManager;
 import com.android.internal.telephony.ITelephony;
 
@@ -101,6 +102,7 @@
         SpeedDialFragment.HostInterface,
         OnDragDropListener,
         OnPhoneNumberPickerActionListener,
+        PopupMenu.OnMenuItemClickListener,
         ViewPager.OnPageChangeListener {
     private static final String TAG = "DialtactsActivity";
 
@@ -160,8 +162,6 @@
     private View mFloatingActionButtonContainer;
     private ImageButton mFloatingActionButton;
 
-    private View mFragmentsFrame;
-
     private int mActionBarHeight;
     private boolean mInDialpadSearch;
     private boolean mInRegularSearch;
@@ -190,8 +190,10 @@
     private String mPendingSearchViewQuery;
 
     private EditText mSearchView;
+    private View mSearchIcon;
     private View mSearchViewCloseButton;
     private View mVoiceSearchButton;
+
     /**
      * 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
@@ -206,11 +208,8 @@
     private DialerDatabaseHelper mDialerDatabaseHelper;
     private DragDropController mDragDropController;
 
-    private int mDialerBackgroundColor;
-    private int mContactListBackgroundColor;
-
-    private class OverflowPopupMenu extends PopupMenu {
-        public OverflowPopupMenu(Context context, View anchor) {
+    private class OptionsPopupMenu extends PopupMenu {
+        public OptionsPopupMenu(Context context, View anchor) {
             super(context, anchor);
         }
 
@@ -218,8 +217,9 @@
         public void show() {
             final Menu menu = getMenu();
             final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
-            // TODO: Check mSpeedDialFragment.hasFrequents()
-            clearFrequents.setVisible(true);
+            clearFrequents.setVisible(mListsFragment != null &&
+                    mListsFragment.getSpeedDialFragment() != null &&
+                    mListsFragment.getSpeedDialFragment().hasFrequents());
             super.show();
         }
     }
@@ -261,19 +261,21 @@
                 Log.d(TAG, "onTextChange for mSearchView called with new query: " + newText);
             }
 
-            // Show search result with non-empty text. Show a bare list otherwise.
-            final boolean sameSearchMode = (mIsDialpadShown && mInDialpadSearch) ||
-                    (!mIsDialpadShown && mInRegularSearch);
-            if (!sameSearchMode) {
-                // call enterSearchUi only if we are switching search modes, or entering
-                // search ui for the first time
-                enterSearchUi(mIsDialpadShown, newText);
+            // Show search fragment only when the query string is changed to non-empty text.
+            if (!TextUtils.isEmpty(newText)) {
+                // Call enterSearchUi only if we are switching search modes, or showing a search
+                // fragment for the first time.
+                final boolean sameSearchMode = (mIsDialpadShown && mInDialpadSearch) ||
+                        (!mIsDialpadShown && mInRegularSearch);
+                if (!sameSearchMode) {
+                    enterSearchUi(mIsDialpadShown, mSearchQuery);
+                }
             }
 
             if (mIsDialpadShown && mSmartDialSearchFragment != null) {
-                mSmartDialSearchFragment.setQueryString(newText, false /* delaySelection */);
+                mSmartDialSearchFragment.setQueryString(mSearchQuery, false /* delaySelection */);
             } else if (mRegularSearchFragment != null) {
-                mRegularSearchFragment.setQueryString(newText, false /* delaySelection */);
+                mRegularSearchFragment.setQueryString(mSearchQuery, false /* delaySelection */);
             }
 
             if (TextUtils.isEmpty(newText)) {
@@ -290,6 +292,34 @@
         }
     };
 
+
+    /**
+     * Open the search UI when the user touches the search text view.
+     */
+    private final View.OnTouchListener mSearchViewOnTouchListener = new View.OnTouchListener() {
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            if (!isInSearchUi()) {
+                enterSearchUi(false /* smartDialSearch */, mSearchView.getText().toString());
+            }
+            return false;
+        }
+    };
+
+    /**
+     * If the search term is empty and the user closes the soft keyboard, close the search UI.
+     */
+    private final View.OnKeyListener mSearchEditTextLayoutListener = new View.OnKeyListener() {
+        @Override
+        public boolean onKey(View v, int keyCode, KeyEvent event) {
+            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN &&
+                    TextUtils.isEmpty(mSearchView.getText().toString())) {
+                onBackPressed();
+            }
+            return false;
+        }
+    };
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -302,14 +332,25 @@
         actionBar.setCustomView(R.layout.search_edittext);
         actionBar.setDisplayShowCustomEnabled(true);
 
-        final View customView = actionBar.getCustomView();
+        SearchEditTextLayout actionBarView = (SearchEditTextLayout) actionBar.getCustomView();
+        actionBarView.setPreImeKeyListener(mSearchEditTextLayoutListener);
 
-        mSearchView = (EditText) customView.findViewById(R.id.search_view);
+        mSearchIcon = actionBarView.findViewById(R.id.search_magnifying_glass);
+        mVoiceSearchButton = actionBarView.findViewById(R.id.voice_search_button);
+
+        mSearchView = (EditText) actionBarView.findViewById(R.id.search_view);
         mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener);
+        mSearchView.setOnTouchListener(mSearchViewOnTouchListener);
 
-        mSearchViewCloseButton = customView.findViewById(R.id.search_close_button);
+        mSearchViewCloseButton = actionBarView.findViewById(R.id.search_close_button);
         mSearchViewCloseButton.setOnClickListener(this);
 
+        ImageButton optionsMenuButton =
+                (ImageButton) actionBarView.findViewById(R.id.dialtacts_options_menu_button);
+        optionsMenuButton.setOnClickListener(this);
+        final OptionsPopupMenu optionsMenu = buildOptionsMenu(optionsMenuButton);
+        optionsMenuButton.setOnTouchListener(optionsMenu.getDragToOpenListener());
+
         final TypedArray styledAttributes = getTheme().obtainStyledAttributes(
                 new int[] { android.R.attr.actionBarSize });
         mActionBarHeight = (int) styledAttributes.getDimension(0, 0);
@@ -333,12 +374,6 @@
         parentLayout.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
         parentLayout.setOnDragListener(new LayoutOnDragListener());
 
-        mDialerBackgroundColor = getResources().getColor(R.color.background_dialer_light);
-        mContactListBackgroundColor =
-                getResources().getColor(R.color.contact_list_background_color);
-
-        mFragmentsFrame = findViewById(R.id.dialtacts_frame);
-
         mFloatingActionButtonContainer = findViewById(R.id.floating_action_button_container);
         ViewUtil.setupFloatingActionButton(mFloatingActionButtonContainer, getResources());
 
@@ -393,17 +428,9 @@
         } else if (fragment instanceof SmartDialSearchFragment) {
             mSmartDialSearchFragment = (SmartDialSearchFragment) fragment;
             mSmartDialSearchFragment.setOnPhoneNumberPickerActionListener(this);
-            mSmartDialSearchFragment.setShowEmptyListForNullQuery(true);
-            if (mFragmentsFrame != null) {
-                mFragmentsFrame.setAlpha(1.0f);
-            }
         } else if (fragment instanceof SearchFragment) {
             mRegularSearchFragment = (RegularSearchFragment) fragment;
             mRegularSearchFragment.setOnPhoneNumberPickerActionListener(this);
-            mRegularSearchFragment.setShowEmptyListForNullQuery(true);
-            if (mFragmentsFrame != null) {
-                mFragmentsFrame.setAlpha(1.0f);
-            }
         } else if (fragment instanceof ListsFragment) {
             mListsFragment = (ListsFragment) fragment;
             mListsFragment.addOnPageChangeListener(this);
@@ -447,6 +474,9 @@
                             Toast.LENGTH_SHORT).show();
                 }
                 break;
+            case R.id.dialtacts_options_menu_button:
+                buildOptionsMenu(view).show();
+                break;
             default: {
                 Log.wtf(TAG, "Unexpected onClick event from " + view);
                 break;
@@ -455,7 +485,7 @@
     }
 
     @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
+    public boolean onMenuItemClick(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.menu_history:
                 showCallHistory();
@@ -479,8 +509,6 @@
                         DialtactsActivity.class);
                 return true;
             case R.id.menu_clear_frequents:
-                // TODO: This should be enabled/disabled based on
-                // SpeedDialFragment.hasFrequents
                 ClearFrequentsDialog.show(getFragmentManager());
                 return true;
             case R.id.menu_call_settings:
@@ -524,6 +552,10 @@
         final FragmentTransaction ft = getFragmentManager().beginTransaction();
         ft.show(mDialpadFragment);
         ft.commit();
+
+        if (!isInSearchUi()) {
+            enterSearchUi(true /* isSmartDial */, mSearchQuery);
+        }
     }
 
     /**
@@ -538,12 +570,6 @@
             mDialpadFragment.setYFraction(0);
         }
 
-        if (mListsFragment != null && mListsFragment.isResumed() && mListsFragment.isVisible()) {
-            // If the favorites fragment is showing, fade to blank.
-            mFragmentsFrame.animate().alpha(0.0f);
-            parentLayout.setBackgroundColor(mContactListBackgroundColor);
-        }
-
         updateSearchFragmentPosition();
         getActionBar().hide();
     }
@@ -566,6 +592,7 @@
         mIsDialpadShown = false;
         mDialpadFragment.setAnimate(animate);
 
+        updateSearchFragmentPosition();
         updateFloatingActionButton();
         if (animate) {
             Animation slideOut = AnimationUtils.loadAnimation(this, R.anim.slide_out);
@@ -580,13 +607,10 @@
             commitDialpadFragmentHide();
         }
 
-        if (mListsFragment != null && mListsFragment.isVisible()) {
-            mFragmentsFrame.animate().alpha(1.0f);
-            parentLayout.setBackgroundColor(mDialerBackgroundColor);
+        mListsFragment.maybeShowActionBar();
+        if (isInSearchUi()) {
+            mSearchIcon.setVisibility(View.GONE);
         }
-
-        updateSearchFragmentPosition();
-        getActionBar().show();
     }
 
     /**
@@ -601,9 +625,9 @@
     private void updateSearchFragmentPosition() {
         int translationValue = mIsDialpadShown ?  -mActionBarHeight : 0;
         SearchFragment fragment = null;
-        if (mInDialpadSearch) {
+        if (mSmartDialSearchFragment != null && mSmartDialSearchFragment.isVisible()) {
             fragment = mSmartDialSearchFragment;
-        } else if (mInRegularSearch) {
+        } else if (mRegularSearchFragment != null && mRegularSearchFragment.isVisible()) {
             fragment = mRegularSearchFragment;
         }
         if (fragment != null && fragment.isVisible()) {
@@ -612,7 +636,7 @@
         }
     }
 
-    private boolean getInSearchUi() {
+    private boolean isInSearchUi() {
         return mInDialpadSearch || mInRegularSearch;
     }
 
@@ -635,7 +659,6 @@
     }
 
     private void prepareVoiceSearchButton() {
-        mVoiceSearchButton = getActionBar().getCustomView().findViewById(R.id.voice_search_button);
         final Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
         if (canIntentBeHandled(voiceIntent)) {
             mVoiceSearchButton.setVisibility(View.VISIBLE);
@@ -645,19 +668,20 @@
         }
     }
 
+    private OptionsPopupMenu buildOptionsMenu(View invoker) {
+        final OptionsPopupMenu popupMenu = new OptionsPopupMenu(this, invoker);
+        popupMenu.inflate(R.menu.dialtacts_options);
+        popupMenu.setOnMenuItemClickListener(this);
+        return popupMenu;
+    }
+
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        if (DEBUG) {
-            Log.d(TAG, "onCreateOptionsMenu");
-        }
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.dialtacts_options, menu);
-
         if (mPendingSearchViewQuery != null) {
             mSearchView.setText(mPendingSearchViewQuery);
             mPendingSearchViewQuery = null;
         }
-        return super.onCreateOptionsMenu(menu);
+        return false;
     }
 
     /**
@@ -773,19 +797,29 @@
         mInRegularSearch = !smartDialSearch;
 
         SearchFragment fragment = (SearchFragment) getFragmentManager().findFragmentByTag(tag);
+        transaction.setCustomAnimations(android.R.animator.fade_in, 0);
         if (fragment == null) {
             if (smartDialSearch) {
                 fragment = new SmartDialSearchFragment();
             } else {
                 fragment = new RegularSearchFragment();
             }
+            transaction.add(R.id.dialtacts_frame, fragment, tag);
+        } else {
+            transaction.show(fragment);
         }
+
         // DialtactsActivity will provide the options menu
         fragment.setHasOptionsMenu(false);
-        transaction.replace(R.id.dialtacts_frame, fragment, tag);
-        transaction.addToBackStack(null);
+        fragment.setShowEmptyListForNullQuery(true);
         fragment.setQueryString(query, false /* delaySelection */);
         transaction.commit();
+
+        mListsFragment.getView().animate().alpha(0).withLayer();
+
+        if (!mIsDialpadShown) {
+            mSearchIcon.setVisibility(View.GONE);
+        }
     }
 
     /**
@@ -796,14 +830,24 @@
         if (getFragmentManager().isDestroyed()) {
             return;
         }
-        // Go all the way back to the favorites fragment, regardless of how many times we
-        // transitioned between search fragments
-        getFragmentManager().popBackStack(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+
+        mSearchView.setText(null);
+        mDialpadFragment.clearDialpad();
         setNotInSearchUi();
 
-        if (mIsDialpadShown) {
-            mFragmentsFrame.setAlpha(0);
+        final FragmentTransaction transaction = getFragmentManager().beginTransaction();
+        transaction.setCustomAnimations(0, android.R.animator.fade_out);
+
+        if (mSmartDialSearchFragment != null) {
+            transaction.remove(mSmartDialSearchFragment);
         }
+        if (mRegularSearchFragment != null) {
+            transaction.remove(mRegularSearchFragment);
+        }
+        transaction.commit();
+
+        mListsFragment.getView().animate().alpha(1).withLayer();
+        mSearchIcon.setVisibility(View.VISIBLE);
     }
 
     /** Returns an Intent to launch Call Settings screen */
@@ -817,10 +861,11 @@
     @Override
     public void onBackPressed() {
         if (mIsDialpadShown) {
+            if (TextUtils.isEmpty(mSearchQuery)) {
+                exitSearchUi();
+            }
             hideDialpadFragment(true, false);
-        } else if (getInSearchUi()) {
-            mSearchView.setText(null);
-            mDialpadFragment.clearDialpad();
+        } else if (isInSearchUi()) {
             exitSearchUi();
         } else {
             super.onBackPressed();
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index 2b2d43c..6caa25c 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -17,6 +17,8 @@
 package com.android.dialer.calllog;
 
 import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.animation.Animator.AnimatorListener;
 import android.app.Activity;
@@ -541,9 +543,33 @@
                 if (!isExpand) {
                     viewHolder.actionsView.setVisibility(View.VISIBLE);
                 }
+
+                // Set up the fade effect for the action buttons.
+                if (isExpand) {
+                    int fadeDuration = getResources().getInteger(
+                            R.integer.call_log_actions_fade_in_duration);
+                    int startDelay = getResources().getInteger(
+                            R.integer.call_log_actions_fade_start);
+                    // Start the fade in after the expansion has partly completed, otherwise it
+                    // will be mostly over before the expansion completes.
+                    viewHolder.actionsView.setAlpha(0f);
+                    viewHolder.actionsView.animate()
+                            .alpha(1f)
+                            .setStartDelay(startDelay)
+                            .setDuration(fadeDuration)
+                            .start();
+                } else {
+                    int fadeDuration = getResources().getInteger(
+                            R.integer.call_log_actions_fade_out_duration);
+                    viewHolder.actionsView.setAlpha(1f);
+                    viewHolder.actionsView.animate()
+                            .alpha(0f)
+                            .setDuration(fadeDuration)
+                            .start();
+                }
                 view.requestLayout();
 
-                // Set up the animator to animate the expansion.
+                // Set up the animator to animate the expansion and shadow depth.
                 ValueAnimator animator = isExpand ? ValueAnimator.ofFloat(0f, 1f)
                         : ValueAnimator.ofFloat(1f, 0f);
 
@@ -555,7 +581,8 @@
                         // For each value from 0 to 1, animate the various parts of the layout.
                         view.getLayoutParams().height =
                                 (int) (value * distance + baseHeight);
-                        view.setElevation(mExpandedItemElevation * value);
+                        viewHolder.callLogEntryView
+                                .setElevation(mExpandedItemElevation * value);
                         view.requestLayout();
                     }
                 });
@@ -564,6 +591,7 @@
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         view.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
+
                         if (!isExpand) {
                             viewHolder.actionsView.setVisibility(View.GONE);
                         }
@@ -576,6 +604,11 @@
                     @Override
                     public void onAnimationStart(Animator animation) { }
                 });
+
+                final int expandCollapseDuration = getResources().getInteger(
+                        R.integer.call_log_expand_collapse_duration);
+
+                animator.setDuration(expandCollapseDuration);
                 animator.start();
 
                 // Return false so this draw does not occur to prevent the final frame from
diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java
index 18fa531..f2be6ab 100644
--- a/src/com/android/dialer/list/ListsFragment.java
+++ b/src/com/android/dialer/list/ListsFragment.java
@@ -89,6 +89,8 @@
     private CallLogAdapter mCallLogAdapter;
     private CallLogQueryHandler mCallLogQueryHandler;
 
+    private boolean mIsPanelOpen = true;
+
     /**
      * Call shortcuts older than this date (persisted in shared preferences) will not show up in
      * at the top of the screen
@@ -143,15 +145,21 @@
                 final int availableActionBarHeight =
                         Math.min(mActionBar.getHeight(), topPaneHeight);
                 mActionBar.setHideOffset(mActionBar.getHeight() - availableActionBarHeight);
+
+                if (!mActionBar.isShowing()) {
+                    mActionBar.show();
+                }
             }
         }
 
         @Override
         public void onPanelOpened(View panel) {
+            mIsPanelOpen = true;
         }
 
         @Override
         public void onPanelClosed(View panel) {
+            mIsPanelOpen = false;
         }
     };
 
@@ -335,6 +343,15 @@
         }
     }
 
+    public void maybeShowActionBar() {
+        // TODO: Try to show the action bar regardless of whether the panel is open, and then update
+        // the offset to show/hide the action bar, instead of updating the whether the action bar is
+        // shown in onPanelSlide.
+        if (mIsPanelOpen && mActionBar != null) {
+            mActionBar.show();
+        }
+    }
+
     private void setupPaneLayout(OverlappingPaneLayout paneLayout) {
         // TODO: Remove the notion of a capturable view. The entire view be slideable, once
         // the framework better supports nested scrolling.
@@ -347,4 +364,8 @@
         // height changes.
         transition.enableTransitionType(LayoutTransition.CHANGING);
     }
+
+    public SpeedDialFragment getSpeedDialFragment() {
+        return mSpeedDialFragment;
+    }
 }
diff --git a/src/com/android/dialer/list/SpeedDialFragment.java b/src/com/android/dialer/list/SpeedDialFragment.java
index 0399bf7..478327c 100644
--- a/src/com/android/dialer/list/SpeedDialFragment.java
+++ b/src/com/android/dialer/list/SpeedDialFragment.java
@@ -146,7 +146,6 @@
 
     private PhoneFavoriteListView mListView;
 
-    private View mPhoneFavoritesMenu;
     private View mContactTileFrame;
 
     private TileInteractionTeaserView mTileInteractionTeaserView;
@@ -211,8 +210,6 @@
 
         mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view);
 
-        mPhoneFavoritesMenu = inflater.inflate(R.layout.phone_favorites_menu, mListView, false);
-
         mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame);
 
         mTileInteractionTeaserView = (TileInteractionTeaserView) inflater.inflate(
diff --git a/src/com/android/dialer/widget/SearchEditTextLayout.java b/src/com/android/dialer/widget/SearchEditTextLayout.java
new file mode 100644
index 0000000..40a4e43
--- /dev/null
+++ b/src/com/android/dialer/widget/SearchEditTextLayout.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ */
+
+package com.android.dialer.widget;
+
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.LinearLayout;
+
+public class SearchEditTextLayout extends LinearLayout {
+    private OnKeyListener mPreImeKeyListener;
+
+    public SearchEditTextLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setPreImeKeyListener(OnKeyListener listener) {
+        mPreImeKeyListener = listener;
+    }
+
+    @Override
+    public boolean dispatchKeyEventPreIme(KeyEvent event) {
+        if (mPreImeKeyListener != null) {
+            if (mPreImeKeyListener.onKey(this, event.getKeyCode(), event)) {
+                return true;
+            }
+        }
+        return super.dispatchKeyEventPreIme(event);
+    }
+}
\ No newline at end of file