Adding support for expandable call log entries.

Bug: 13962594
Change-Id: I19a4a65dce922619df0a709293ca291c345c8be7
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index aa8a185..23c7b14 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -66,8 +66,7 @@
             android:layout_height="match_parent"
             android:fadingEdge="none"
             android:scrollbarStyle="outsideOverlay"
-            android:divider="@color/favorite_contacts_separator_color"
-            android:dividerHeight="1dp"
+            android:divider="@null"
         />
         <TextView android:id="@android:id/empty"
             android:layout_width="match_parent"
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 953efc4..eaf2a80 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -39,22 +39,22 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:baselineAligned="false"
-        android:orientation="horizontal"
+        android:orientation="vertical"
         android:gravity="center_vertical"
         >
 
         <!-- Primary area containing the contact badge and caller information -->
         <LinearLayout
             android:id="@+id/primary_action_view"
-            android:layout_width="0dp"
-            android:layout_weight="1"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
             android:padding="@dimen/call_log_outer_margin"
             android:orientation="horizontal"
             android:gravity="center_vertical"
             android:background="?android:attr/selectableItemBackground"
             android:focusable="true"
-            android:nextFocusRight="@+id/secondary_action_icon"
+            android:nextFocusRight="@+id/call_back_action"
             android:nextFocusLeft="@+id/quick_contact_photo"
             >
             <QuickContactBadge
@@ -79,25 +79,19 @@
                     android:layout_height="wrap_content"
                     android:layout_marginEnd="@dimen/call_log_icon_margin"
                     android:textColor="?attr/call_log_primary_text_color"
-                    android:textSize="16sp"
+                    android:textSize="@dimen/call_log_primary_text_size"
                     android:singleLine="true"
                     />
-                <LinearLayout
+                <TextView
+                    android:id="@+id/voicemail_transcription"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    >
-                    <TextView
-                        android:id="@+id/label"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="@dimen/call_log_icon_margin"
-                        android:textColor="?attr/call_log_secondary_text_color"
-                        android:textSize="12sp"
-                        android:singleLine="true"
-                        android:ellipsize="marquee"
-                        />
-                </LinearLayout>
+                    android:layout_marginEnd="@dimen/call_log_icon_margin"
+                    android:textColor="?attr/call_log_secondary_text_color"
+                    android:textSize="@dimen/call_log_secondary_text_size"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    />
                 <LinearLayout
                     android:id="@+id/call_type"
                     android:layout_width="wrap_content"
@@ -113,46 +107,25 @@
                         android:layout_gravity="center_vertical"
                         />
                     <TextView
-                        android:id="@+id/call_count_and_date"
+                        android:id="@+id/call_location_and_date"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_marginEnd="@dimen/call_log_icon_margin"
                         android:layout_gravity="center_vertical"
                         android:textColor="?attr/call_log_secondary_text_color"
-                        android:textSize="12sp"
+                        android:textSize="@dimen/call_log_secondary_text_size"
                         android:singleLine="true"
                         />
                 </LinearLayout>
             </LinearLayout>
         </LinearLayout>
-        <!-- Linear layout to house a vertical separator line and the secondary action button.
-             Used as a convenience to hide both the separator and action button at the same
-             time. -->
-        <LinearLayout
-            android:id="@+id/secondary_action_view"
-            android:layout_width="@dimen/call_log_call_action_width"
-            android:layout_height="match_parent"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            >
-            <!-- Thin vertical divider to visually separate the secondary action button -->
-            <View
-                android:id="@+id/vertical_divider"
-                android:layout_width="@dimen/call_log_list_item_vertical_divider_width"
-                android:layout_height="match_parent"
-                android:layout_marginTop="@dimen/call_log_list_item_vertical_divider_margin"
-                android:layout_marginBottom="@dimen/call_log_list_item_vertical_divider_margin"
-                android:background="?android:attr/dividerVertical"/>
-            <!-- The secondary action button; either play voicemail or call details. -->
-            <ImageButton
-                android:id="@+id/secondary_action_icon"
-                android:layout_width="fill_parent"
-                android:layout_height="match_parent"
-                android:scaleType="center"
-                android:background="?android:attr/selectableItemBackground"
-                android:nextFocusLeft="@id/primary_action_view"
-                />
-        </LinearLayout>
+
+        <!-- Viewstub with additional expandable actions for a call log entry -->
+        <ViewStub android:id="@+id/call_log_entry_actions_stub"
+                  android:inflatedId="@+id/call_log_entry_actions"
+                  android:layout="@layout/call_log_list_item_actions"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"/>
     </LinearLayout>
     <TextView
         android:id="@+id/call_log_header"
diff --git a/res/layout/call_log_list_item_actions.xml b/res/layout/call_log_list_item_actions.xml
new file mode 100644
index 0000000..7337863
--- /dev/null
+++ b/res/layout/call_log_list_item_actions.xml
@@ -0,0 +1,74 @@
+<?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
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:id="@+id/call_log_action_container">
+    <LinearLayout
+        android:id="@+id/call_log_entry_actions_ll"
+        android:gravity="center_vertical"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/call_log_action_height"
+        android:orientation="horizontal"
+        android:paddingLeft="@dimen/call_log_actions_left_padding"
+        android:visibility="visible"
+        android:importantForAccessibility="1"
+        >
+        <TextView
+            android:id="@+id/call_back_action"
+            android:fontFamily="sans-serif-medium"
+            android:gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/call_log_action_horizontal_padding"
+            android:paddingRight="@dimen/call_log_action_horizontal_padding"
+            android:text="@string/call_log_action_call_back"
+            android:textColor="@color/call_log_action_text"
+            android:textSize="@dimen/call_log_secondary_text_size"
+            android:nextFocusLeft="@+id/primary_action_view"
+            android:nextFocusRight="@+id/voicemail_action"
+            android:focusable="true"/>
+        <TextView
+            android:id="@+id/voicemail_action"
+            android:fontFamily="sans-serif-medium"
+            android:gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/call_log_action_horizontal_padding"
+            android:paddingRight="@dimen/call_log_action_horizontal_padding"
+            android:text="@string/call_log_action_voicemail"
+            android:textColor="@color/call_log_action_text"
+            android:textSize="@dimen/call_log_secondary_text_size"
+            android:nextFocusLeft="@+id/call_back_action"
+            android:nextFocusRight="@+id/delete_action"
+            android:focusable="true"/>
+        <TextView
+            android:id="@+id/delete_action"
+            android:fontFamily="sans-serif-medium"
+            android:gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/call_log_action_horizontal_padding"
+            android:paddingRight="@dimen/call_log_action_horizontal_padding"
+            android:text="@string/call_log_action_delete"
+            android:textColor="@color/call_log_action_delete_text"
+            android:textSize="@dimen/call_log_secondary_text_size"
+            android:nextFocusLeft="@+id/voicemail_action"
+            android:nextFocusRight="@+id/primary_action_view"
+            android:focusable="true"/>
+    </LinearLayout>
+</FrameLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5a62273..ffc6115 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -55,7 +55,7 @@
     <color name="background_dialer_light">#ffffff</color>
 
     <!-- Background color of dialer list items (contacts, call log entries) -->
-    <color name="background_dialer_list_items">#ffffff</color>
+    <color name="background_dialer_list_items">#fbfbfb</color>
 
     <!-- Background color of action bars. Ensure this stays in sync with packages/Telephony
          actionbar_background_color. -->
@@ -107,4 +107,14 @@
     <!-- 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 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>
+
+    <!-- Color of the "delete" action in expanded call log entries. -->
+    <color name="call_log_action_delete_text">#ff4f4f</color>
+
+    <!-- Color of action text for expanded call log entries which is disabled. -->
+    <color name="call_log_disabled_text">#b3b3b3</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 5095cdd..d81c0f6 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -33,7 +33,7 @@
     <dimen name="call_log_outer_margin">8dip</dimen>
     <dimen name="call_log_indent_margin">24dip</dimen>
     <dimen name="call_log_list_item_height">56dip</dimen>
-    <dimen name="call_log_list_contact_photo_size">64dip</dimen>
+    <dimen name="call_log_list_contact_photo_size">40dip</dimen>
     <dimen name="call_detail_contact_name_margin">24dip</dimen>
     <dimen name="call_detail_button_spacing">2dip</dimen>
     <!-- Defines the vertical margin for the vertical separator between
@@ -128,7 +128,19 @@
     <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>
-
     <!-- Size of text in tabs. -->
     <dimen name="tab_text_size">13sp</dimen>
+    <!-- Padding to the left and right of call log action buttons. -->
+    <dimen name="call_log_action_horizontal_padding">8dp</dimen>
+    <!-- Left-padding for the call log action buttons - ensures the buttons align with the text
+         to the right of the contact badge.  Adjust when any of the following change:
+         call_log_action_horizontal_padding
+         call_log_list_contact_photo_size  -->
+    <dimen name="call_log_actions_left_padding">48dp</dimen>
+    <!-- Text size for primary call log text -->
+    <dimen name="call_log_primary_text_size">16sp</dimen>
+    <!-- Text size for secondary call log text -->
+    <dimen name="call_log_secondary_text_size">14sp</dimen>
+    <!-- Height of the call log actions section for each call log entry -->
+    <dimen name="call_log_action_height">48dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2575a0b..4815eb8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -472,59 +472,6 @@
     -->
     <string name="description_num_calls"><xliff:g id="numberOfCalls">%1$s</xliff:g> calls.</string>
 
-
-    <!-- Call history description for a missed call from a caller.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_return_missed_call">Return missed call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
-
-
-    <!-- Call history description for an answered call for a caller.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_return_answered_call">Return answered call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
-
-    <!-- Call history description for a missed call from an unknown caller.
-         Drops the "return" part of description_return_missed_call since it is not
-         possible to actually call an unknown number.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_unknown_missed_call">Missed call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
-
-
-    <!-- Call history description for an answered call from an unknown caller.
-        Drops the "return" part of description_return_answered_call since it is not
-         possible to actually call an unknown number.
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_unknown_answered_call">Answered call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
-
-    <!-- String describing an outgoing call entry in the call log.  Used to indicate that
-         a call will be made to the specified caller.  Used when there are multiple calls to/from
-         the caller.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_call_last_multiple">Call <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g>.  Last called <xliff:g id="timeOfCall">%3$s</xliff:g>.</string>
-
-    <!-- String describing an outgoing call entry in the call log.  Used to indicate that
-         a call will be made to the specified caller.  Used when there is only a single call
-         related to/from the caller.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_call_last">Call <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g>.  Called <xliff:g id="timeOfCall">%3$s</xliff:g>.</string>
-
-
     <!-- String describing the button to SMS a number or contact.
 
         Note: AccessibilityServices use this attribute to announce what the view represents.
@@ -548,10 +495,6 @@
     <!-- String describing the icon used to start a voice search -->
     <string name="description_start_voice_search">Start voice search</string>
 
-    <!-- The string used to represent an unknown location for a phone number in the call log
-        Do not translate. -->
-    <string name="call_log_empty_geocode"></string>
-
     <!-- Menu item used to call a contact, containing the number of the contact to call -->
     <string name="menu_callNumber">Call <xliff:g id="number">%s</xliff:g></string>
 
@@ -774,4 +717,57 @@
     <!-- 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] -->
+    <string name="call_log_action_call_back">CALL BACK</string>
+
+    <!-- Button text for the "DELETE" button displayed underneath an entry in the call log.
+         Tapping causes the call log entry in question to be removed from the call log.
+         [CHAR LIMIT=30] -->
+    <string name="call_log_action_delete">DELETE</string>
+
+    <!-- Button text for the "LISTEN" button displayed underneath an entry in the call log.
+         Tapping navigates the user to the call details screen where the user can listen to the
+         voicemail represented by the call log entry.
+         [CHAR LIMIT=30] -->
+    <string name="call_log_action_voicemail">LISTEN</string>
+
+    <!-- String describing an incoming missed call entry in the call log.
+         Note: AccessibilityServices uses this attribute to announce what the view represents.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_incoming_missed_call">Missed call from <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g>, <xliff:g id="typeOrLocation" example="Mobile">%2$s</xliff:g>, <xliff:g id="timeOfCall" example="2 min ago">%3$s</xliff:g>.</string>
+
+    <!-- String describing an incoming answered call entry in the call log.
+         Note: AccessibilityServices uses this attribute to announce what the view represents.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_incoming_answered_call">Answered call from <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g>, <xliff:g id="typeOrLocation" example="Mobile">%2$s</xliff:g>, <xliff:g id="timeOfCall" example="2 min ago">%3$s</xliff:g>.</string>
+
+    <!-- String describing an outgoing call entry in the call log.
+         Note: AccessibilityServices uses this attribute to announce what the view represents.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_outgoing_call">Call to <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g>, <xliff:g id="typeOrLocation" example="Mobile">%2$s</xliff:g>, <xliff:g id="timeOfCall" example="2 min ago">%3$s</xliff:g>.</string>
+
+    <!-- String describing the "call back" action for an entry in the call log.  The call back
+         action triggers a return call to the named user.
+         Note: AccessibilityServices uses this attribute to announce the purpose of the button.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_call_back_action">Call back <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g></string>
+
+    <!-- String describing the "listen" action for an entry in the call log.  The listen
+         action is shown for call log entries representing a voicemail message and this button
+         triggers playing back the voicemail.
+         Note: AccessibilityServices uses this attribute to announce the purpose of the button.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_voicemail_action">Listen to voicemail from <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g></string>
+
+    <!-- String describing the "delete" action for an entry in the call log.  The delete
+         action triggers the removal of the current call log entry from the call log.
+         Note: AccessibilityServices uses this attribute to announce the purpose of the button.
+         [CHAR LIMIT=NONE] -->
+    <string name="description_delete_action">Delete call log entry for <xliff:g id="nameOrNumber" example="John Smith">%1$s</xliff:g></string>
+
+    <!-- Toast message which appears when a call log entry is deleted. -->
+    <string name="toast_entry_removed">Call log entry deleted.</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 738a0b6..db56ab2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -100,9 +100,9 @@
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
         <!-- CallLog -->
-        <item name="call_log_primary_text_color">#333333</item>
+        <item name="call_log_primary_text_color">#404040</item>
         <item name="call_log_primary_background_color">#FFFFFF</item>
-        <item name="call_log_secondary_text_color">#333333</item>
+        <item name="call_log_secondary_text_color">#9a9a9a</item>
         <item name="call_log_secondary_background_color">#FFFFFF</item>
         <item name="call_log_header_color">#FFFFFF</item>
         <!-- VoicemailStatus -->
diff --git a/src/com/android/dialer/PhoneCallDetailsHelper.java b/src/com/android/dialer/PhoneCallDetailsHelper.java
index 4424fcb..edd0831 100644
--- a/src/com/android/dialer/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/PhoneCallDetailsHelper.java
@@ -18,9 +18,7 @@
 
 import android.content.res.Resources;
 import android.graphics.Typeface;
-import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.telephony.PhoneNumberUtils;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -36,6 +34,10 @@
 import com.android.dialer.calllog.ContactInfo;
 import com.android.dialer.calllog.PhoneNumberDisplayHelper;
 import com.android.dialer.calllog.PhoneNumberUtilsWrapper;
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Helper class to fill in the views in {@link PhoneCallDetailsViews}.
@@ -53,6 +55,11 @@
     private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper;
 
     /**
+     * List of items to be concatenated together for accessibility descriptions
+     */
+    private ArrayList<CharSequence> mDescriptionItems = Lists.newArrayList();
+
+    /**
      * Creates a new instance of the helper.
      * <p>
      * Generally you should have a single instance of this helper in any context.
@@ -90,42 +97,54 @@
         Integer highlightColor =
                 isHighlighted ? mCallTypeHelper.getHighlightedColor(details.callTypes[0]) : null;
 
-        // The date of this call, relative to the current time.
-        CharSequence dateText = getCallDate(details);
+        CharSequence callLocationAndDate = getCallLocationAndDate(details);
 
-        // Set the call count and date.
-        setCallCountAndDate(views, callCount, dateText, highlightColor);
-
-        // Get type of call (ie mobile, home, etc) if known, or the caller's
-        CharSequence numberFormattedLabel = getCallTypeOrLocation(details);
+        // Set the call count, location and date.
+        setCallCountAndDate(views, callCount, callLocationAndDate, highlightColor);
 
         final CharSequence nameText;
-        final CharSequence numberText;
-        final CharSequence labelText;
         final CharSequence displayNumber =
             mPhoneNumberHelper.getDisplayNumber(details.number,
                     details.numberPresentation, details.formattedNumber);
         if (TextUtils.isEmpty(details.name)) {
             nameText = displayNumber;
-            if (TextUtils.isEmpty(details.geocode)
-                    || mPhoneNumberUtilsWrapper.isVoicemailNumber(details.number)) {
-                numberText = mResources.getString(R.string.call_log_empty_geocode);
-            } else {
-                numberText = details.geocode;
-            }
-            labelText = numberText;
             // We have a real phone number as "nameView" so make it always LTR
             views.nameView.setTextDirection(View.TEXT_DIRECTION_LTR);
         } else {
             nameText = details.name;
-            numberText = displayNumber;
-            labelText = TextUtils.isEmpty(numberFormattedLabel) ? numberText :
-                    numberFormattedLabel;
         }
 
         views.nameView.setText(nameText);
-        views.labelView.setText(labelText);
-        views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
+
+        // TODO: At the current time the voicemail transcription is not supported.  This view
+        // is kept for future expansion when we may wish to show a transcription of voicemail.
+        views.voicemailTranscriptionView.setText("");
+        views.voicemailTranscriptionView.setVisibility(View.GONE);
+    }
+
+    /**
+     * Builds a string containing the call location and date.
+     *
+     * @param details The call details.
+     * @return The call location and date string.
+     */
+    private CharSequence getCallLocationAndDate(PhoneCallDetails details) {
+        mDescriptionItems.clear();
+
+        // Get type of call (ie mobile, home, etc) if known, or the caller's location.
+        CharSequence callTypeOrLocation = getCallTypeOrLocation(details);
+
+        // Only add the call type or location if its not empty.  It will be empty for unknown
+        // callers.
+        if (!TextUtils.isEmpty(callTypeOrLocation)) {
+            mDescriptionItems.add(callTypeOrLocation);
+        }
+        // The date of this call, relative to the current time.
+        mDescriptionItems.add(getCallDate(details));
+
+        // Create a comma separated list from the call type or location, and call date.
+        // TextUtils.join ensures a locale appropriate list separator is used.
+        return TextUtils.join((List<CharSequence>)mDescriptionItems);
     }
 
     /**
@@ -139,7 +158,9 @@
         CharSequence numberFormattedLabel = null;
         // Only show a label if the number is shown and it is not a SIP address.
         if (!TextUtils.isEmpty(details.number)
-                && !PhoneNumberHelper.isUriNumber(details.number.toString())) {
+                && !PhoneNumberHelper.isUriNumber(details.number.toString())
+                && !mPhoneNumberUtilsWrapper.isVoicemailNumber(details.number)) {
+
             if (details.numberLabel == ContactInfo.GEOCODE_AS_LABEL) {
                 numberFormattedLabel = details.geocode;
             } else {
@@ -147,6 +168,11 @@
                         details.numberLabel);
             }
         }
+
+        if (!TextUtils.isEmpty(details.name) && TextUtils.isEmpty(numberFormattedLabel)) {
+            numberFormattedLabel = mPhoneNumberHelper.getDisplayNumber(details.number,
+                    details.numberPresentation, details.formattedNumber);
+        }
         return numberFormattedLabel;
     }
 
@@ -216,7 +242,7 @@
             formattedText = text;
         }
 
-        views.callTypeAndDate.setText(formattedText);
+        views.callLocationAndDate.setText(formattedText);
     }
 
     /** Creates a SpannableString for the given text which is bold and in the given color. */
diff --git a/src/com/android/dialer/PhoneCallDetailsViews.java b/src/com/android/dialer/PhoneCallDetailsViews.java
index 4e48210..30023ea 100644
--- a/src/com/android/dialer/PhoneCallDetailsViews.java
+++ b/src/com/android/dialer/PhoneCallDetailsViews.java
@@ -29,16 +29,17 @@
     public final TextView nameView;
     public final View callTypeView;
     public final CallTypeIconsView callTypeIcons;
-    public final TextView callTypeAndDate;
-    public final TextView labelView;
+    public final TextView callLocationAndDate;
+    public final TextView voicemailTranscriptionView;
 
     private PhoneCallDetailsViews(TextView nameView, View callTypeView,
-            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView labelView) {
+            CallTypeIconsView callTypeIcons, TextView callLocationAndDate,
+            TextView voicemailTranscriptionView) {
         this.nameView = nameView;
         this.callTypeView = callTypeView;
         this.callTypeIcons = callTypeIcons;
-        this.callTypeAndDate = callTypeAndDate;
-        this.labelView = labelView;
+        this.callLocationAndDate = callLocationAndDate;
+        this.voicemailTranscriptionView = voicemailTranscriptionView;
     }
 
     /**
@@ -52,8 +53,8 @@
         return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
                 view.findViewById(R.id.call_type),
                 (CallTypeIconsView) view.findViewById(R.id.call_type_icons),
-                (TextView) view.findViewById(R.id.call_count_and_date),
-                (TextView) view.findViewById(R.id.label));
+                (TextView) view.findViewById(R.id.call_location_and_date),
+                (TextView) view.findViewById(R.id.voicemail_transcription));
     }
 
     public static PhoneCallDetailsViews createForTest(Context context) {
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 266be34..a8cd72a 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -22,6 +22,7 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Message;
 import android.provider.CallLog.Calls;
@@ -35,20 +36,26 @@
 import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.android.common.widget.GroupingListAdapter;
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.util.UriUtils;
+import com.android.dialer.CallDetailActivity;
 import com.android.dialer.PhoneCallDetails;
 import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
+import com.android.dialer.util.AsyncTaskExecutor;
+import com.android.dialer.util.AsyncTaskExecutors;
 import com.android.dialer.util.ExpirableCache;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 
+import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 
 /**
  * Adapter class to fill in data for the Call Log.
@@ -56,6 +63,12 @@
 public class CallLogAdapter extends GroupingListAdapter
         implements ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
 
+
+    /** The enumeration of {@link android.os.AsyncTask} objects used in this class. */
+    public enum Tasks {
+        REMOVE_CALL_LOG_ENTRIES,
+    }
+
     /** Interface used to initiate a refresh of the content. */
     public interface CallFetcher {
         public void fetchCalls();
@@ -103,6 +116,9 @@
     private final CallFetcher mCallFetcher;
     private ViewTreeObserver mViewTreeObserver = null;
 
+    /** Aynchronous task executor, lazy instantiated as needed. */
+    private AsyncTaskExecutor mAsyncTaskExecutor;
+
     /**
      * A cache of the contact details for the phone numbers in the call log.
      * <p>
@@ -113,6 +129,9 @@
      */
     private ExpirableCache<NumberWithCountryIso, ContactInfo> mContactInfoCache;
 
+    /** Hashmap, keyed by call Id, used to track which call log entries have been expanded or not */
+    private HashMap<Long,Boolean> mIsExpanded = new HashMap<Long,Boolean>();
+
     /**
      * A request for contact details for the given number.
      */
@@ -186,12 +205,6 @@
     /** Can be set to true by tests to disable processing of requests. */
     private volatile boolean mRequestProcessingDisabled = false;
 
-    /**
-     * Whether to show the secondary action button used to play voicemail or show call details.
-     * True if created from a CallLogFragment.
-     * False if created from the PhoneFavoriteFragment. */
-    private boolean mShowSecondaryActionButton = true;
-
     private boolean mIsCallLog = true;
     private int mNumMissedCalls = 0;
     private int mNumMissedCallsShown = 0;
@@ -211,6 +224,35 @@
         }
     };
 
+    /**
+     * Click listener for the delete from call log button.  Removes the current call log
+     * entry and its associated calls from the call log.
+     */
+    private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            // Retrieve the views from the call log view.
+            final CallLogListItemViews views =
+                    (CallLogListItemViews)
+                            ((View)v.getParent().getParent().getParent().getParent()).getTag();
+
+            deleteCalls(views.callIds);
+            notifyDataSetChanged();
+        }
+    };
+
+    /**
+     * The onClickListener used to expand or collapse the action buttons section for a call log
+     * entry.
+     */
+    private final View.OnClickListener mExpandCollapseListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            expandOrCollapseActions((View) v.getParent().getParent());
+            notifyDataSetChanged();
+        }
+    };
+
     private void startActivityForAction(View view) {
         final IntentProvider intentProvider = (IntentProvider) view.getTag();
         if (intentProvider != null) {
@@ -251,14 +293,13 @@
     };
 
     public CallLogAdapter(Context context, CallFetcher callFetcher,
-            ContactInfoHelper contactInfoHelper, boolean showSecondaryActionButton,
+            ContactInfoHelper contactInfoHelper,
             boolean isCallLog) {
         super(context);
 
         mContext = context;
         mCallFetcher = callFetcher;
         mContactInfoHelper = contactInfoHelper;
-        mShowSecondaryActionButton = showSecondaryActionButton;
         mIsCallLog = isCallLog;
 
         mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
@@ -512,8 +553,6 @@
     private void findAndCacheViews(View view) {
         // Get the views to bind to.
         CallLogListItemViews views = CallLogListItemViews.fromView(view);
-        views.primaryActionView.setOnClickListener(mActionListener);
-        views.secondaryActionButtonView.setOnClickListener(mActionListener);
         view.setTag(views);
     }
 
@@ -537,36 +576,55 @@
         final long duration = c.getLong(CallLogQuery.DURATION);
         final int callType = c.getInt(CallLogQuery.CALL_TYPE);
         final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
+        final long rowId = c.getLong(CallLogQuery.ID);
+        views.rowId = rowId;
+
+        // Store some values used when the actions ViewStub is inflated on expansion of the actions
+        // section.
+        views.number = number;
+        views.numberPresentation = numberPresentation;
+        views.callType = callType;
+        views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
+        // Stash away the Ids of the calls so that we can support deleting a row in the call log.
+        views.callIds = getCallIds(c, rowId, count);
 
         final ContactInfo cachedContactInfo = getContactInfoFromCallLog(c);
 
         final boolean isVoicemailNumber =
                 PhoneNumberUtilsWrapper.INSTANCE.isVoicemailNumber(number);
 
-        // Primary action is always to call, if possible.
-        if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)) {
-            // Sets the primary action to call the number.
-            views.primaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
-        } else {
-            views.primaryActionView.setTag(null);
-        }
+        // Where binding and not in the call log, use default behaviour of invoking a call when
+        // tapping the primary view.
+        if (!mIsCallLog) {
+            views.primaryActionView.setOnClickListener(this.mActionListener);
 
-        if ( mShowSecondaryActionButton ) {
-            // Store away the voicemail information so we can play it directly.
-            if (callType == Calls.VOICEMAIL_TYPE) {
-                String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
-                final long rowId = c.getLong(CallLogQuery.ID);
-                views.secondaryActionButtonView.setTag(
-                        IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
+            // Set return call intent, otherwise null.
+            if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)) {
+                // Sets the primary action to call the number.
+                views.primaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
             } else {
-                // Store the call details information.
-                views.secondaryActionButtonView.setTag(
-                        IntentProvider.getCallDetailIntentProvider(
-                                getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
+                // Number is not callable, so hide button.
+                views.primaryActionView.setTag(null);
             }
         } else {
-            // No action enabled.
-            views.secondaryActionButtonView.setTag(null);
+            // In the call log, expand/collapse an actions section for the call log entry when
+            // the primary view is tapped.
+
+            // TODO: This needs to be changed to do the proper QP open/close animation.
+            views.primaryActionView.setOnClickListener(this.mExpandCollapseListener);
+
+            // Note: Binding of the action buttons is done as required in configureActionViews
+            // when the user expands the actions ViewStub.
+        }
+
+        // Restore expansion state of the row on rebind.  Inflate the actions ViewStub if required,
+        // and set its visibility state accordingly.
+        if (isExpanded(rowId)) {
+            // Inflate the view stub if necessary, and wire up the event handlers.
+            inflateActionViewStub(view);
+            views.actionsView.setVisibility(View.VISIBLE);
+        } else if (views.actionsView != null) {
+            views.actionsView.setVisibility(View.GONE);
         }
 
         // Lookup contacts with this number
@@ -631,8 +689,7 @@
         final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
         // New items also use the highlighted version of the text.
         final boolean isHighlighted = isNew;
-        mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted,
-                mShowSecondaryActionButton);
+        mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted);
 
         int contactType = ContactPhotoManager.TYPE_DEFAULT;
 
@@ -668,6 +725,130 @@
         bindBadge(view, info, details, callType);
     }
 
+    /**
+     * Determines if a call log row with the given Id is expanded to show the action buttons or
+     * not. If the row Id is not yet tracked, add a new entry assuming the row is collapsed.
+     * @param rowId
+     * @return
+     */
+    private boolean isExpanded(long rowId) {
+        if (!mIsExpanded.containsKey(rowId)) {
+            mIsExpanded.put(rowId, false);
+        }
+
+        return mIsExpanded.get(rowId);
+    }
+
+    /**
+     * Toggles the expansion state tracked for the call log row identified by rowId and returns
+     * the new expansion state.
+     *
+     * @param rowId The row Id associated with the call log row to expand/collapse.
+     * @return True where the row is now expanded, false otherwise.
+     */
+    private boolean toggleExpansion(long rowId) {
+        boolean isExpanded = isExpanded(rowId);
+
+        mIsExpanded.put(rowId, !isExpanded);
+        return !isExpanded;
+    }
+
+    /**
+     * Expands or collapses the view containing the CALLBACK, VOICEMAIL and DELETE action buttons.
+     *
+     * @param callLogItem The call log entry parent view.
+     */
+    private void expandOrCollapseActions(View callLogItem) {
+        final CallLogListItemViews views = (CallLogListItemViews)callLogItem.getTag();
+
+        // Hide or show the actions view.
+        boolean expanded = toggleExpansion(views.rowId);
+
+        // Inflate the view stub if necessary, and wire up the event handlers.
+        inflateActionViewStub(callLogItem);
+
+        if (expanded) {
+            views.actionsView.setVisibility(View.VISIBLE);
+
+            // Attempt to give accessibility focus to one of the action buttons.
+            // This ensures that a user realizes the expansion occurred.
+            // NOTE(tgunn): requestAccessibilityFocus returns true if the requested
+            // focus was successful.  The first successful focus will satisfy the OR
+            // block and block further attempts to set focus.
+            boolean focused = views.callBackButtonView.requestAccessibilityFocus() ||
+                    views.voicemailButtonView.requestAccessibilityFocus() ||
+                    views.deleteButtonView.requestAccessibilityFocus();
+        } else {
+            views.actionsView.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * Configures the action buttons in the expandable actions ViewStub.  The ViewStub is not
+     * inflated during initial binding, so click handlers, tags and accessibility text must be set
+     * here, if necessary.
+     *
+     * @param callLogItem The call log list item view.
+     */
+    private void inflateActionViewStub(View callLogItem) {
+        final CallLogListItemViews views = (CallLogListItemViews)callLogItem.getTag();
+
+        ViewStub stub = (ViewStub)callLogItem.findViewById(R.id.call_log_entry_actions_stub);
+        if (stub != null) {
+            views.actionsView = stub.inflate();
+        }
+
+        if (views.callBackButtonView == null) {
+            views.callBackButtonView = (TextView)views.actionsView.findViewById(R.id.call_back_action);
+        }
+
+        if (views.voicemailButtonView == null) {
+            views.voicemailButtonView = (TextView)views.actionsView.findViewById(R.id.voicemail_action);
+        }
+
+        if ( views.deleteButtonView == null) {
+            views.deleteButtonView = (TextView)views.actionsView.findViewById(R.id.delete_action);
+        }
+
+        bindActionButtons(views);
+    }
+
+    /***
+     * Binds click handlers and intents to the voicemail, delete and callback action buttons.
+     *
+     * @param views  The call log item views.
+     */
+    private void bindActionButtons(CallLogListItemViews views) {
+        // Set return call intent, otherwise null.
+        if (PhoneNumberUtilsWrapper.canPlaceCallsTo(views.number, views.numberPresentation)) {
+            // Sets the primary action to call the number.
+            views.callBackButtonView.setTag(
+                    IntentProvider.getReturnCallIntentProvider(views.number));
+            views.callBackButtonView.setVisibility(View.VISIBLE);
+            views.callBackButtonView.setOnClickListener(mActionListener);
+        } else {
+            // Number is not callable, so hide button.
+            views.callBackButtonView.setTag(null);
+            views.callBackButtonView.setVisibility(View.GONE);
+        }
+
+        // For voicemail calls, show the "VOICEMAIL" action button; hide otherwise.
+        if (views.callType == Calls.VOICEMAIL_TYPE) {
+            views.voicemailButtonView.setOnClickListener(mActionListener);
+            views.voicemailButtonView.setTag(
+                    IntentProvider.getPlayVoicemailIntentProvider(
+                            views.rowId, views.voicemailUri));
+            views.voicemailButtonView.setVisibility(View.VISIBLE);
+        } else {
+            views.voicemailButtonView.setTag(null);
+            views.voicemailButtonView.setVisibility(View.GONE);
+        }
+
+        views.deleteButtonView.setOnClickListener(this.mDeleteListener);
+
+        mCallLogViewsHelper.setActionContentDescriptions(views);
+    }
+
     protected void bindBadge(View view, ContactInfo info, PhoneCallDetails details, int callType) {
 
         // Do not show badge in call log.
@@ -960,4 +1141,76 @@
         }
         return number;
     }
+
+    /**
+     * Retrieves the call Ids represented by the current call log row.
+     *
+     * @param cursor Call log cursor to retrieve call Ids from.
+     * @param id Id of the first call of the grouping.
+     * @param groupSize Number of calls associated with the current call log row.
+     * @return Array of call Ids.
+     */
+    private long[] getCallIds(final Cursor cursor, final long id, final int groupSize) {
+        // We want to restore the position in the cursor at the end.
+        int startingPosition = cursor.getPosition();
+        long[] ids = new long[groupSize];
+        // Copy the ids of the rows in the group.
+        for (int index = 0; index < groupSize; ++index) {
+            ids[index] = cursor.getLong(CallLogQuery.ID);
+            cursor.moveToNext();
+        }
+        cursor.moveToPosition(startingPosition);
+        return ids;
+    }
+
+    /**
+     * Retrieves an instance of the asynchronous task executor, creating one if required.
+     * @return The {@link com.android.dialer.util.AsyncTaskExecutor}
+     */
+    private AsyncTaskExecutor getTaskExecutor() {
+        if (mAsyncTaskExecutor == null) {
+            mAsyncTaskExecutor = AsyncTaskExecutors.createAsyncTaskExecutor();
+        }
+        return mAsyncTaskExecutor;
+    }
+
+    /**
+     * Deletes the calls specified in the callIds array, asynchronously.
+     *
+     * @param callIds Ids of calls to be deleted.
+     */
+    private void deleteCalls(long[] callIds) {
+        if (callIds == null) {
+            return;
+        }
+
+        // Build comma separated list of ids to delete.
+        final StringBuilder callIdString = new StringBuilder();
+        for (long callId : callIds) {
+            if (callIdString.length() != 0) {
+                callIdString.append(",");
+            }
+            callIdString.append(callId);
+        }
+
+        // Perform removal of call log entries asynchronously.
+        getTaskExecutor().submit(Tasks.REMOVE_CALL_LOG_ENTRIES,
+                new AsyncTask<Void, Void, Void>() {
+                    @Override
+                    public Void doInBackground(Void... params) {
+                        // Issue delete.
+                        mContext.getContentResolver().delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
+                                Calls._ID + " IN (" + callIdString + ")", null);
+                        return null;
+                    }
+
+                    @Override
+                    public void onPostExecute(Void result) {
+                        // Somewhere went wrong: we're going to bail out and show error to users.
+                        Toast.makeText(mContext, R.string.toast_entry_removed,
+                                Toast.LENGTH_SHORT).show();
+                    }
+                }
+        );
+    }
 }
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index 2ab6136..0948151 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -154,7 +154,7 @@
 
         String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
         mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(
-                getActivity(), currentCountryIso), true, true);
+                getActivity(), currentCountryIso), true);
         setListAdapter(mAdapter);
         mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(),
                 this, mLogLimit);
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index a85cd01..81d1a27 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -25,6 +25,7 @@
 import com.android.dialer.PhoneCallDetails;
 import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
+import com.android.internal.util.CharSequences;
 
 /**
  * Helper class to fill in the views of a call log entry.
@@ -56,13 +57,11 @@
      * @param views the views to populate
      * @param details the details of a phone call needed to fill in the data
      * @param isHighlighted whether to use the highlight text for the call
-     * @param showSecondaryActionButton whether to show the secondary action button or not
      */
     public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
-            boolean isHighlighted, boolean showSecondaryActionButton) {
+            boolean isHighlighted) {
         mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details,
                 isHighlighted);
-        boolean canPlay = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
 
         // Set the accessibility text for the contact badge
         views.quickContactView.setContentDescription(getContactBadgeDescription(details));
@@ -70,35 +69,25 @@
         // Set the primary action accessibility description
         views.primaryActionView.setContentDescription(getCallDescription(details));
 
-        // If secondary action is visible, either show voicemail playback icon, or
-        // show the "clock" icon corresponding to the call details screen.
-        if (showSecondaryActionButton) {
-            if (canPlay) {
-                // Playback action takes preference.
-                configurePlaySecondaryAction(views, isHighlighted);
-            } else {
-                // Call details is the secondary action.
-                configureCallDetailsSecondaryAction(views, details);
-            }
-        } else {
-            // No secondary action is to be shown (ie this is likely a PhoneFavoriteFragment)
-            views.secondaryActionView.setVisibility(View.GONE);
-        }
+        // Cache name or number of caller.  Used when setting the content descriptions of buttons
+        // when the actions ViewStub is inflated.
+        views.nameOrNumber = this.getNameOrNumber(details);
     }
 
     /**
-     * Sets the secondary action to invoke call details.
+     * Sets the accessibility descriptions for the action buttons in the action button ViewStub.
      *
-     * @param views   the views to populate
-     * @param details the details of a phone call needed to fill in the call details data
+     * @param views The views associated with the current call log entry.
      */
-    private void configureCallDetailsSecondaryAction(CallLogListItemViews views,
-            PhoneCallDetails details) {
-        views.secondaryActionView.setVisibility(View.VISIBLE);
-        // Use the small dark grey clock icon.
-        views.secondaryActionButtonView.setImageResource(R.drawable.ic_menu_history_dk);
-        views.secondaryActionButtonView.setContentDescription(
-                mResources.getString(R.string.description_call_details));
+    public void setActionContentDescriptions(CallLogListItemViews views) {
+        views.callBackButtonView.setContentDescription(
+                mResources.getString(R.string.description_call_back_action, views.nameOrNumber));
+
+        views.voicemailButtonView.setContentDescription(
+                mResources.getString(R.string.description_voicemail_action, views.nameOrNumber));
+
+        views.deleteButtonView.setContentDescription(
+                mResources.getString(R.string.description_delete_action, views.nameOrNumber));
     }
 
     /**
@@ -123,16 +112,11 @@
      *
      * The {Caller Information} references the most recent call associated with the caller.
      * For incoming calls:
-     * If missed call:  Return missed call from {Name/Number} {Call Type} {Call Time}.
-     * If answered call: Return answered call from {Name/Number} {Call Type} {Call Time}.
-     *
-     * For unknown callers, drop the "Return" part, since the call can't be returned:
-     * If answered unknown: Answered call from {Name/Number} {Call Time}.
-     * If missed unknown: Missed call from {Name/Number} {Call Time}.
+     * If missed call:  Missed call from {Name/Number} {Call Type} {Call Time}.
+     * If answered call: Answered call from {Name/Number} {Call Type} {Call Time}.
      *
      * For outgoing calls:
-     * If outgoing:  Call {Name/Number] {Call Type}.  {Last} called {Call Time}.
-     * Where {Last} is dropped if the number of calls for the caller is 1.
+     * If outgoing:  Call to {Name/Number] {Call Type} {Call Time}.
      *
      * Where:
      * {Name/Number} is the name or number of the caller (as shown in call log).
@@ -140,8 +124,8 @@
      * {Call Time} is the time since the last call for the contact occurred.
      *
      * Examples:
-     * 3 calls.  New Voicemail.  Return missed call from Joe Smith mobile 2 hours ago.
-     * 2 calls.  Call John Doe mobile.  Last called 1 hour ago.
+     * 3 calls.  New Voicemail.  Missed call from Joe Smith mobile 2 hours ago.
+     * 2 calls.  Answered call from John Doe mobile.  Last called 1 hour ago.
      * @param details Details of call.
      * @return Return call action description.
      */
@@ -191,43 +175,17 @@
      */
     public int getCallDescriptionStringID(PhoneCallDetails details) {
         int lastCallType = getLastCallType(details.callTypes);
-        boolean isNumberCallable = PhoneNumberUtilsWrapper.canPlaceCallsTo(details.number,
-                details.numberPresentation);
+        int stringID;
 
-        // Default string to use is "call XYZ..." just in case we manage to fall through.
-        int stringID = R.string.description_call_last_multiple;
-
-        if (!isNumberCallable) {
-            // Number isn't callable; this is an incoming call from an unknown caller.
-            // An uncallable outgoing call wouldn't be in the call log.
-
-            // Voicemail and missed calls are both considered missed.
-            if (lastCallType == Calls.VOICEMAIL_TYPE ||
-                    lastCallType == Calls.MISSED_TYPE) {
-                stringID = R.string.description_unknown_missed_call;
-            } else if (lastCallType == Calls.INCOMING_TYPE) {
-                stringID = R.string.description_unknown_answered_call;
-            }
+        if (lastCallType == Calls.VOICEMAIL_TYPE || lastCallType == Calls.MISSED_TYPE) {
+            //Message: Missed call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>.
+            stringID = R.string.description_incoming_missed_call;
+        } else if (lastCallType == Calls.INCOMING_TYPE) {
+            //Message: Answered call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>.
+            stringID = R.string.description_incoming_answered_call;
         } else {
-            // Known caller, so callable.
-
-            // Missed call (ie voicemail or missed)
-            if (lastCallType == Calls.VOICEMAIL_TYPE ||
-                    lastCallType == Calls.MISSED_TYPE) {
-                stringID = R.string.description_return_missed_call;
-            } else if (lastCallType == Calls.INCOMING_TYPE) {
-                // Incoming answered.
-                stringID = R.string.description_return_answered_call;
-            } else {
-                // Outgoing call.
-
-                // If we have a history of multiple calls
-                if (details.callTypes.length > 1) {
-                    stringID = R.string.description_call_last_multiple;
-                } else {
-                    stringID = R.string.description_call_last;
-                }
-            }
+            //Message: Call to <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>.
+            stringID = R.string.description_outgoing_call;
         }
         return stringID;
     }
@@ -260,13 +218,4 @@
         }
         return recipient;
     }
-
-    /** Sets the secondary action to correspond to the play button. */
-    private void configurePlaySecondaryAction(CallLogListItemViews views, boolean isHighlighted) {
-        views.secondaryActionView.setVisibility(View.VISIBLE);
-        views.secondaryActionButtonView.setImageResource(
-                isHighlighted ? R.drawable.ic_play_active_holo_dark : R.drawable.ic_play_holo_light);
-        views.secondaryActionButtonView.setContentDescription(
-                mResources.getString(R.string.description_call_log_play_button));
-    }
 }
diff --git a/src/com/android/dialer/calllog/CallLogListItemViews.java b/src/com/android/dialer/calllog/CallLogListItemViews.java
index a378956..879647f 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViews.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViews.java
@@ -34,25 +34,67 @@
     public final QuickContactBadge quickContactView;
     /** The primary action view of the entry. */
     public final View primaryActionView;
-    /** The secondary action view, which includes both the vertical divider line and
-     *  the action button itself.  Used so that the button and divider line can be
-     *  made visible/hidden as a whole. */
-    public final View secondaryActionView;
-    /** The secondary action button on the entry. */
-    public final ImageView secondaryActionButtonView;
     /** The details of the phone call. */
     public final PhoneCallDetailsViews phoneCallDetailsViews;
     /** The text of the header of a section. */
     public final TextView listHeaderTextView;
+    /** The view containing call log item actions.  Null until the ViewStub is inflated. */
+    public View actionsView;
+    /** The "call back" action button - assigned only when the action section is expanded. */
+    public TextView callBackButtonView;
+    /** The "delete" action button - assigned only when the action section is expanded. */
+    public TextView deleteButtonView;
+    /** The "voicemail" action button - assigned only when the action section is expanded. */
+    public TextView voicemailButtonView;
+
+    /**
+     * The row Id for the first call associated with the call log entry.  Used as a key for the
+     * map used to track which call log entries have the action button section expanded.
+     */
+    public long rowId;
+
+    /**
+     * The call Ids for the calls represented by the current call log entry.  Used when the user
+     * deletes a call log entry.
+     */
+    public long[] callIds;
+
+    /**
+     * The callable phone number for the current call log entry.  Cached here as the call back
+     * intent is set only when the actions ViewStub is inflated.
+     */
+    public String number;
+
+    /**
+     * The phone number presentation for the current call log entry.  Cached here as the call back
+     * intent is set only when the actions ViewStub is inflated.
+     */
+    public int numberPresentation;
+
+    /**
+     * The type of call for the current call log entry.  Cached here as the call back
+     * intent is set only when the actions ViewStub is inflated.
+     */
+    public int callType;
+
+    /**
+     * If the call has an associated voicemail message, the URI of the voicemail message for
+     * playback.  Cached here as the voicemail intent is only set when the actions ViewStub is
+     * inflated.
+     */
+    public String voicemailUri;
+
+    /**
+     * The name or number associated with the call.  Cached here for use when setting content
+     * descriptions on buttons in the actions ViewStub when it is inflated.
+     */
+    public CharSequence nameOrNumber;
 
     private CallLogListItemViews(QuickContactBadge quickContactView, View primaryActionView,
-            View secondaryActionView, ImageView secondaryActionButtonView,
             PhoneCallDetailsViews phoneCallDetailsViews,
             TextView listHeaderTextView) {
         this.quickContactView = quickContactView;
         this.primaryActionView = primaryActionView;
-        this.secondaryActionView = secondaryActionView;
-        this.secondaryActionButtonView = secondaryActionButtonView;
         this.phoneCallDetailsViews = phoneCallDetailsViews;
         this.listHeaderTextView = listHeaderTextView;
     }
@@ -61,8 +103,6 @@
         return new CallLogListItemViews(
                 (QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
                 view.findViewById(R.id.primary_action_view),
-                view.findViewById(R.id.secondary_action_view),
-                (ImageView) view.findViewById(R.id.secondary_action_icon),
                 PhoneCallDetailsViews.fromView(view),
                 (TextView) view.findViewById(R.id.call_log_header));
     }
@@ -72,8 +112,6 @@
         return new CallLogListItemViews(
                 new QuickContactBadge(context),
                 new View(context),
-                new View(context),
-                new ImageView(context),
                 PhoneCallDetailsViews.createForTest(context),
                 new TextView(context));
     }
diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java
index 49d6b3a..88e5ce0 100644
--- a/src/com/android/dialer/list/ListsFragment.java
+++ b/src/com/android/dialer/list/ListsFragment.java
@@ -177,7 +177,7 @@
                 this, 1);
         final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
         mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this,
-                new ContactInfoHelper(getActivity(), currentCountryIso), false, false);
+                new ContactInfoHelper(getActivity(), currentCountryIso), false);
 
         mMergedAdapter = new ShortcutCardsAdapter(getActivity(), this, mCallLogAdapter);
     }
diff --git a/src/com/android/dialerbind/ObjectFactory.java b/src/com/android/dialerbind/ObjectFactory.java
index be91e33..e7ca8d9 100644
--- a/src/com/android/dialerbind/ObjectFactory.java
+++ b/src/com/android/dialerbind/ObjectFactory.java
@@ -39,15 +39,11 @@
      * @param context The context to use.
      * @param callFetcher Instance of call fetcher to use.
      * @param contactInfoHelper Instance of contact info helper class to use.
-     * @param hideSecondaryAction If true, secondary action will be hidden (ie call details
-     *                            or play voicemail).
      * @param isCallLog Is this call log adapter being used on the call log?
      * @return Instance of CallLogAdapter.
      */
     public static CallLogAdapter newCallLogAdapter(Context context, CallFetcher callFetcher,
-            ContactInfoHelper contactInfoHelper, boolean hideSecondaryAction,
-            boolean isCallLog) {
-        return new CallLogAdapter(context, callFetcher, contactInfoHelper, hideSecondaryAction,
-                isCallLog);
+            ContactInfoHelper contactInfoHelper, boolean isCallLog) {
+        return new CallLogAdapter(context, callFetcher, contactInfoHelper, isCallLog);
     }
 }
diff --git a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
index 9b7d9de..626ff16 100644
--- a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
@@ -22,6 +22,7 @@
 import android.test.AndroidTestCase;
 import android.text.Html;
 import android.text.Spanned;
+import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
 
@@ -111,9 +112,9 @@
     public void testSetPhoneCallDetails_Normal() {
         setPhoneCallDetailsWithNumber("14125551212",
                 Calls.PRESENTATION_ALLOWED, "1-412-555-1212");
-        assertEquals("Yesterday", mViews.callTypeAndDate.getText().toString());
-        assertEqualsHtml("<font color='#33b5e5'><b>Yesterday</b></font>",
-                mViews.callTypeAndDate.getText());
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains("Yesterday"));
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains(
+                "<font color='#33b5e5'><b>Yesterday</b></font>"));
     }
 
     /** Asserts that a char sequence is actually a Spanned corresponding to the expected HTML. */
@@ -252,12 +253,12 @@
 
     /** Asserts that the label text field contains the given string value. */
     private void assertLabelEquals(String text) {
-        assertEquals(text, mViews.labelView.getText().toString());
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains(text));
     }
 
     /** Asserts that the date text field contains the given string value. */
     private void assertDateEquals(String text) {
-        assertEquals(text, mViews.callTypeAndDate.getText().toString());
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains(text));
     }
 
     /** Asserts that the call type contains the images with the given drawables. */
@@ -268,7 +269,7 @@
             assertEquals(id, mViews.callTypeIcons.getCallType(index));
         }
         assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
-        assertEquals("Yesterday", mViews.callTypeAndDate.getText().toString());
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains("Yesterday"));
     }
 
     /**
@@ -282,7 +283,8 @@
             assertEquals(id, mViews.callTypeIcons.getCallType(index));
         }
         assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
-        assertEquals(overflowText + " Yesterday", mViews.callTypeAndDate.getText().toString());
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains(overflowText));
+        assertTrue(mViews.callLocationAndDate.getText().toString().contains("Yesterday"));
     }
 
     /** Sets the phone call details with default values and the given number. */
diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index 12cdb2b..55e4224 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -212,7 +212,7 @@
 
         public TestCallLogAdapter(Context context, CallFetcher callFetcher,
                 ContactInfoHelper contactInfoHelper) {
-            super(context, callFetcher, contactInfoHelper, false, false);
+            super(context, callFetcher, contactInfoHelper, false);
         }
 
         @Override
diff --git a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java b/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
index 25f5379..a423cde 100644
--- a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
@@ -35,6 +35,7 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
 import android.view.View;
 import android.widget.FrameLayout;
 
@@ -174,7 +175,6 @@
         insertPrivate(NOW, 0);
         View view = mAdapter.newGroupView(getActivity(), mParentView);
         mAdapter.bindGroupView(view, getActivity(), mCursor, 3, false);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -183,7 +183,6 @@
         insertPrivate(NOW, 0);
         View view = mAdapter.newStandAloneView(getActivity(), mParentView);
         mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -192,7 +191,6 @@
         insertPrivate(NOW, 0);
         View view = mAdapter.newChildView(getActivity(), mParentView);
         mAdapter.bindChildView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
     }
 
     @MediumTest
@@ -328,7 +326,7 @@
         // {@link com.android.dialer.calllog.CallLogAdapter#bindView} method.  If it is possible
         // to place a call to the phone number, a call intent will have been created for the
         // primaryActionView.
-        IntentProvider intentProvider = (IntentProvider) views.primaryActionView.getTag();
+        IntentProvider intentProvider = (IntentProvider) views.callBackButtonView.getTag();
         Intent intent = intentProvider.getIntent(mActivity);
         // Starts a call.
         assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
@@ -344,7 +342,7 @@
         mAdapter.bindStandAloneView(view, getActivity(), mCursor);
 
         CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        IntentProvider intentProvider = (IntentProvider) views.secondaryActionButtonView.getTag();
+        IntentProvider intentProvider = (IntentProvider) views.voicemailButtonView.getTag();
         Intent intent = intentProvider.getIntent(mActivity);
         // Starts the call detail activity.
         assertEquals(new ComponentName(mActivity, CallDetailActivity.class),
@@ -384,12 +382,12 @@
             if (presentation == Calls.PRESENTATION_RESTRICTED ||
                     presentation == Calls.PRESENTATION_UNKNOWN) {
                 //If number is not callable, the primary action view should have a null tag.
-                assertNull(mItem.primaryActionView.getTag());
+                assertNull(mItem.callBackButtonView.getTag());
             } else {
                 //If the number is callable, the primary action view should have a non-null tag.
-                assertNotNull(mItem.primaryActionView.getTag());
+                assertNotNull(mItem.callBackButtonView.getTag());
 
-                IntentProvider intentProvider = (IntentProvider)mItem.primaryActionView.getTag();
+                IntentProvider intentProvider = (IntentProvider)mItem.callBackButtonView.getTag();
                 Intent callIntent = intentProvider.getIntent(mActivity);
 
                 //The intent should be to make the call
@@ -650,10 +648,9 @@
     /** Asserts that the label text view contains the given text. */
     private void assertLabel(CallLogListItemViews views, CharSequence number,
             CharSequence label) {
-        assertEquals(label == null ? View.GONE : View.VISIBLE,
-                views.phoneCallDetailsViews.labelView.getVisibility());
         if (label != null) {
-            assertEquals(label, views.phoneCallDetailsViews.labelView.getText().toString());
+            assertTrue(views.phoneCallDetailsViews.callLocationAndDate.getText().toString()
+                    .contains(label));
         }
     }
 }
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index 7e4736e..15c1676 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -81,13 +81,7 @@
     public void testSetPhoneCallDetails() {
         setPhoneCallDetailsWithNumber("12125551234", Calls.PRESENTATION_ALLOWED,
                 "1-212-555-1234");
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetailsInFavorites() {
-        setPhoneCallDetailsWithNumberInFavorites("12125551234", Calls.PRESENTATION_ALLOWED,
-                "1-212-555-1234");
-        assertNoCallIntent();
+        assertEquals(View.VISIBLE, mViews.callBackButtonView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_Unknown() {
@@ -95,73 +89,36 @@
         assertNoCallIntent();
     }
 
-    public void testSetPhoneCallDetailsInFavorites_Unknown() {
-        setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_UNKNOWN, "");
-        assertNoCallIntent();
-    }
-
     public void testSetPhoneCallDetails_Private() {
         setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_RESTRICTED, "");
         assertNoCallIntent();
     }
 
-    public void testSetPhoneCallDetailsInFavorites_Private() {
-        setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_RESTRICTED, "");
-        assertNoCallIntent();
-    }
-
     public void testSetPhoneCallDetails_Payphone() {
         setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_PAYPHONE, "");
         assertNoCallIntent();
     }
 
-    public void testSetPhoneCallDetailsInFavorites_Payphone() {
-        setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_PAYPHONE, "");
-        assertNoCallIntent();
-    }
-
     public void testSetPhoneCallDetails_VoicemailNumber() {
         setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER,
                 Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.voicemailButtonView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_ReadVoicemail() {
         setPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.voicemailButtonView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_UnreadVoicemail() {
         setUnreadPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.voicemailButtonView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_VoicemailFromUnknown() {
         setPhoneCallDetailsWithNumberAndType("", Calls.PRESENTATION_UNKNOWN,
                 "", Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetailsInFavorites_VoicemailNumber() {
-        setPhoneCallDetailsWithNumberInFavorites(TEST_VOICEMAIL_NUMBER,
-                Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
-        assertNoCallIntent();
-    }
-
-    public void testSetPhoneCallDetailsInFavorites_ReadVoicemail() {
-        setPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetailsInFavorites_UnreadVoicemail() {
-        setUnreadPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetailsInFavorites_VoicemailFromUnknown() {
-        setPhoneCallDetailsWithNumberAndTypeInFavorites("", Calls.PRESENTATION_UNKNOWN,
-                "", Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
+        assertEquals(View.VISIBLE, mViews.voicemailButtonView.getVisibility());
     }
 
     /**
@@ -172,7 +129,7 @@
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_unknown_answered_call,
+        assertEquals(R.string.description_incoming_answered_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -184,7 +141,7 @@
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_unknown_missed_call,
+        assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -196,7 +153,7 @@
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_unknown_missed_call,
+        assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -209,7 +166,7 @@
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_return_answered_call,
+        assertEquals(R.string.description_incoming_answered_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -222,7 +179,7 @@
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_return_missed_call,
+        assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -235,7 +192,7 @@
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_return_missed_call,
+        assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -249,7 +206,7 @@
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_call_last,
+        assertEquals(R.string.description_outgoing_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -263,7 +220,7 @@
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
                 new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
-        assertEquals(R.string.description_call_last_multiple,
+        assertEquals(R.string.description_outgoing_call,
                 mHelper.getCallDescriptionStringID(details));
     }
 
@@ -370,13 +327,6 @@
                 formattedNumber, Calls.INCOMING_TYPE);
     }
 
-    /** Sets the details of a phone call in the favorite screen using the specified phone number. */
-    private void setPhoneCallDetailsWithNumberInFavorites(String number,
-            int presentation, String formattedNumber) {
-        setPhoneCallDetailsWithNumberAndTypeInFavorites(number, presentation,
-                formattedNumber, Calls.INCOMING_TYPE);
-    }
-
     /** Sets the details of a phone call using the specified phone number. */
     private void setPhoneCallDetailsWithNumberAndType(String number,
             int presentation, String formattedNumber, int callType) {
@@ -384,17 +334,7 @@
                 new PhoneCallDetails(number, presentation, formattedNumber,
                         TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ callType }, TEST_DATE, TEST_DURATION),
-                false, false);
-    }
-
-    /** Sets the details of a phone call in the favorite screen using the specified phone number. */
-    private void setPhoneCallDetailsWithNumberAndTypeInFavorites(String number,
-            int presentation, String formattedNumber, int callType) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, presentation, formattedNumber,
-                        TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        new int[]{ callType }, TEST_DATE, TEST_DURATION),
-                false, true);
+                false);
     }
 
     /** Sets the details of a phone call using the specified call type. */
@@ -403,16 +343,7 @@
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         types, TEST_DATE, TEST_DURATION),
-                false, false);
-    }
-
-    /** Sets the details of a phone call in the favorite screen using the specified call type. */
-    private void setPhoneCallDetailsWithTypesInFavorites(int... types) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
-                        TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        types, TEST_DATE, TEST_DURATION),
-                false, true);
+                false);
     }
 
     /** Sets the details of an unread phone call using the specified call type. */
@@ -421,17 +352,6 @@
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         types, TEST_DATE, TEST_DURATION),
-                true, false);
-    }
-
-    /** Sets the details of an unread phone call in the favorite screen using the specified call
-     * type.
-     */
-    private void setUnreadPhoneCallDetailsWithTypesInFavorites(int... types) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
-                        TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        types, TEST_DATE, TEST_DURATION),
-                true, true);
+                true);
     }
 }