Add voicemail transcriptions to Dialer

* Display voicemail transcriptions in the call log and call details
activity in the Dialer
* Fix a bug in CallDetailActivity that would result in multiple instances of    VoicemailPlaybackFragment being added on rotation. Now, reuse the same fragment
if it is already present in the FragmentManager, to avoid creating new ones
* Simplify some test and ctor logic in PhoneCallDetails to reduce the pain
of adding new fields into PhoneCallDetails
* Simplified playback_layout.xml to remove unnecessary parent LinearLayouts

Bug: 16320164

Change-Id: Ie68acc9058aace49d8e64f44a0128de0b6a3f842
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
index 9ca30a8..f08531b 100644
--- a/res/layout/call_detail.xml
+++ b/res/layout/call_detail.xml
@@ -15,17 +15,16 @@
 -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent" >
 
     <LinearLayout
         android:id="@+id/call_detail"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
-        android:background="@color/background_dialer_list_items"
         android:layout_alignParentStart="true"
         android:layout_alignParentTop="true"
-    >
+        android:background="@color/background_dialer_list_items" >
         <!-- Caller information "card" -->
         <LinearLayout
             android:id="@+id/caller_information"
@@ -39,7 +38,7 @@
             android:gravity="center_vertical"
             android:translationZ="@dimen/call_detail_translation_z"
             android:focusable="true"
-            android:background="@color/background_dialer_white">
+            android:background="@color/background_dialer_white" >
 
             <QuickContactBadge
                 android:id="@+id/quick_contact_photo"
@@ -85,11 +84,20 @@
             >
             <include layout="@layout/call_log_voicemail_status"/>
         </FrameLayout>
+        <TextView
+            android:id="@+id/voicemail_transcription"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingStart="@dimen/call_detail_horizontal_margin"
+            android:paddingEnd="@dimen/call_detail_horizontal_margin"
+            android:paddingTop="@dimen/transcription_top_margin"
+            android:paddingBottom="@dimen/transcription_bottom_margin"
+            android:background="@color/background_dialer_list_items" />
         <LinearLayout
             android:id="@+id/voicemail_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
+            android:orientation="vertical"
             android:paddingBottom="@dimen/call_detail_button_spacing"
             android:visibility="gone"
             >
diff --git a/res/layout/call_detail_history_item.xml b/res/layout/call_detail_history_item.xml
index cc06d21..0e5dcf2 100644
--- a/res/layout/call_detail_history_item.xml
+++ b/res/layout/call_detail_history_item.xml
@@ -23,41 +23,35 @@
     android:paddingStart="@dimen/call_detail_horizontal_margin"
     android:paddingEnd="@dimen/call_log_outer_margin"
     android:orientation="vertical"
-    android:background="@color/background_dialer_list_items"
->
+    android:background="@color/background_dialer_list_items" >
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-    >
+        android:orientation="horizontal" >
         <view
             class="com.android.dialer.calllog.CallTypeIconsView"
             android:id="@+id/call_type_icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-        />
+            android:layout_gravity="center_vertical" />
         <TextView
             android:id="@+id/call_type_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/call_log_icon_margin"
             android:textColor="?attr/call_log_primary_text_color"
-            android:textSize="@dimen/call_log_primary_text_size"
-        />
+            android:textSize="@dimen/call_log_primary_text_size" />
     </LinearLayout>
     <TextView
         android:id="@+id/date"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textColor="?attr/call_log_secondary_text_color"
-        android:textSize="@dimen/call_log_secondary_text_size"
-    />
+        android:textSize="@dimen/call_log_secondary_text_size" />
     <TextView
         android:id="@+id/duration"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textColor="?attr/call_log_secondary_text_color"
-        android:textSize="@dimen/call_log_secondary_text_size"
-    />
+        android:textSize="@dimen/call_log_secondary_text_size" />
 </LinearLayout>
diff --git a/res/layout/playback_layout.xml b/res/layout/playback_layout.xml
index 2f4d33c..500ed96 100644
--- a/res/layout/playback_layout.xml
+++ b/res/layout/playback_layout.xml
@@ -14,10 +14,11 @@
      limitations under the License.
 -->
 
-<RelativeLayout
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:orientation="vertical"
     android:background="@color/background_dialer_list_items"
 >
     <!-- Mute, playback, trash buttons. -->
@@ -26,44 +27,31 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        android:layout_alignParentTop="true"
     >
-        <LinearLayout
+        <ImageButton
+            android:id="@+id/playback_start_stop"
             android:layout_width="match_parent"
-            android:layout_height="58dip"
+            android:layout_height="58dp"
             android:layout_marginEnd="@dimen/call_detail_button_spacing"
             android:layout_weight="1"
-        >
-            <ImageButton
-                android:id="@+id/playback_start_stop"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:background="?android:attr/selectableItemBackground"
-                android:src="@drawable/ic_hold_pause"
-                android:contentDescription="@string/voicemail_play_start_pause"
-            />
-        </LinearLayout>
-        <LinearLayout
+            android:background="?android:attr/selectableItemBackground"
+            android:src="@drawable/ic_hold_pause"
+            android:contentDescription="@string/voicemail_play_start_pause"
+        />
+        <ImageButton
+            android:id="@+id/playback_speakerphone"
             android:layout_width="match_parent"
             android:layout_height="58dip"
             android:layout_weight="1"
-            android:background="@color/background_dialer_list_items"
-        >
-            <ImageButton
-                android:id="@+id/playback_speakerphone"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:background="?android:attr/selectableItemBackground"
-                android:src="@drawable/ic_speakerphone_on"
-                android:contentDescription="@string/description_playback_speakerphone"
-            />
-        </LinearLayout>
+            android:background="?android:attr/selectableItemBackground"
+            android:src="@drawable/ic_speakerphone_on"
+            android:contentDescription="@string/description_playback_speakerphone"
+        />
     </LinearLayout>
     <RelativeLayout
         android:id="@+id/seek_container"
         android:layout_width="match_parent"
         android:layout_height="80dip"
-        android:layout_below="@id/buttons_linear_layout"
         android:layout_marginTop="@dimen/call_detail_button_spacing"
     >
         <!-- SeekBar left-right margin decreased from redlines 72dip by 8dip to account for
@@ -137,4 +125,4 @@
             android:layout_height="2dp"
             android:layout_alignParentBottom="true"/>
     </RelativeLayout>
-</RelativeLayout>
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b7aceef..176680e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -40,6 +40,8 @@
     <dimen name="call_detail_bottom_margin">32dp</dimen>
     <dimen name="call_detail_header_top_margin">24dp</dimen>
     <dimen name="call_detail_translation_z">0.5dp</dimen>
+    <dimen name="transcription_top_margin">18dp</dimen>
+    <dimen name="transcription_bottom_margin">18dp</dimen>
 
     <!-- Size of call provider icon width and height -->
     <dimen name="call_provider_small_icon_size">12dp</dimen>
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index 42e4659..cd5fb3b 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -32,6 +32,7 @@
 import android.provider.CallLog;
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.VoicemailContract;
 import android.provider.VoicemailContract.Voicemails;
 import android.telecomm.PhoneAccount;
 import android.telecomm.TelecommManager;
@@ -107,6 +108,8 @@
     /** If the activity was triggered from a notification. */
     public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
 
+    public static final String VOICEMAIL_FRAGMENT_TAG = "voicemail_fragment";
+
     private CallTypeHelper mCallTypeHelper;
     private PhoneNumberDisplayHelper mPhoneNumberHelper;
     private QuickContactBadge mQuickContactBadge;
@@ -130,6 +133,7 @@
     private View mStatusMessageView;
     private TextView mStatusMessageText;
     private TextView mStatusMessageAction;
+    private TextView mVoicemailTranscription;
 
     /** Whether we should show "edit number before call" in the options menu. */
     private boolean mHasEditNumberBeforeCallOption;
@@ -203,7 +207,8 @@
         CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME,
         CallLog.Calls.PHONE_ACCOUNT_ID,
         CallLog.Calls.FEATURES,
-        CallLog.Calls.DATA_USAGE
+        CallLog.Calls.DATA_USAGE,
+        CallLog.Calls.TRANSCRIPTION
     };
 
     static final int DATE_COLUMN_INDEX = 0;
@@ -217,6 +222,7 @@
     static final int ACCOUNT_ID = 8;
     static final int FEATURES = 9;
     static final int DATA_USAGE = 10;
+    static final int TRANSCRIPTION_COLUMN_INDEX = 11;
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -235,6 +241,7 @@
         mStatusMessageView = findViewById(R.id.voicemail_status);
         mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message);
         mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action);
+        mVoicemailTranscription = (TextView) findViewById(R.id.voicemail_transcription);
         mQuickContactBadge = (QuickContactBadge) findViewById(R.id.quick_contact_photo);
         mQuickContactBadge.setOverlay(null);
         mCallerName = (TextView) findViewById(R.id.caller_name);
@@ -268,17 +275,25 @@
             // Has voicemail: add the voicemail fragment.  Add suitable arguments to set the uri
             // to play and optionally start the playback.
             // Do a query to fetch the voicemail status messages.
-            VoicemailPlaybackFragment playbackFragment = new VoicemailPlaybackFragment();
-            Bundle fragmentArguments = new Bundle();
-            fragmentArguments.putParcelable(EXTRA_VOICEMAIL_URI, getVoicemailUri());
-            if (getIntent().getBooleanExtra(EXTRA_VOICEMAIL_START_PLAYBACK, false)) {
-                fragmentArguments.putBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, true);
+            VoicemailPlaybackFragment playbackFragment;
+
+            playbackFragment = (VoicemailPlaybackFragment) getFragmentManager().findFragmentByTag(
+                    VOICEMAIL_FRAGMENT_TAG);
+
+            if (playbackFragment == null) {
+                playbackFragment = new VoicemailPlaybackFragment();
+                Bundle fragmentArguments = new Bundle();
+                fragmentArguments.putParcelable(EXTRA_VOICEMAIL_URI, getVoicemailUri());
+                if (getIntent().getBooleanExtra(EXTRA_VOICEMAIL_START_PLAYBACK, false)) {
+                    fragmentArguments.putBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, true);
+                }
+                playbackFragment.setArguments(fragmentArguments);
+                getFragmentManager().beginTransaction()
+                        .add(R.id.voicemail_container, playbackFragment, VOICEMAIL_FRAGMENT_TAG)
+                                .commitAllowingStateLoss();
             }
-            playbackFragment.setArguments(fragmentArguments);
+
             voicemailContainer.setVisibility(View.VISIBLE);
-            getFragmentManager().beginTransaction()
-                    .add(R.id.voicemail_container, playbackFragment)
-                    .commitAllowingStateLoss();
             mAsyncQueryHandler.startVoicemailStatusQuery(getVoicemailUri());
             markVoicemailAsRead(getVoicemailUri());
         } else {
@@ -453,6 +468,14 @@
                     nameForDefaultImage = firstDetails.name.toString();
                 }
 
+                if (hasVoicemail() && !TextUtils.isEmpty(firstDetails.transcription)) {
+                    mVoicemailTranscription.setText(firstDetails.transcription);
+                    mVoicemailTranscription.setVisibility(View.VISIBLE);
+                } else {
+                    mVoicemailTranscription.setText(null);
+                    mVoicemailTranscription.setVisibility(View.GONE);
+                }
+
                 loadContactPhotos(
                         contactUri, photoUri, nameForDefaultImage, lookupKey, contactType);
                 findViewById(R.id.call_detail).setVisibility(View.VISIBLE);
@@ -495,6 +518,7 @@
             final int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
             String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX);
             final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX);
+            final String transcription = callCursor.getString(TRANSCRIPTION_COLUMN_INDEX);
 
             final Drawable accountIcon = PhoneAccountUtils.getAccountIcon(this,
                     PhoneAccountUtils.getAccount(
@@ -547,7 +571,7 @@
                     formattedNumber, countryIso, geocode,
                     new int[]{ callType }, date, duration,
                     nameText, numberType, numberLabel, lookupUri, photoUri, sourceType,
-                    accountIcon, features, dataUsage);
+                    accountIcon, features, dataUsage, transcription);
         } finally {
             if (callCursor != null) {
                 callCursor.close();
diff --git a/src/com/android/dialer/PhoneCallDetails.java b/src/com/android/dialer/PhoneCallDetails.java
index 0dc6fd3..8692036 100644
--- a/src/com/android/dialer/PhoneCallDetails.java
+++ b/src/com/android/dialer/PhoneCallDetails.java
@@ -16,6 +16,8 @@
 
 package com.android.dialer;
 
+import com.google.common.annotations.VisibleForTesting;
+
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.CallLog.Calls;
@@ -76,15 +78,32 @@
      * Total data usage for this call.
      */
     public final Long dataUsage;
+    /**
+     * Voicemail transcription
+     */
+    public final String transcription;
+
+    /**
+     * Create the details for a call, with empty defaults specified for extra fields that are
+     * not necessary for testing.
+     */
+    @VisibleForTesting
+    public PhoneCallDetails(CharSequence number, int numberPresentation,
+            CharSequence formattedNumber, String countryIso, String geocode,
+            int[] callTypes, long date, long duration) {
+        this (number, numberPresentation, formattedNumber, countryIso, geocode,
+        callTypes, date, duration, "", 0, "", null, null, 0, null, Calls.FEATURES_NONE,
+        null, null);
+    }
 
     /** Create the details for a call with a number not associated with a contact. */
     public PhoneCallDetails(CharSequence number, int numberPresentation,
             CharSequence formattedNumber, String countryIso, String geocode,
             int[] callTypes, long date, long duration, Drawable accountIcon, int features,
-            Long dataUsage) {
+            Long dataUsage, String transcription) {
         this(number, numberPresentation, formattedNumber, countryIso, geocode,
                 callTypes, date, duration, "", 0, "", null, null, 0, accountIcon, features,
-                dataUsage);
+                dataUsage, transcription);
     }
 
     /** Create the details for a call with a number associated with a contact. */
@@ -92,7 +111,8 @@
             CharSequence formattedNumber, String countryIso, String geocode,
             int[] callTypes, long date, long duration, CharSequence name,
             int numberType, CharSequence numberLabel, Uri contactUri,
-            Uri photoUri, int sourceType, Drawable accountIcon, int features, Long dataUsage) {
+            Uri photoUri, int sourceType, Drawable accountIcon, int features, Long dataUsage,
+            String transcription) {
         this.number = number;
         this.numberPresentation = numberPresentation;
         this.formattedNumber = formattedNumber;
@@ -110,5 +130,6 @@
         this.accountIcon = accountIcon;
         this.features = features;
         this.dataUsage = dataUsage;
+        this.transcription = transcription;
     }
 }
diff --git a/src/com/android/dialer/PhoneCallDetailsHelper.java b/src/com/android/dialer/PhoneCallDetailsHelper.java
index 2a24557..3846b6f 100644
--- a/src/com/android/dialer/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/PhoneCallDetailsHelper.java
@@ -77,8 +77,12 @@
         // Display up to a given number of icons.
         views.callTypeIcons.clear();
         int count = details.callTypes.length;
+        boolean isVoicemail = false;
         for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) {
             views.callTypeIcons.add(details.callTypes[index]);
+            if (index == 0) {
+                isVoicemail = details.callTypes[index] == Calls.VOICEMAIL_TYPE;
+            }
         }
 
         // Show the video icon if the call had video enabled.
@@ -122,10 +126,13 @@
 
         views.nameView.setText(nameText);
 
-        // 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);
+        if (isVoicemail && !TextUtils.isEmpty(details.transcription)) {
+            views.voicemailTranscriptionView.setText(details.transcription);
+            views.voicemailTranscriptionView.setVisibility(View.VISIBLE);
+        } else {
+            views.voicemailTranscriptionView.setText(null);
+            views.voicemailTranscriptionView.setVisibility(View.GONE);
+        }
     }
 
     /**
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 682dbd1..630cf3f 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -651,6 +651,7 @@
         final Drawable accountIcon = PhoneAccountUtils.getAccountIcon(mContext,
                 accountHandle);
         final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
+
         final long rowId = c.getLong(CallLogQuery.ID);
         views.rowId = rowId;
 
@@ -755,6 +756,7 @@
         final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
         final int sourceType = info.sourceType;
         final int features = getCallFeatures(c, count);
+        final String transcription = c.getString(CallLogQuery.TRANSCRIPTION);
         Long dataUsage = null;
         if (!c.isNull(CallLogQuery.DATA_USAGE)) {
             dataUsage = c.getLong(CallLogQuery.DATA_USAGE);
@@ -772,12 +774,12 @@
         if (TextUtils.isEmpty(name)) {
             details = new PhoneCallDetails(number, numberPresentation,
                     formattedNumber, countryIso, geocode, callTypes, date,
-                    duration, accountIcon, features, dataUsage);
+                    duration, accountIcon, features, dataUsage, transcription);
         } else {
             details = new PhoneCallDetails(number, numberPresentation,
                     formattedNumber, countryIso, geocode, callTypes, date,
                     duration, name, ntype, label, lookupUri, photoUri, sourceType,
-                    accountIcon, features, dataUsage);
+                    accountIcon, features, dataUsage, transcription);
         }
 
         mCallLogViewsHelper.setPhoneCallDetails(views, details);
diff --git a/src/com/android/dialer/calllog/CallLogQuery.java b/src/com/android/dialer/calllog/CallLogQuery.java
index 904ce74..0ae4cda 100644
--- a/src/com/android/dialer/calllog/CallLogQuery.java
+++ b/src/com/android/dialer/calllog/CallLogQuery.java
@@ -16,15 +16,12 @@
 
 package com.android.dialer.calllog;
 
-import android.database.Cursor;
 import android.provider.CallLog.Calls;
 
 /**
  * The query for the call log table.
  */
 public final class CallLogQuery {
-    // If you alter this, you must also alter the method that inserts a fake row to the headers
-    // in the CallLogQueryHandler class called createHeaderCursorFor().
     public static final String[] _PROJECTION = new String[] {
             Calls._ID,                          // 0
             Calls.NUMBER,                       // 1
@@ -47,7 +44,8 @@
             Calls.PHONE_ACCOUNT_COMPONENT_NAME, // 18
             Calls.PHONE_ACCOUNT_ID,             // 19
             Calls.FEATURES,                     // 20
-            Calls.DATA_USAGE                    // 21
+            Calls.DATA_USAGE,                   // 21
+            Calls.TRANSCRIPTION                 // 22
     };
 
     public static final int ID = 0;
@@ -72,4 +70,5 @@
     public static final int ACCOUNT_ID = 19;
     public static final int FEATURES = 20;
     public static final int DATA_USAGE = 21;
+    public static final int TRANSCRIPTION = 22;
 }
diff --git a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
index d0c13ee..569da54 100644
--- a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
@@ -312,7 +312,7 @@
                 new PhoneCallDetails(number, presentation, formattedNumber,
                         TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ Calls.VOICEMAIL_TYPE }, TEST_DATE, TEST_DURATION, null,
-                        Calls.FEATURES_NONE, null)
+                        Calls.FEATURES_NONE, null, null)
         );
     }
 
@@ -323,7 +323,7 @@
                 new PhoneCallDetails(number, Calls.PRESENTATION_ALLOWED,
                         formattedNumber, TEST_COUNTRY_ISO, geocodedLocation,
                         new int[]{ Calls.VOICEMAIL_TYPE }, TEST_DATE, TEST_DURATION, null,
-                        Calls.FEATURES_NONE, null)
+                        Calls.FEATURES_NONE, null, null)
         );
     }
 
@@ -332,8 +332,7 @@
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION, null,
-                        Calls.FEATURES_NONE, null)
+                        new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION)
         );
     }
 
@@ -342,7 +341,7 @@
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        callTypes, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE, null)
+                        callTypes, TEST_DATE, TEST_DURATION)
         );
     }
 
@@ -354,7 +353,7 @@
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION, null,
-                        features, null)
+                        features, null, null)
         );
     }
 
@@ -363,7 +362,7 @@
                 new PhoneCallDetails(number, presentation,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION, null,
-                        Calls.FEATURES_NONE, null));
+                        Calls.FEATURES_NONE, null, null));
     }
 
     private void setCallDetailsHeader(String name) {
@@ -371,6 +370,6 @@
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
                         new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION,
-                        name, 0, "", null, null, 0, null, Calls.FEATURES_NONE, null));
+                        name, 0, "", null, null, 0, null, Calls.FEATURES_NONE, null, null));
     }
 }
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index 4c9d92c..52f2544 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -128,8 +128,7 @@
     public void testGetCallDescriptionID_UnknownAnswered() {
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                null);
+                new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_answered_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -141,8 +140,7 @@
     public void testGetCallDescriptionID_UnknownMissed() {
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                null);
+                new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -154,8 +152,7 @@
     public void testGetCallDescriptionID_UnknownVoicemail() {
         PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION, null,
-                Calls.FEATURES_NONE, null);
+                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -168,8 +165,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                null);
+                new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_answered_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -182,8 +178,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                null);
+                new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -196,8 +191,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION, null,
-                Calls.FEATURES_NONE, null);
+                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_incoming_missed_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -211,8 +205,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                null);
+                new int[]{Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_outgoing_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -226,8 +219,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION, null,
-                Calls.FEATURES_NONE, null);
+                new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         assertEquals(R.string.description_outgoing_call,
                 mHelper.getCallDescriptionStringID(details));
     }
@@ -240,8 +232,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION,
-                null, Calls.FEATURES_NONE, null);
+                new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
@@ -255,8 +246,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION,
-                null, Calls.FEATURES_NONE, null);
+                new int[]{Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
@@ -270,8 +260,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.MISSED_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION, null,
-                Calls.FEATURES_NONE, null);
+                new int[]{Calls.MISSED_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
@@ -285,8 +274,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION,
-                null, Calls.FEATURES_NONE, null);
+                new int[]{Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertTrue(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
@@ -300,8 +288,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION, null,
-                Calls.FEATURES_NONE, null);
+                new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
 
         // Rather than hard coding the "X calls" string message, we'll generate it with an empty
@@ -320,8 +307,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION,
-                null, Calls.FEATURES_NONE, null);
+                new int[]{Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertTrue(description.toString()
                 .contains(this.mResources.getString(R.string.description_num_calls, 2)));
@@ -335,8 +321,7 @@
         PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                 TEST_FORMATTED_NUMBER,
                 TEST_COUNTRY_ISO, TEST_GEOCODE,
-                new int[]{Calls.INCOMING_TYPE, Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION,
-                null, Calls.FEATURES_VIDEO, null);
+                new int[]{Calls.INCOMING_TYPE, Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
         CharSequence description = mHelper.getCallDescription(details);
         assertTrue(description.toString()
                 .contains(this.mResources.getString(R.string.description_video_call, 2)));
@@ -362,8 +347,7 @@
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(number, presentation, formattedNumber,
                         TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        new int[]{ callType }, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE,
-                        null)
+                        new int[]{ callType }, TEST_DATE, TEST_DURATION)
         );
     }
 
@@ -372,7 +356,7 @@
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        types, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE, null)
+                        types, TEST_DATE, TEST_DURATION)
         );
     }
 
@@ -381,7 +365,7 @@
         mHelper.setPhoneCallDetails(mViews,
                 new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
                         TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        types, TEST_DATE, TEST_DURATION, null, Calls.FEATURES_NONE, null)
+                        types, TEST_DATE, TEST_DURATION)
         );
     }
 }
diff --git a/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java b/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
index dc3f525..2f7d212 100644
--- a/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
+++ b/tests/src/com/android/dialer/calllog/CallLogQueryTestUtils.java
@@ -29,7 +29,8 @@
     public static Object[] createTestValues() {
         Object[] values = new Object[]{
                 0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null, 0, Calls.PRESENTATION_ALLOWED, null, null, Calls.FEATURES_NONE, null
+                0L, null, 0, Calls.PRESENTATION_ALLOWED, null, null, Calls.FEATURES_NONE, null,
+                null
         };
         assertEquals(CallLogQuery._PROJECTION.length, values.length);
         return values;