Adapter logic for adding call context to call card fragment.

+ Adapter for call context list view
+ Method in CallCardFragment that handles properly displaying the call
  context information
+ Strings for the call context title
Note: the setCallContext method is currently not being called anywhere.
It is anticipated to be called in CallCardPresenter after the
appropriate data is loaded.

Bug: 23351559
Change-Id: Id72390fc9d2a8794b88ab72661381eb96596d619
diff --git a/InCallUI/res/drawable/incoming_sms_background.xml b/InCallUI/res/drawable/incoming_sms_background.xml
index 231ae25..81ff21c 100644
--- a/InCallUI/res/drawable/incoming_sms_background.xml
+++ b/InCallUI/res/drawable/incoming_sms_background.xml
@@ -17,9 +17,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
     <corners
-        android:topLeftRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:topRightRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:bottomRightRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:bottomLeftRadius="@dimen/contact_call_content_message_background_accent_radius"/>
-    <solid android:color="@color/contact_call_context_message_background_color" />
+        android:topLeftRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:topRightRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:bottomRightRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:bottomLeftRadius="@dimen/person_contact_context_message_background_accent_radius"/>
+    <solid android:color="@color/person_contact_context_message_background_color" />
 </shape>
diff --git a/InCallUI/res/drawable/outgoing_sms_background.xml b/InCallUI/res/drawable/outgoing_sms_background.xml
index 09c870f..e4f868f 100644
--- a/InCallUI/res/drawable/outgoing_sms_background.xml
+++ b/InCallUI/res/drawable/outgoing_sms_background.xml
@@ -17,9 +17,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
     <corners
-        android:topLeftRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:topRightRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:bottomLeftRadius="@dimen/contact_call_content_message_background_main_radius"
-        android:bottomRightRadius="@dimen/contact_call_content_message_background_accent_radius"/>
-    <solid android:color="@color/contact_call_context_message_background_color" />
+        android:topLeftRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:topRightRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:bottomLeftRadius="@dimen/person_contact_context_message_background_main_radius"
+        android:bottomRightRadius="@dimen/person_contact_context_message_background_accent_radius"/>
+    <solid android:color="@color/person_contact_context_message_background_color" />
 </shape>
diff --git a/InCallUI/res/layout/business_call_info_list_item.xml b/InCallUI/res/layout/business_context_info_list_item.xml
similarity index 70%
rename from InCallUI/res/layout/business_call_info_list_item.xml
rename to InCallUI/res/layout/business_context_info_list_item.xml
index 0a2478f..7ed528c 100644
--- a/InCallUI/res/layout/business_call_info_list_item.xml
+++ b/InCallUI/res/layout/business_context_info_list_item.xml
@@ -17,25 +17,25 @@
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
      <ImageView android:id="@+id/icon"
-         android:layout_width="@dimen/business_call_context_image_size"
-         android:layout_height="@dimen/business_call_context_image_size"
+         android:layout_width="@dimen/business_contact_context_image_size"
+         android:layout_height="@dimen/business_contact_context_image_size"
          android:scaleType="centerCrop"
          android:layout_centerVertical="true"
-         android:layout_marginLeft="@dimen/business_call_context_image_padding"
-         android:layout_marginRight="@dimen/business_call_context_image_padding"/>
+         android:layout_marginLeft="@dimen/business_contact_context_image_padding"
+         android:layout_marginRight="@dimen/business_contact_context_image_padding"/>
      <TextView android:id="@+id/heading"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_toEndOf="@id/icon"
-         android:textSize="@dimen/business_call_context_heading_font_size"
-         android:textColor="@color/business_call_context_text_color"
+         android:textSize="@dimen/business_contact_context_heading_font_size"
+         android:textColor="@color/business_contact_context_text_color"
          android:fontFamily="sans-serif-medium"/>
      <TextView android:id="@+id/detail"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_toEndOf="@id/icon"
          android:layout_below="@id/heading"
-         android:textSize="@dimen/business_call_context_detail_font_size"
-         android:textColor="@color/business_call_context_text_color"
+         android:textSize="@dimen/business_contact_context_detail_font_size"
+         android:textColor="@color/business_contact_context_text_color"
          android:fontFamily="sans-serif-medium"/>
  </RelativeLayout>
\ No newline at end of file
diff --git a/InCallUI/res/layout/call_card_fragment.xml b/InCallUI/res/layout/call_card_fragment.xml
index 87280b3..a8f3d27 100644
--- a/InCallUI/res/layout/call_card_fragment.xml
+++ b/InCallUI/res/layout/call_card_fragment.xml
@@ -74,25 +74,25 @@
 
             <!-- Call context -->
             <LinearLayout
-                android:id="@+id/call_context"
+                android:id="@+id/contact_context"
                 android:layout_height="match_parent"
                 android:layout_width="match_parent"
                 android:orientation="vertical"
                 android:background="@color/incall_background_color"
                 android:visibility="gone">
-                <TextView android:id="@+id/contextTitle"
-                    android:textSize="@dimen/call_context_title_text_size"
-                    android:textColor="@color/call_context_title_text_color"
+                <TextView android:id="@+id/contactContextTitle"
+                    android:textSize="@dimen/contact_context_title_text_size"
+                    android:textColor="@color/contact_context_title_text_color"
                     android:fontFamily="sans-serif-medium"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center_horizontal"
-                    android:layout_marginBottom="@dimen/call_context_title_margin_bottom"/>
-                <ListView android:id="@+id/callContextInfo"
+                    android:layout_marginBottom="@dimen/contact_context_title_margin_bottom"/>
+                <ListView android:id="@+id/contactContextInfo"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:divider="@null"
-                     android:dividerHeight="@dimen/call_context_list_item_padding"/>
+                     android:dividerHeight="@dimen/contact_context_list_item_padding"/>
             </LinearLayout>
         </FrameLayout>
 
diff --git a/InCallUI/res/layout/contact_call_info_list_item.xml b/InCallUI/res/layout/contact_call_info_list_item.xml
deleted file mode 100644
index 424b59d..0000000
--- a/InCallUI/res/layout/contact_call_info_list_item.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-     android:layout_width="match_parent"
-     android:layout_height="match_parent"
-     android:paddingRight="@dimen/contact_call_context_horizontal_padding"
-     android:paddingLeft="@dimen/contact_call_context_horizontal_padding">
-     <TextView android:id="@+id/message"
-         android:layout_width="wrap_content"
-         android:layout_height="wrap_content"
-         android:paddingLeft="@dimen/contact_call_context_message_horizontal_padding"
-         android:paddingRight="@dimen/contact_call_context_message_horizontal_padding"
-         android:paddingTop="@dimen/contact_call_context_message_vertical_padding"
-         android:paddingBottom="@dimen/contact_call_context_message_vertical_padding"
-         android:textSize="@dimen/contact_call_context_message_text_size"
-         android:textColor="@color/contact_call_context_message_text_color"
-         android:fontFamily="sans-serif-medium"
-         android:background="@drawable/incoming_sms_background"/>
-      <TextView android:id="@+id/detail"
-         android:layout_width="wrap_content"
-         android:layout_height="wrap_content"
-         android:paddingTop="@dimen/contact_call_context_detail_padding_top"
-         android:textSize="@dimen/contact_call_context_detail_text_size"
-         android:textColor="@color/contact_call_context_detail_text_color"
-         android:fontFamily="sans-serif-medium"
-         android:layout_below="@id/message"/>
-</RelativeLayout>
\ No newline at end of file
diff --git a/InCallUI/res/layout/person_context_info_list_item.xml b/InCallUI/res/layout/person_context_info_list_item.xml
new file mode 100644
index 0000000..4f973d5
--- /dev/null
+++ b/InCallUI/res/layout/person_context_info_list_item.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+     android:layout_width="match_parent"
+     android:layout_height="match_parent"
+     android:paddingRight="@dimen/person_contact_context_horizontal_padding"
+     android:paddingLeft="@dimen/person_contact_context_horizontal_padding">
+     <TextView android:id="@+id/message"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:paddingLeft="@dimen/person_contact_context_message_horizontal_padding"
+         android:paddingRight="@dimen/person_contact_context_message_horizontal_padding"
+         android:paddingTop="@dimen/person_contact_context_message_vertical_padding"
+         android:paddingBottom="@dimen/person_contact_context_message_vertical_padding"
+         android:textSize="@dimen/person_contact_context_message_text_size"
+         android:textColor="@color/person_contact_context_message_text_color"
+         android:fontFamily="sans-serif-medium"
+         android:background="@drawable/incoming_sms_background"/>
+      <TextView android:id="@+id/detail"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:paddingTop="@dimen/person_contact_context_detail_padding_top"
+         android:textSize="@dimen/person_contact_context_detail_text_size"
+         android:textColor="@color/person_contact_context_detail_text_color"
+         android:fontFamily="sans-serif-medium"
+         android:layout_below="@id/message"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/InCallUI/res/values/colors.xml b/InCallUI/res/values/colors.xml
index 409c2d2..3697e11 100644
--- a/InCallUI/res/values/colors.xml
+++ b/InCallUI/res/values/colors.xml
@@ -111,9 +111,9 @@
     <!-- Ripple color used over light backgrounds. -->
     <color name="ripple_light">#40000000</color>
 
-    <color name="call_context_title_text_color">@color/incall_call_banner_subtext_color</color>
-    <color name="contact_call_context_message_text_color">@color/dialer_theme_color</color>
-    <color name="contact_call_context_message_background_color">@color/incall_call_banner_subtext_color</color>
-    <color name="contact_call_context_detail_text_color">@color/incall_call_banner_subtext_color</color>
-    <color name="business_call_context_text_color">@color/incall_call_banner_subtext_color</color>
+    <color name="contact_context_title_text_color">@color/incall_call_banner_subtext_color</color>
+    <color name="person_contact_context_message_text_color">@color/dialer_theme_color</color>
+    <color name="person_contact_context_message_background_color">@color/incall_call_banner_subtext_color</color>
+    <color name="person_contact_context_detail_text_color">@color/incall_call_banner_subtext_color</color>
+    <color name="business_contact_context_text_color">@color/incall_call_banner_subtext_color</color>
 </resources>
diff --git a/InCallUI/res/values/dimens.xml b/InCallUI/res/values/dimens.xml
index 7738336..02527d3 100644
--- a/InCallUI/res/values/dimens.xml
+++ b/InCallUI/res/values/dimens.xml
@@ -120,21 +120,21 @@
     <dimen name="conference_call_manager_padding_top">64dp</dimen>
     <dimen name="conference_call_manager_button_dimension">46dp</dimen>
 
-    <dimen name="call_context_title_text_size">14sp</dimen>
-    <dimen name="call_context_title_margin_bottom">13dp</dimen>
-    <dimen name="call_context_list_item_padding">13dp</dimen>
+    <dimen name="contact_context_title_text_size">14sp</dimen>
+    <dimen name="contact_context_title_margin_bottom">13dp</dimen>
+    <dimen name="contact_context_list_item_padding">13dp</dimen>
 
-    <dimen name="contact_call_context_horizontal_padding">30dp</dimen>
-    <dimen name="contact_call_context_message_text_size">16sp</dimen>
-    <dimen name="contact_call_context_message_vertical_padding">7dp</dimen>
-    <dimen name="contact_call_context_message_horizontal_padding">12dp</dimen>
-    <dimen name="contact_call_content_message_background_main_radius">15dp</dimen>
-    <dimen name="contact_call_content_message_background_accent_radius">2dp</dimen>
-    <dimen name="contact_call_context_detail_padding_top">7dp</dimen>
-    <dimen name="contact_call_context_detail_text_size">14sp</dimen>
+    <dimen name="person_contact_context_horizontal_padding">30dp</dimen>
+    <dimen name="person_contact_context_message_text_size">16sp</dimen>
+    <dimen name="person_contact_context_message_vertical_padding">7dp</dimen>
+    <dimen name="person_contact_context_message_horizontal_padding">12dp</dimen>
+    <dimen name="person_contact_context_message_background_main_radius">15dp</dimen>
+    <dimen name="person_contact_context_message_background_accent_radius">2dp</dimen>
+    <dimen name="person_contact_context_detail_padding_top">7dp</dimen>
+    <dimen name="person_contact_context_detail_text_size">14sp</dimen>
 
-    <dimen name="business_call_context_image_size">25dp</dimen>
-    <dimen name="business_call_context_image_padding">20dp</dimen>
-    <dimen name="business_call_context_heading_font_size">18sp</dimen>
-    <dimen name="business_call_context_detail_font_size">13sp</dimen>
+    <dimen name="business_contact_context_image_size">25dp</dimen>
+    <dimen name="business_contact_context_image_padding">20dp</dimen>
+    <dimen name="business_contact_context_heading_font_size">18sp</dimen>
+    <dimen name="business_contact_context_detail_font_size">13sp</dimen>
 </resources>
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index e59867c..0d0aab3 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -464,4 +464,10 @@
     <!-- Used to inform the user that the note associated with an outgoing call has been sent.
          [CHAR LIMIT=32] -->
     <string name="note_sent">Note sent</string>
+
+    <!-- Title for the call context with a person-type contact. [CHAR LIMIT=40] -->
+    <string name="person_contact_context_title">Recent messages</string>
+
+    <!-- Title for the call context with a business-type contact. [CHAR LIMIT=40] -->
+    <string name="business_contact_context_title">Business info</string>
 </resources>
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 5e00587..ffc7cb6 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -46,11 +46,15 @@
 import android.view.animation.AnimationUtils;
 import android.widget.ImageButton;
 import android.widget.ImageView;
+import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
 import com.android.contacts.common.widget.FloatingActionButtonController;
+import com.android.incallui.InCallContactInteractions.BusinessContextInfo;
+import com.android.incallui.InCallContactInteractions.PersonContextInfo;
+import com.android.incallui.InCallContactInteractions.ContactContextInfo;
 import com.android.phone.common.animation.AnimUtils;
 
 import java.util.List;
@@ -122,7 +126,6 @@
     private ImageView mHdAudioIcon;
     private ImageView mForwardIcon;
     private View mCallNumberAndLabel;
-    private ImageView mPhoto;
     private TextView mElapsedTime;
     private Drawable mPrimaryPhotoDrawable;
     private TextView mCallSubject;
@@ -142,6 +145,13 @@
     private View mSecondaryCallVideoCallIcon;
     private View mProgressSpinner;
 
+    // Call card content
+    private View mCallCardContent;
+    private ImageView mPhoto;
+    private View mContactContext;
+    private TextView mContactContextTitle;
+    private ListView mContactContextListView;
+
     private View mManageConferenceCallButton;
 
     // Dark number info bar
@@ -168,6 +178,8 @@
     private boolean mCallStateLabelResetPending = false;
     private Handler mHandler;
 
+    private InCallContactInteractions mInCallContactInteractions;
+
     @Override
     public CallCardPresenter.CallCardUi getUi() {
         return this;
@@ -235,6 +247,7 @@
         mNumberLabel = (TextView) view.findViewById(R.id.label);
         mSecondaryCallInfo = view.findViewById(R.id.secondary_call_info);
         mSecondaryCallProviderInfo = view.findViewById(R.id.secondary_call_provider_info);
+        mCallCardContent = view.findViewById(R.id.call_card_content);
         mPhoto = (ImageView) view.findViewById(R.id.photo);
         mPhoto.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -242,6 +255,9 @@
                 getPresenter().onContactPhotoClick();
             }
         });
+        mContactContext = view.findViewById(R.id.contact_context);
+        mContactContextTitle = (TextView) view.findViewById(R.id.contactContextTitle);
+        mContactContextListView = (ListView) view.findViewById(R.id.contactContextInfo);
         mCallStateIcon = (ImageView) view.findViewById(R.id.callStateIcon);
         mCallStateVideoCallIcon = (ImageView) view.findViewById(R.id.videoCallIcon);
         mCallStateLabel = (TextView) view.findViewById(R.id.callStateLabel);
@@ -319,6 +335,25 @@
         mProgressSpinner.setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 
+    @Override
+    public void setContactContext(boolean isBusiness, List<ContactContextInfo> info) {
+        mPhoto.setVisibility(View.GONE);
+        mPrimaryCallCardContainer.setElevation(0);
+        mContactContext.setVisibility(View.VISIBLE);
+
+        if (mInCallContactInteractions == null) {
+            mInCallContactInteractions =
+                    new InCallContactInteractions(getView().getContext(), isBusiness);
+        } else {
+            mInCallContactInteractions.setIsBusiness(isBusiness);
+        }
+
+        mContactContextTitle.setText(mInCallContactInteractions.getContactContextTitle());
+        mInCallContactInteractions.setData(info);
+        mContactContextListView.setAdapter(mInCallContactInteractions.getListAdapter());
+    }
+
+
     /**
      * Sets the visibility of the primary call card.
      * Ensures that when the primary call card is hidden, the video surface slides over to fill the
@@ -1051,6 +1086,8 @@
         }
         mCallButtonsContainer.setBackgroundColor(themeColors.mPrimaryColor);
         mCallSubject.setTextColor(themeColors.mPrimaryColor);
+        mCallCardContent.setBackgroundColor(themeColors.mPrimaryColor);
+        //TODO: set color of message text in call context "recent messages" to be the theme color.
 
         mCurrentThemeColors = themeColors;
     }
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 0460829..2cd6b6e 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -38,6 +38,7 @@
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.incallui.Call.LogState;
+import com.android.incallui.InCallContactInteractions.ContactContextInfo;
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
 import com.android.incallui.InCallPresenter.InCallDetailsListener;
@@ -48,6 +49,7 @@
 import com.android.incalluibind.ObjectFactory;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
 
 import com.google.common.base.Preconditions;
 
@@ -952,6 +954,7 @@
 
     public interface CallCardUi extends Ui {
         void setVisible(boolean on);
+        void setContactContext(boolean isBusiness, List<ContactContextInfo> info);
         void setCallCardVisible(boolean visible);
         void setPrimary(String number, String name, boolean nameIsNumber, String label,
                 Drawable photo, boolean isSipCall, boolean isContactPhotoShown);
diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
new file mode 100644
index 0000000..c1af44b
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.RelativeLayout;
+import android.widget.RelativeLayout.LayoutParams;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Wrapper class for objects that are used in generating the context about the contact in the InCall
+ * screen.
+ *
+ * This handles generating the appropriate resource for the ListAdapter based on whether the contact
+ * is a business contact or not and logic for the manipulation of data for the call context.
+ */
+public class InCallContactInteractions {
+    private Context mContext;
+    private InCallContactInteractionsListAdapter mListAdapter;
+    private boolean mIsBusiness;
+
+    public InCallContactInteractions(Context context, boolean isBusiness) {
+        mContext = context;
+        setIsBusiness(isBusiness);
+    }
+
+    public InCallContactInteractionsListAdapter getListAdapter() {
+        return mListAdapter;
+    }
+
+    /**
+     * Resets the "isBusiness" value, also recreates the list adapter with the resource
+     * corresponding to the new isBusiness value.
+     * @param isBusiness Whether or not the contact is a business.
+     */
+    public void setIsBusiness(boolean isBusiness) {
+        if (mIsBusiness != isBusiness || mListAdapter == null) {
+            mIsBusiness = isBusiness;
+            mListAdapter = new InCallContactInteractionsListAdapter(mContext,
+                    mIsBusiness ? R.layout.business_context_info_list_item
+                            : R.layout.person_context_info_list_item);
+        }
+    }
+
+    /**
+     * Set the data for the list adapter.
+     * @param data The data to add to the list adapter. This completely replaces any previous data.
+     */
+    public void setData(List<ContactContextInfo> data) {
+        mListAdapter.clear();
+        mListAdapter.addAll(data);
+    }
+
+    /**
+     * Get the appropriate title for the context.
+     * @return The "Business info" title for a business contact and the "Recent messages" title for
+     *         personal contacts.
+     */
+    public String getContactContextTitle() {
+        return mIsBusiness
+                ? mContext.getResources().getString(R.string.business_contact_context_title)
+                : mContext.getResources().getString(R.string.person_contact_context_title);
+    }
+
+    public static abstract class ContactContextInfo {
+        Context mContext;
+
+        public ContactContextInfo(Context context) {
+            mContext = context;
+        }
+
+        public abstract void setListView(View listItem);
+    }
+
+    public static class BusinessContextInfo extends ContactContextInfo {
+        public BusinessContextInfo(Context context) {
+            super(context);
+        }
+
+        int iconId;
+        String heading;
+        String detail;
+
+        @Override
+        public void setListView(View listItem) {
+            ImageView imageView = (ImageView) listItem.findViewById(R.id.icon);
+            TextView headingTextView = (TextView) listItem.findViewById(R.id.heading);
+            TextView detailTextView = (TextView) listItem.findViewById(R.id.detail);
+
+            if (this.iconId == 0 || this.heading == null || this.detail == null) {
+                return;
+            }
+
+            imageView.setImageDrawable(mContext.getDrawable(this.iconId));
+            headingTextView.setText(this.heading);
+            detailTextView.setText(this.detail);
+        }
+    }
+
+    public static class PersonContextInfo extends ContactContextInfo {
+        boolean isIncoming;
+        String message;
+        String detail;
+
+        public PersonContextInfo(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void setListView(View listItem) {
+            TextView messageTextView = (TextView) listItem.findViewById(R.id.message);
+            TextView detailTextView = (TextView) listItem.findViewById(R.id.detail);
+
+            if (this.message == null || this.detail == null) {
+                return;
+            }
+
+            messageTextView.setBackgroundResource(this.isIncoming ?
+                    R.drawable.incoming_sms_background : R.drawable.outgoing_sms_background);
+            messageTextView.setText(this.message);
+            LayoutParams messageLayoutParams = (LayoutParams) messageTextView.getLayoutParams();
+            messageLayoutParams.addRule(this.isIncoming?
+                    RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END);
+            messageTextView.setLayoutParams(messageLayoutParams);
+
+            LayoutParams detailLayoutParams = (LayoutParams) detailTextView.getLayoutParams();
+            detailLayoutParams.addRule(this.isIncoming ?
+                    RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END);
+            detailTextView.setLayoutParams(detailLayoutParams);
+            detailTextView.setText(this.detail);
+        }
+    }
+
+    /**
+     * A list adapter for call context information. We use the same adapter for both business and
+     * contact context.
+     */
+    private class InCallContactInteractionsListAdapter extends ArrayAdapter<ContactContextInfo> {
+        // The resource id of the list item layout.
+        int mResId;
+
+        public InCallContactInteractionsListAdapter(Context context, int resource) {
+            super(context, resource);
+            mResId = resource;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            LayoutInflater inflater = (LayoutInflater)
+                    getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            View listItem;
+            listItem = inflater.inflate(mResId, null);
+
+            ContactContextInfo item = getItem(position);
+
+            if (item == null) {
+                return listItem;
+            }
+
+            item.setListView(listItem);
+
+            return listItem;
+        }
+    }
+}
\ No newline at end of file