Merge "New appearance and look and feel for dialpad."
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 15d7a92..e39b413 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -34,9 +34,20 @@
         @id/call_log_item gone
     -->
 
+    <!-- Linear layout to separate the primary area containing the contact badge and caller
+         information and the secondary action (call details / play voicemail). -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:gravity="center_vertical"
+        >
+
+        <!-- Primary area containing the contact badge and caller information -->
         <LinearLayout
             android:id="@+id/primary_action_view"
-            android:layout_width="match_parent"
+            android:layout_width="0dp"
+            android:layout_weight="1"
             android:layout_height="wrap_content"
             android:layout_centerVertical="true"
             android:padding="@dimen/call_log_outer_margin"
@@ -46,7 +57,7 @@
             android:focusable="true"
             android:nextFocusRight="@+id/secondary_action_icon"
             android:nextFocusLeft="@+id/quick_contact_photo"
-        >
+            >
             <QuickContactBadge
                 android:id="@+id/quick_contact_photo"
                 android:layout_width="@dimen/call_log_list_contact_photo_size"
@@ -54,7 +65,7 @@
                 android:nextFocusRight="@id/primary_action_view"
                 android:layout_alignParentStart="true"
                 android:focusable="true"
-            />
+                />
             <LinearLayout
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
@@ -62,7 +73,7 @@
                 android:orientation="vertical"
                 android:gravity="center_vertical"
                 android:layout_marginStart="@dimen/call_log_inner_margin"
-            >
+                >
                 <TextView
                     android:id="@+id/name"
                     android:layout_width="wrap_content"
@@ -71,12 +82,12 @@
                     android:textColor="?attr/call_log_primary_text_color"
                     android:textSize="16sp"
                     android:singleLine="true"
-                />
+                    />
                 <LinearLayout
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:orientation="horizontal"
-                >
+                    >
                     <TextView
                         android:id="@+id/label"
                         android:layout_width="wrap_content"
@@ -87,13 +98,13 @@
                         android:singleLine="true"
                         android:ellipsize="marquee"
                         />
-                    </LinearLayout>
+                </LinearLayout>
                 <LinearLayout
                     android:id="@+id/call_type"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:orientation="horizontal"
-                >
+                    >
                     <view
                         class="com.android.dialer.calllog.CallTypeIconsView"
                         android:id="@+id/call_type_icons"
@@ -101,7 +112,7 @@
                         android:layout_height="wrap_content"
                         android:layout_marginEnd="@dimen/call_log_icon_margin"
                         android:layout_gravity="center_vertical"
-                    />
+                        />
                     <TextView
                         android:id="@+id/call_count_and_date"
                         android:layout_width="wrap_content"
@@ -111,43 +122,43 @@
                         android:textColor="?attr/call_log_secondary_text_color"
                         android:textSize="12sp"
                         android:singleLine="true"
-                    />
+                        />
                 </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="wrap_content"
-                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="@dimen/call_log_call_action_width"
-                    android:layout_height="match_parent"
-                    android:paddingStart="@dimen/call_log_inner_margin"
-                    android:paddingTop="@dimen/call_log_inner_margin"
-                    android:paddingBottom="@dimen/call_log_inner_margin"
-                    android:paddingEnd="@dimen/call_log_inner_margin"
-                    android:scaleType="center"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:nextFocusLeft="@id/primary_action_view"
-                />
-            </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="match_parent"
+                android:layout_height="match_parent"
+                android:paddingStart="@dimen/call_log_inner_margin"
+                android:paddingTop="@dimen/call_log_inner_margin"
+                android:paddingBottom="@dimen/call_log_inner_margin"
+                android:paddingEnd="@dimen/call_log_inner_margin"
+                android:scaleType="center"
+                android:background="?android:attr/selectableItemBackground"
+                android:nextFocusLeft="@id/primary_action_view"
+                />
+        </LinearLayout>
+    </LinearLayout>
     <TextView
         android:id="@+id/call_log_header"
         style="@style/ContactListSeparatorTextViewStyle"
diff --git a/res/layout/phone_favorite_regular_row_view.xml b/res/layout/phone_favorite_regular_row_view.xml
index 0d131f6..d046fdb 100644
--- a/res/layout/phone_favorite_regular_row_view.xml
+++ b/res/layout/phone_favorite_regular_row_view.xml
@@ -65,18 +65,6 @@
                 android:singleLine="true"
                 android:textColor="@color/dialtacts_secondary_text_color" />
         </LinearLayout>
-        <ImageView
-            android:id="@+id/contact_favorite_star"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignRight="@id/contact_tile_quick"
-            android:layout_alignEnd="@id/contact_tile_quick"
-            android:layout_alignBottom="@id/contact_tile_quick"
-            android:layout_marginRight="7dip"
-            android:layout_marginEnd="7dip"
-            android:layout_marginBottom="7dip"
-            android:src="@drawable/star_thumbnail"
-            android:visibility="gone" />
 
     </RelativeLayout>
 
diff --git a/res/layout/phone_favorite_tile_view.xml b/res/layout/phone_favorite_tile_view.xml
index c4ad780..8562b36 100644
--- a/res/layout/phone_favorite_tile_view.xml
+++ b/res/layout/phone_favorite_tile_view.xml
@@ -85,26 +85,6 @@
             android:nextFocusRight="@+id/contact_tile_secondary_button"
             android:background="?android:attr/selectableItemBackground" />
 
-        <ImageView
-            android:id="@+id/contact_favorite_star"
-            android:background="?android:attr/selectableItemBackground"
-            android:layout_height="@dimen/contact_tile_info_button_height_and_width"
-            android:layout_width="@dimen/contact_tile_info_button_height_and_width"
-            android:paddingLeft="2dp"
-            android:paddingRight="2dp"
-            android:paddingStart="2dp"
-            android:paddingEnd="2dp"
-            android:paddingTop="2dp"
-            android:paddingBottom="2dp"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentRight="true"
-            android:layout_alignParentEnd="true"
-            android:src="@drawable/star_thumbnail"
-            android:scaleType="center"
-            android:contentDescription="@string/description_view_contact_detail"
-            android:visibility="gone" />
-
-
         <ImageButton
             android:id="@id/contact_tile_secondary_button"
             android:src="@drawable/overflow_thumbnail"
diff --git a/res/layout/tile_interactions_teaser_view.xml b/res/layout/tile_interactions_teaser_view.xml
index 4104446..8204cb1 100644
--- a/res/layout/tile_interactions_teaser_view.xml
+++ b/res/layout/tile_interactions_teaser_view.xml
@@ -18,7 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/actionbar_background_color"
+    android:background="@color/background_dialer_list_items"
     android:paddingBottom="@dimen/favorites_row_bottom_padding"
     android:paddingTop="@dimen/favorites_row_top_padding">
 
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 57cf883..bd949b5 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -125,8 +125,7 @@
     <string name="description_call_last" msgid="491385778814705302">"Soita <xliff:g id="NAMEORNUMBER">%1$s</xliff:g> <xliff:g id="TYPEORLOCATION">%2$s</xliff:g>. Soitettiin <xliff:g id="TIMEOFCALL">%3$s</xliff:g>."</string>
     <string name="description_send_text_message" msgid="7803126439934046891">"Lähetä tekstiviesti: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"Kuuntelematon vastaajaviesti"</string>
-    <!-- no translation found for description_clear_search (688023606766232904) -->
-    <skip />
+    <string name="description_clear_search" msgid="688023606766232904">"Tyhjennä haku"</string>
     <string name="description_start_voice_search" msgid="520539488194946012">"Aloita puhehaku"</string>
     <string name="menu_callNumber" msgid="997146291983360266">"Soita <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="unknown" msgid="740067747858270469">"Tuntematon"</string>
@@ -174,10 +173,7 @@
     <string name="no_favorites" msgid="5212485868783382971">"Suosikit ja yhteyshenkilöt, joille\nsoitat usein, näkyvät tässä.\nAla siis soitella."</string>
     <string name="contact_tooltip" msgid="7817483485692282287">"Napauta kuvaa nähdäksesi kaikki numerot tai järjestä uudelleen painamalla pitkään"</string>
     <string name="description_dismiss" msgid="2146276780562549643">"Ohita"</string>
-    <!-- no translation found for remove_contact (1080555335283662961) -->
-    <skip />
-    <!-- no translation found for favorites_menu_speed_dial (3832518092014707628) -->
-    <skip />
-    <!-- no translation found for favorites_menu_all_contacts (992506284449891186) -->
-    <skip />
+    <string name="remove_contact" msgid="1080555335283662961">"Poista"</string>
+    <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"Pikavalinta"</string>
+    <string name="favorites_menu_all_contacts" msgid="992506284449891186">"KAIKKI YHTEYSTIEDOT"</string>
 </resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index eac67ec..1c01456 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -125,8 +125,7 @@
     <string name="description_call_last" msgid="491385778814705302">"Panggil <xliff:g id="NAMEORNUMBER">%1$s</xliff:g> <xliff:g id="TYPEORLOCATION">%2$s</xliff:g>. Dipanggil <xliff:g id="TIMEOFCALL">%3$s</xliff:g>."</string>
     <string name="description_send_text_message" msgid="7803126439934046891">"Hantar mesej teks kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"Mel suara belum didengar"</string>
-    <!-- no translation found for description_clear_search (688023606766232904) -->
-    <skip />
+    <string name="description_clear_search" msgid="688023606766232904">"Kosongkan carian"</string>
     <string name="description_start_voice_search" msgid="520539488194946012">"Mulakan carian suara"</string>
     <string name="menu_callNumber" msgid="997146291983360266">"Panggil <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="unknown" msgid="740067747858270469">"Tidak diketahui"</string>
@@ -174,10 +173,7 @@
     <string name="no_favorites" msgid="5212485868783382971">"Kegemaran &amp; kenalan yang\nkerap anda hubungi akan ditunjukkan di sini.\nJadi, mulalah membuat panggilan."</string>
     <string name="contact_tooltip" msgid="7817483485692282287">"Ketik imej untuk melihat semua nombor atau tekan dan tahan imej untuk menyusun semula"</string>
     <string name="description_dismiss" msgid="2146276780562549643">"Ketepikan"</string>
-    <!-- no translation found for remove_contact (1080555335283662961) -->
-    <skip />
-    <!-- no translation found for favorites_menu_speed_dial (3832518092014707628) -->
-    <skip />
-    <!-- no translation found for favorites_menu_all_contacts (992506284449891186) -->
-    <skip />
+    <string name="remove_contact" msgid="1080555335283662961">"Alih keluar"</string>
+    <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"Dail Laju"</string>
+    <string name="favorites_menu_all_contacts" msgid="992506284449891186">"SEMUA KENALAN"</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index cdfd4ad..29659b6 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -174,6 +174,6 @@
     <string name="contact_tooltip" msgid="7817483485692282287">"Trykk på bildet for å se alle telefonnumrene, eller trykk og hold inne for å endre rekkefølgen"</string>
     <string name="description_dismiss" msgid="2146276780562549643">"Fjern"</string>
     <string name="remove_contact" msgid="1080555335283662961">"Fjern"</string>
-    <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"Hurtigvalg"</string>
+    <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"Hurtigoppringing"</string>
     <string name="favorites_menu_all_contacts" msgid="992506284449891186">"ALLE KONTAKTER"</string>
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index cf0fc74..d3fb399 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -125,8 +125,7 @@
     <string name="description_call_last" msgid="491385778814705302">"Sunați la <xliff:g id="NAMEORNUMBER">%1$s</xliff:g> <xliff:g id="TYPEORLOCATION">%2$s</xliff:g>. Ora apelului: <xliff:g id="TIMEOFCALL">%3$s</xliff:g>."</string>
     <string name="description_send_text_message" msgid="7803126439934046891">"Trimiteţi un mesaj text către <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"Mesaje vocale neascultate"</string>
-    <!-- no translation found for description_clear_search (688023606766232904) -->
-    <skip />
+    <string name="description_clear_search" msgid="688023606766232904">"Ștergeți căutarea"</string>
     <string name="description_start_voice_search" msgid="520539488194946012">"Începeţi căutarea vocală"</string>
     <string name="menu_callNumber" msgid="997146291983360266">"Apelaţi <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="unknown" msgid="740067747858270469">"Necunoscut"</string>
@@ -174,10 +173,7 @@
     <string name="no_favorites" msgid="5212485868783382971">"Preferințele și persoanele din Agendă pe care \nle apelați frecvent vor fi afișate aici.\nÎncepeți să faceți apeluri."</string>
     <string name="contact_tooltip" msgid="7817483485692282287">"Atingeți imaginea pentru a vedea toate numerele sau apăsați și țineți apăsat pentru a reordona"</string>
     <string name="description_dismiss" msgid="2146276780562549643">"Închideți"</string>
-    <!-- no translation found for remove_contact (1080555335283662961) -->
-    <skip />
-    <!-- no translation found for favorites_menu_speed_dial (3832518092014707628) -->
-    <skip />
-    <!-- no translation found for favorites_menu_all_contacts (992506284449891186) -->
-    <skip />
+    <string name="remove_contact" msgid="1080555335283662961">"Eliminați"</string>
+    <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"Apelare rapidă"</string>
+    <string name="favorites_menu_all_contacts" msgid="992506284449891186">"TOATĂ AGENDA"</string>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index a923087..a13b125 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -173,7 +173,7 @@
     <string name="no_favorites" msgid="5212485868783382971">"您收藏的联系人和经常通话\n的联系人都会显示在这里。\n现在就开始与联系人通话吧。"</string>
     <string name="contact_tooltip" msgid="7817483485692282287">"点按图片可查看所有号码,按住图片可重新排序"</string>
     <string name="description_dismiss" msgid="2146276780562549643">"关闭"</string>
-    <string name="remove_contact" msgid="1080555335283662961">"删除"</string>
+    <string name="remove_contact" msgid="1080555335283662961">"移除"</string>
     <string name="favorites_menu_speed_dial" msgid="3832518092014707628">"快速拨号"</string>
     <string name="favorites_menu_all_contacts" msgid="992506284449891186">"所有联系人"</string>
 </resources>
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index 2b6566f..e09e6f3 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -32,6 +32,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.CallLog;
+import android.provider.ContactsContract;
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Contacts;
@@ -56,6 +57,7 @@
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.ClipboardUtils;
+import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.GeoUtil;
 import com.android.contacts.common.model.Contact;
 import com.android.contacts.common.model.ContactLoader;
@@ -545,14 +547,14 @@
                             mainActionDescription);
                 }
 
+                final CharSequence displayNumber =
+                        mPhoneNumberHelper.getDisplayNumber(
+                                firstDetails.number,
+                                firstDetails.numberPresentation,
+                                firstDetails.formattedNumber);
+
                 // This action allows to call the number that places the call.
                 if (canPlaceCallsTo) {
-                    final CharSequence displayNumber =
-                            mPhoneNumberHelper.getDisplayNumber(
-                                    firstDetails.number,
-                                    firstDetails.numberPresentation,
-                                    firstDetails.formattedNumber);
-
                     ViewEntry entry = new ViewEntry(
                             getString(R.string.menu_callNumber,
                                     forceLeftToRight(displayNumber)),
@@ -623,7 +625,20 @@
                             }
                         },
                         historyList);
-                loadContactPhotos(photoUri);
+
+                final String displayNameForDefaultImage = TextUtils.isEmpty(firstDetails.name) ?
+                        displayNumber.toString() : firstDetails.name.toString();
+
+                final String lookupKey = ContactInfoHelper.getLookupKeyFromUri(contactUri);
+
+                final boolean isBusiness = mContactInfoHelper.isBusiness(firstDetails.sourceType);
+
+                final int contactType =
+                        isVoicemailNumber? ContactPhotoManager.TYPE_VOICEMAIL :
+                        isBusiness ? ContactPhotoManager.TYPE_BUSINESS :
+                        ContactPhotoManager.TYPE_DEFAULT;
+
+                loadContactPhotos(photoUri, displayNameForDefaultImage, lookupKey, contactType);
                 findViewById(R.id.call_detail).setVisibility(View.VISIBLE);
             }
         }
@@ -690,6 +705,7 @@
             final CharSequence numberLabel;
             final Uri photoUri;
             final Uri lookupUri;
+            int sourceType;
             // If this is not a regular number, there is no point in looking it up in the contacts.
             ContactInfo info =
                     PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)
@@ -704,6 +720,7 @@
                 numberLabel = "";
                 photoUri = null;
                 lookupUri = null;
+                sourceType = 0;
             } else {
                 formattedNumber = info.formattedNumber;
                 nameText = info.name;
@@ -711,11 +728,12 @@
                 numberLabel = info.label;
                 photoUri = info.photoUri;
                 lookupUri = info.lookupUri;
+                sourceType = info.sourceType;
             }
             return new PhoneCallDetails(number, numberPresentation,
                     formattedNumber, countryIso, geocode,
                     new int[]{ callType }, date, duration,
-                    nameText, numberType, numberLabel, lookupUri, photoUri);
+                    nameText, numberType, numberLabel, lookupUri, photoUri, sourceType);
         } finally {
             if (callCursor != null) {
                 callCursor.close();
@@ -724,9 +742,12 @@
     }
 
     /** Load the contact photos and places them in the corresponding views. */
-    private void loadContactPhotos(Uri photoUri) {
+    private void loadContactPhotos(Uri photoUri, String displayName, String lookupKey,
+            int contactType) {
+        final DefaultImageRequest request = new DefaultImageRequest(displayName, lookupKey,
+                contactType);
         mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri,
-                mContactBackgroundView.getWidth(), true);
+                mContactBackgroundView.getWidth(), true, request);
     }
 
     static final class ViewEntry {
diff --git a/src/com/android/dialer/PhoneCallDetails.java b/src/com/android/dialer/PhoneCallDetails.java
index c380b65..4e01ab5 100644
--- a/src/com/android/dialer/PhoneCallDetails.java
+++ b/src/com/android/dialer/PhoneCallDetails.java
@@ -59,13 +59,17 @@
      * This is meant to store the high-res photo only.
      */
     public final Uri photoUri;
+    /**
+     * The source type of the contact associated with this call.
+     */
+    public final int sourceType;
 
     /** 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) {
         this(number, numberPresentation, formattedNumber, countryIso, geocode,
-                callTypes, date, duration, "", 0, "", null, null);
+                callTypes, date, duration, "", 0, "", null, null, 0);
     }
 
     /** Create the details for a call with a number associated with a contact. */
@@ -73,7 +77,7 @@
             CharSequence formattedNumber, String countryIso, String geocode,
             int[] callTypes, long date, long duration, CharSequence name,
             int numberType, CharSequence numberLabel, Uri contactUri,
-            Uri photoUri) {
+            Uri photoUri, int sourceType) {
         this.number = number;
         this.numberPresentation = numberPresentation;
         this.formattedNumber = formattedNumber;
@@ -87,5 +91,6 @@
         this.numberLabel = numberLabel;
         this.contactUri = contactUri;
         this.photoUri = photoUri;
+        this.sourceType = sourceType;
     }
 }
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 32699e6..175a733 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -27,6 +27,7 @@
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.PhoneLookup;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -37,11 +38,13 @@
 
 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.PhoneCallDetails;
 import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
 import com.android.dialer.util.ExpirableCache;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 
@@ -537,6 +540,9 @@
 
         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.
@@ -569,7 +575,7 @@
                 mContactInfoCache.getCachedValue(numberCountryIso);
         ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue();
         if (!PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)
-                || new PhoneNumberUtilsWrapper().isVoicemailNumber(number)) {
+                || isVoicemailNumber) {
             // If this is a number that cannot be dialed, there is no point in looking up a contact
             // for it.
             info = ContactInfo.EMPTY;
@@ -609,6 +615,7 @@
         CharSequence formattedNumber = info.formattedNumber;
         final int[] callTypes = getCallTypes(c, count);
         final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
+        final int sourceType = info.sourceType;
         final PhoneCallDetails details;
 
         if (TextUtils.isEmpty(name)) {
@@ -618,7 +625,7 @@
         } else {
             details = new PhoneCallDetails(number, numberPresentation,
                     formattedNumber, countryIso, geocode, callTypes, date,
-                    duration, name, ntype, label, lookupUri, photoUri);
+                    duration, name, ntype, label, lookupUri, photoUri, sourceType);
         }
 
         final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
@@ -627,10 +634,32 @@
         mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted,
                 mShowSecondaryActionButton);
 
-        if (photoId == 0 && photoUri != null) {
-            setPhoto(views, photoUri, lookupUri);
+        int contactType = ContactPhotoManager.TYPE_DEFAULT;
+
+        if (isVoicemailNumber) {
+            contactType = ContactPhotoManager.TYPE_VOICEMAIL;
+        } else if (mContactInfoHelper.isBusiness(info.sourceType)) {
+            contactType = ContactPhotoManager.TYPE_BUSINESS;
+        }
+
+        String lookupKey = info.lookupKey;
+        if (lookupUri != null) {
+            //lookupKey = ContactInfoHelper.getLookupKeyFromUri(lookupUri);
+
+        }
+
+        String nameForDefaultImage = null;
+        if (TextUtils.isEmpty(name)) {
+            nameForDefaultImage = mPhoneNumberHelper.getDisplayNumber(details.number,
+                    details.numberPresentation, details.formattedNumber).toString();
         } else {
-            setPhoto(views, photoId, lookupUri);
+            nameForDefaultImage = name;
+        }
+
+        if (photoId == 0 && photoUri != null) {
+            setPhoto(views, photoUri, lookupUri, nameForDefaultImage, lookupKey, contactType);
+        } else {
+            setPhoto(views, photoId, lookupUri, nameForDefaultImage, lookupKey, contactType);
         }
 
         // Listen for the first draw
@@ -853,15 +882,22 @@
         return callTypes;
     }
 
-    private void setPhoto(CallLogListItemViews views, long photoId, Uri contactUri) {
+    private void setPhoto(CallLogListItemViews views, long photoId, Uri contactUri,
+            String displayName, String identifier, int contactType) {
         views.quickContactView.assignContactUri(contactUri);
-        mContactPhotoManager.loadThumbnail(views.quickContactView, photoId, false /* darkTheme */);
+        DefaultImageRequest request = new DefaultImageRequest(displayName, identifier,
+                contactType);
+        mContactPhotoManager.loadThumbnail(views.quickContactView, photoId, false /* darkTheme */,
+                request);
     }
 
-    private void setPhoto(CallLogListItemViews views, Uri photoUri, Uri contactUri) {
+    private void setPhoto(CallLogListItemViews views, Uri photoUri, Uri contactUri,
+            String displayName, String identifier, int contactType) {
         views.quickContactView.assignContactUri(contactUri);
+        DefaultImageRequest request = new DefaultImageRequest(displayName, identifier,
+                contactType);
         mContactPhotoManager.loadDirectoryPhoto(views.quickContactView, photoUri,
-                false /* darkTheme */);
+                false /* darkTheme */, request);
     }
 
 
diff --git a/src/com/android/dialer/calllog/ContactInfo.java b/src/com/android/dialer/calllog/ContactInfo.java
index 601f552..41afa5a 100644
--- a/src/com/android/dialer/calllog/ContactInfo.java
+++ b/src/com/android/dialer/calllog/ContactInfo.java
@@ -27,6 +27,7 @@
  */
 public class ContactInfo {
     public Uri lookupUri;
+    public String lookupKey;
     public String name;
     public int type;
     public String label;
diff --git a/src/com/android/dialer/calllog/ContactInfoHelper.java b/src/com/android/dialer/calllog/ContactInfoHelper.java
index d248c70..84ce27e 100644
--- a/src/com/android/dialer/calllog/ContactInfoHelper.java
+++ b/src/com/android/dialer/calllog/ContactInfoHelper.java
@@ -1,17 +1,15 @@
 /*
  * Copyright (C) 2011 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
+ * 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
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
  */
 
 package com.android.dialer.calllog;
@@ -37,6 +35,8 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.util.List;
+
 /**
  * Utility class to look up the contact information for a given number.
  */
@@ -101,7 +101,7 @@
                 updatedInfo = new ContactInfo();
                 updatedInfo.number = number;
                 updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
-                updatedInfo.lookupUri = createTemporaryContactUri(number);
+                updatedInfo.lookupUri = createTemporaryContactUri(updatedInfo.formattedNumber);
             } else {
                 updatedInfo = info;
             }
@@ -113,23 +113,20 @@
      * Creates a JSON-encoded lookup uri for a unknown number without an associated contact
      *
      * @param number - Unknown phone number
-     * @return JSON-encoded URI that can be used to perform a lookup when clicking
-     * on the quick contact card.
+     * @return JSON-encoded URI that can be used to perform a lookup when clicking on the quick
+     *         contact card.
      */
     private static Uri createTemporaryContactUri(String number) {
         try {
-            final JSONObject contactRows = new JSONObject()
-                    .put(Phone.CONTENT_ITEM_TYPE, new JSONObject()
-                            .put(Phone.NUMBER, number)
-                                    .put(Phone.TYPE, Phone.TYPE_CUSTOM));
+            final JSONObject contactRows = new JSONObject().put(Phone.CONTENT_ITEM_TYPE,
+                    new JSONObject().put(Phone.NUMBER, number).put(Phone.TYPE, Phone.TYPE_CUSTOM));
 
-            final String jsonString = new JSONObject()
-                    .put(Contacts.DISPLAY_NAME, number)
-                            .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE)
-                            .put(Contacts.CONTENT_ITEM_TYPE, contactRows)
-                            .toString();
+            final String jsonString = new JSONObject().put(Contacts.DISPLAY_NAME, number)
+                    .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE)
+                    .put(Contacts.CONTENT_ITEM_TYPE, contactRows).toString();
 
-            return Contacts.CONTENT_LOOKUP_URI.buildUpon()
+            return Contacts.CONTENT_LOOKUP_URI
+                    .buildUpon()
                     .appendPath(Constants.LOOKUP_URI_ENCODED)
                     .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
                             String.valueOf(Long.MAX_VALUE))
@@ -152,8 +149,7 @@
     private ContactInfo lookupContactFromUri(Uri uri) {
         final ContactInfo info;
         Cursor phonesCursor =
-                mContext.getContentResolver().query(
-                        uri, PhoneQuery._PROJECTION, null, null, null);
+                mContext.getContentResolver().query(uri, PhoneQuery._PROJECTION, null, null, null);
 
         if (phonesCursor != null) {
             try {
@@ -161,6 +157,7 @@
                     info = new ContactInfo();
                     long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
                     String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
+                    info.lookupKey = lookupKey;
                     info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                     info.name = phonesCursor.getString(PhoneQuery.NAME);
                     info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
@@ -230,8 +227,8 @@
         if (info != null && info != ContactInfo.EMPTY) {
             info.formattedNumber = formatPhoneNumber(number, null, countryIso);
         } else if (mCachedNumberLookupService != null) {
-            CachedContactInfo cacheInfo = mCachedNumberLookupService
-                .lookupCachedContactFromNumber(mContext, number);
+            CachedContactInfo cacheInfo =
+                    mCachedNumberLookupService.lookupCachedContactFromNumber(mContext, number);
             info = cacheInfo != null ? cacheInfo.getContactInfo() : null;
         }
         return info;
@@ -242,14 +239,12 @@
      *
      * @param number the number to be formatted.
      * @param normalizedNumber the normalized number of the given number.
-     * @param countryIso the ISO 3166-1 two letters country code, the country's
-     *        convention will be used to format the number if the normalized
-     *        phone is null.
+     * @param countryIso the ISO 3166-1 two letters country code, the country's convention will be
+     *        used to format the number if the normalized phone is null.
      *
      * @return the formatted number, or the given number if it was formatted.
      */
-    private String formatPhoneNumber(String number, String normalizedNumber,
-            String countryIso) {
+    private String formatPhoneNumber(String number, String normalizedNumber, String countryIso) {
         if (TextUtils.isEmpty(number)) {
             return "";
         }
@@ -262,4 +257,32 @@
         }
         return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso);
     }
+
+    /**
+     * Parses the given URI to determine the original lookup key of the contact.
+     */
+    public static String getLookupKeyFromUri(Uri lookupUri) {
+        // Would be nice to be able to persist the lookup key somehow to avoid having to parse
+        // the uri entirely just to retrieve the lookup key, but every uri is already parsed
+        // once anyway to check if it is an encoded JSON uri, so this has negligible effect
+        // on performance.
+        if (lookupUri != null && !UriUtils.isEncodedContactUri(lookupUri)) {
+            final List<String> segments = lookupUri.getPathSegments();
+            // This returns the third path segment of the uri, where the lookup key is located.
+            // See {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
+            return (segments.size() < 3) ? null : segments.get(2);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Given a contact's sourceType, return true if the contact is a business
+     *
+     * @param sourceType sourceType of the contact. This is usually populated by
+     *        {@link #mCachedNumberLookupService}.
+     */
+    public boolean isBusiness(int sourceType) {
+        return mCachedNumberLookupService.isBusiness(sourceType);
+    }
 }
diff --git a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
index 9c83768..00a260a 100644
--- a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
+++ b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
@@ -30,7 +30,7 @@
  *
  */
 public class PhoneNumberUtilsWrapper {
-    private static final PhoneNumberUtilsWrapper INSTANCE = new PhoneNumberUtilsWrapper();
+    public static final PhoneNumberUtilsWrapper INSTANCE = new PhoneNumberUtilsWrapper();
     private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3");
 
     /** Returns true if it is possible to place a call to the given number. */
diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java
index 5bfe11a..95249a6 100644
--- a/src/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/src/com/android/dialer/database/DialerDatabaseHelper.java
@@ -163,6 +163,17 @@
         /** Selects only rows that have been updated after a certain time stamp.*/
         static final String SELECT_UPDATED_CLAUSE =
                 Phone.CONTACT_LAST_UPDATED_TIMESTAMP + " > ?";
+
+        /** Ignores contacts that have an unreasonably long lookup key. These are likely to be
+         * the result of multiple (> 50) merged raw contacts, and are likely to cause
+         * OutOfMemoryExceptions within SQLite, or cause memory allocation problems later on
+         * when iterating through the cursor set (see b/13133579)
+         */
+        static final String SELECT_IGNORE_LOOKUP_KEY_TOO_LONG_CLAUSE =
+                "length(" + Phone.LOOKUP_KEY + ") < 1000";
+
+        static final String SELECTION = SELECT_UPDATED_CLAUSE + " AND " +
+                SELECT_IGNORE_LOOKUP_KEY_TOO_LONG_CLAUSE;
     }
 
     /** Query options for querying the deleted contact database.*/
@@ -658,7 +669,6 @@
                 } else {
                     insert.bindString(5, displayName);
                 }
-
                 insert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_ID));
                 insert.bindLong(3, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
                 insert.bindLong(6, updatedContactCursor.getLong(PhoneQuery.PHONE_PHOTO_ID));
@@ -758,7 +768,7 @@
              * update time.
              */
             final Cursor updatedContactCursor = mContext.getContentResolver().query(PhoneQuery.URI,
-                    PhoneQuery.PROJECTION, PhoneQuery.SELECT_UPDATED_CLAUSE,
+                    PhoneQuery.PROJECTION, PhoneQuery.SELECTION,
                     new String[]{lastUpdateMillis}, null);
 
             /** Sets the time after querying the database as the current update time. */
diff --git a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
index e855c88..181d602 100644
--- a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
@@ -62,24 +62,12 @@
     public void loadFromContact(ContactEntry entry) {
         super.loadFromContact(entry);
         if (entry != null) {
-            final boolean contactIsFavorite = entry.isFavorite;
-            mSecondaryButton.setVisibility(contactIsFavorite ? GONE : VISIBLE);
-
-            if (contactIsFavorite) {
-                mStarView.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        launchQuickContact();
-                    }
-                });
-            } else {
-                mSecondaryButton.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        launchQuickContact();
-                    }
-                });
-            }
+            mSecondaryButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    launchQuickContact();
+                }
+            });
         }
     }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java
index ecf5616..697a481 100644
--- a/src/com/android/dialer/list/PhoneFavoriteTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java
@@ -30,7 +30,9 @@
 import android.view.View;
 import android.widget.ImageView;
 
+import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.list.ContactEntry;
 import com.android.contacts.common.list.ContactTileView;
 import com.android.dialer.R;
@@ -49,6 +51,12 @@
     private static final String TAG = PhoneFavoriteTileView.class.getSimpleName();
     private static final boolean DEBUG = false;
 
+    // These parameters instruct the photo manager to display the default image/letter at 80% of
+    // its normal size, and vertically offset upwards 20% towards the top of the letter tile, to
+    // make room for the contact name and number label at the bottom of the image.
+    private static final float DEFAULT_IMAGE_LETTER_OFFSET = -0.2f;
+    private static final float DEFAULT_IMAGE_LETTER_SCALE = 0.8f;
+
     /** Length of all animations in miniseconds. */
     private int mAnimationDuration;
 
@@ -60,8 +68,6 @@
     private View mUndoRemovalButton;
     /** The view that holds the list view row. */
     protected ContactTileRow mParentRow;
-    /** The view that indicates whether the contact is a favorate. */
-    protected ImageView mStarView;
 
     /** Users' most frequent phone number. */
     private String mPhoneNumberString;
@@ -89,7 +95,6 @@
         mRemovalDialogue = findViewById(com.android.dialer.R.id.favorite_remove_dialogue);
         mUndoRemovalButton = findViewById(com.android.dialer.R.id
                 .favorite_remove_undo_button);
-        mStarView = (ImageView) findViewById(com.android.dialer.R.id.contact_favorite_star);
 
         mUndoRemovalButton.setOnClickListener(new OnClickListener() {
             @Override
@@ -127,7 +132,6 @@
             // Grab the phone-number to call directly... see {@link onClick()}
             mPhoneNumberString = entry.phoneNumber;
 
-            mStarView.setVisibility(entry.isFavorite ? VISIBLE : GONE);
             // If this is a blank entry, don't show anything.
             // TODO krelease:Just hide the view for now. For this to truly look like an empty row
             // the entire ContactTileRow needs to be hidden.
@@ -240,4 +244,10 @@
             }
         };
     }
+
+    @Override
+    protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
+        return new DefaultImageRequest(displayName, lookupKey, ContactPhotoManager.TYPE_DEFAULT,
+                DEFAULT_IMAGE_LETTER_SCALE, DEFAULT_IMAGE_LETTER_OFFSET);
+    }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index 45cc5a3..d1ac955 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -298,7 +298,8 @@
             contact.name = (!TextUtils.isEmpty(name)) ? name :
                     mResources.getString(R.string.missing_name);
             contact.photoUri = (photoUri != null ? Uri.parse(photoUri) : null);
-            contact.lookupKey = ContentUris.withAppendedId(
+            contact.lookupKey = lookupKey;
+            contact.lookupUri = ContentUris.withAppendedId(
                     Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), id);
             contact.isFavorite = isStarred;
             contact.isDefaultNumber = isDefaultNumber;
@@ -667,7 +668,7 @@
         boolean removed = false;
         if (isIndexInBound(mPotentialRemoveEntryIndex)) {
             final ContactEntry entry = mContactEntries.get(mPotentialRemoveEntryIndex);
-            unstarAndUnpinContact(entry.lookupKey);
+            unstarAndUnpinContact(entry.lookupUri);
             removed = true;
             mAwaitingRemove = true;
         }
@@ -1234,7 +1235,7 @@
     @Override
     public void onDroppedOnRemove() {
         if (mDraggedEntry != null) {
-            unstarAndUnpinContact(mDraggedEntry.lookupKey);
+            unstarAndUnpinContact(mDraggedEntry.lookupUri);
             mAwaitingRemove = true;
         }
     }
diff --git a/src/com/android/dialer/service/CachedNumberLookupService.java b/src/com/android/dialer/service/CachedNumberLookupService.java
index 5745c9d..73fd895 100644
--- a/src/com/android/dialer/service/CachedNumberLookupService.java
+++ b/src/com/android/dialer/service/CachedNumberLookupService.java
@@ -33,6 +33,8 @@
 
     public boolean isCacheUri(String uri);
 
+    public boolean isBusiness(int sourceType);
+
     public boolean addPhoto(Context context, String number, byte[] photo);
 
     /**
diff --git a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
index 6f5a986..9b7d9de 100644
--- a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
@@ -335,6 +335,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));
+                        name, 0, "", null, null, 0));
     }
 }