From 36aeec91ed927b7fe3a27bcd5e224443899117f1 Mon Sep 17 00:00:00 2001 From: Brandon Maxwell Date: Fri, 23 Oct 2015 12:01:00 -0700 Subject: CallDetailActivity respect display name order - Updated the CallDetailActivity to choose whether to show last name first or first name first based on user preferences. - Modified callLog code to behave in a similar fashion - Fixed bug in ContactInfoHelperTests - Rename PhoneCallDetails.name -> PhoneCallDetails.namePrimary Bug: 19364093 Change-Id: I50971ad0f26f6ede49f1c82965d1b00ce0cba4d3 --- src/com/android/dialer/CallDetailActivity.java | 18 ++-- src/com/android/dialer/PhoneCallDetails.java | 25 ++++- src/com/android/dialer/calllog/CallLogAdapter.java | 7 +- .../dialer/calllog/CallLogAsyncTaskUtil.java | 3 +- .../dialer/calllog/CallLogListItemHelper.java | 4 +- .../dialer/calllog/PhoneCallDetailsHelper.java | 12 +-- .../android/dialer/calllog/CallLogAdapterTest.java | 112 ++++++++++++++++++--- .../dialer/calllog/ContactInfoHelperTest.java | 2 +- .../dialer/calllog/PhoneCallDetailsHelperTest.java | 4 +- 9 files changed, 152 insertions(+), 35 deletions(-) diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java index 284a5785e..2aff61c4c 100644 --- a/src/com/android/dialer/CallDetailActivity.java +++ b/src/com/android/dialer/CallDetailActivity.java @@ -24,7 +24,6 @@ import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.v7.app.AppCompatActivity; -import android.telecom.PhoneAccountHandle; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; @@ -45,6 +44,7 @@ import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; import com.android.contacts.common.ContactPhotoManager; import com.android.contacts.common.GeoUtil; import com.android.contacts.common.interactions.TouchPointManager; +import com.android.contacts.common.preference.ContactsPreferences; import com.android.contacts.common.testing.NeededForTesting; import com.android.contacts.common.util.UriUtils; import com.android.dialer.calllog.CallDetailHistoryAdapter; @@ -109,7 +109,6 @@ public class CallDetailActivity extends AppCompatActivity mDetails = details[0]; mNumber = TextUtils.isEmpty(mDetails.number) ? null : mDetails.number.toString(); mDisplayNumber = mDetails.displayNumber; - final int numberPresentation = mDetails.numberPresentation; final CharSequence callLocationOrType = getNumberTypeOrLocation(mDetails); @@ -117,8 +116,10 @@ public class CallDetailActivity extends AppCompatActivity final String displayNumberStr = mBidiFormatter.unicodeWrap( displayNumber.toString(), TextDirectionHeuristics.LTR); - if (!TextUtils.isEmpty(mDetails.name)) { - mCallerName.setText(mDetails.name); + mDetails.nameDisplayOrder = mContactsPreferences.getDisplayOrder(); + + if (!TextUtils.isEmpty(mDetails.getPreferredName())) { + mCallerName.setText(mDetails.getPreferredName()); mCallerNumber.setText(callLocationOrType + " " + displayNumberStr); } else { mCallerName.setText(displayNumberStr); @@ -174,7 +175,7 @@ public class CallDetailActivity extends AppCompatActivity * @return The phone number type or location. */ private CharSequence getNumberTypeOrLocation(PhoneCallDetails details) { - if (!TextUtils.isEmpty(details.name)) { + if (!TextUtils.isEmpty(details.namePrimary)) { return Phone.getTypeLabel(mResources, details.numberType, details.numberLabel); } else { @@ -185,6 +186,7 @@ public class CallDetailActivity extends AppCompatActivity private Context mContext; private ContactInfoHelper mContactInfoHelper; + private ContactsPreferences mContactsPreferences; private CallTypeHelper mCallTypeHelper; private ContactPhotoManager mContactPhotoManager; private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; @@ -223,6 +225,7 @@ public class CallDetailActivity extends AppCompatActivity mContext = this; mResources = getResources(); mContactInfoHelper = new ContactInfoHelper(this, GeoUtil.getCurrentCountryIso(this)); + mContactsPreferences = new ContactsPreferences(mContext); mCallTypeHelper = new CallTypeHelper(getResources()); mFilteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(getContentResolver()); @@ -280,6 +283,7 @@ public class CallDetailActivity extends AppCompatActivity @Override public void onResume() { super.onResume(); + mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY); getCallDetails(); } @@ -436,8 +440,8 @@ public class CallDetailActivity extends AppCompatActivity contactType = ContactPhotoManager.TYPE_BUSINESS; } - final String displayName = TextUtils.isEmpty(mDetails.name) - ? mDetails.displayNumber : mDetails.name.toString(); + final String displayName = TextUtils.isEmpty(mDetails.namePrimary) + ? mDetails.displayNumber : mDetails.namePrimary.toString(); final String lookupKey = mDetails.contactUri == null ? null : UriUtils.getLookupKeyFromUri(mDetails.contactUri); diff --git a/src/com/android/dialer/PhoneCallDetails.java b/src/com/android/dialer/PhoneCallDetails.java index 403c4e86c..fb1827dc4 100644 --- a/src/com/android/dialer/PhoneCallDetails.java +++ b/src/com/android/dialer/PhoneCallDetails.java @@ -16,12 +16,14 @@ package com.android.dialer; +import com.android.contacts.common.preference.ContactsPreferences; import com.android.dialer.calllog.PhoneNumberDisplayUtil; import android.content.Context; import android.net.Uri; import android.provider.CallLog.Calls; import android.telecom.PhoneAccountHandle; +import android.text.TextUtils; /** * The details of a phone call to be shown in the UI. @@ -50,7 +52,14 @@ public class PhoneCallDetails { // The duration of the call in milliseconds, or 0 for missed calls. public long duration; // The name of the contact, or the empty string. - public CharSequence name; + public CharSequence namePrimary; + // The alternative name of the contact, e.g. last name first, or the empty string + public CharSequence nameAlternative; + /** + * The user's preference on name display order, last name first or first time first. + * {@see ContactsPreferences} + */ + public int nameDisplayOrder; // The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. public int numberType; // The custom label associated with the phone number in the contact, or the empty string. @@ -117,4 +126,18 @@ public class PhoneCallDetails { this.formattedNumber, this.isVoicemail).toString(); } + + /** + * Returns the preferred name for the call details as specified by the + * {@link #nameDisplayOrder} + * + * @return the preferred name + */ + public CharSequence getPreferredName() { + if (nameDisplayOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY + || TextUtils.isEmpty(nameAlternative)) { + return namePrimary; + } + return nameAlternative; + } } diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index ae20e4943..01af982f3 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -465,10 +465,11 @@ public class CallLogAdapter extends GroupingListAdapter details.dataUsage = c.getLong(CallLogQuery.DATA_USAGE); } - String preferredName = getPreferredDisplayName(info); - if (!TextUtils.isEmpty(preferredName)) { + if (!TextUtils.isEmpty(info.name) || !TextUtils.isEmpty(info.nameAlternative)) { details.contactUri = info.lookupUri; - details.name = preferredName; + details.namePrimary = info.name; + details.nameAlternative = info.nameAlternative; + details.nameDisplayOrder = mContactsPreferences.getDisplayOrder(); details.numberType = info.type; details.numberLabel = info.label; details.photoUri = info.photoUri; diff --git a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java index 89932ffce..2fffaff8d 100644 --- a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java +++ b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java @@ -189,7 +189,8 @@ public class CallLogAsyncTaskUtil { details.accountHandle = accountHandle; details.contactUri = info.lookupUri; - details.name = info.name; + details.namePrimary = info.name; + details.nameAlternative = info.nameAlternative; details.numberType = info.type; details.numberLabel = info.label; details.photoUri = info.photoUri; diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java index 84d036487..f856bf924 100644 --- a/src/com/android/dialer/calllog/CallLogListItemHelper.java +++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java @@ -260,8 +260,8 @@ import com.android.dialer.R; */ private CharSequence getNameOrNumber(PhoneCallDetails details) { final CharSequence recipient; - if (!TextUtils.isEmpty(details.name)) { - recipient = details.name; + if (!TextUtils.isEmpty(details.getPreferredName())) { + recipient = details.getPreferredName(); } else { recipient = details.displayNumber; } diff --git a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java index b16079a9c..96dbf8219 100644 --- a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java +++ b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java @@ -132,12 +132,12 @@ public class PhoneCallDetailsHelper { final CharSequence nameText; final CharSequence displayNumber = details.displayNumber; - if (TextUtils.isEmpty(details.name)) { + if (TextUtils.isEmpty(details.getPreferredName())) { nameText = displayNumber; // We have a real phone number as "nameView" so make it always LTR views.nameView.setTextDirection(View.TEXT_DIRECTION_LTR); } else { - nameText = details.name; + nameText = details.getPreferredName(); } views.nameView.setText(nameText); @@ -200,7 +200,7 @@ public class PhoneCallDetailsHelper { && !PhoneNumberHelper.isUriNumber(details.number.toString()) && !mTelecomCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) { - if (TextUtils.isEmpty(details.name) && !TextUtils.isEmpty(details.geocode)) { + if (TextUtils.isEmpty(details.namePrimary) && !TextUtils.isEmpty(details.geocode)) { numberFormattedLabel = details.geocode; } else if (!(details.numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(details.numberLabel))) { @@ -210,7 +210,7 @@ public class PhoneCallDetailsHelper { } } - if (!TextUtils.isEmpty(details.name) && TextUtils.isEmpty(numberFormattedLabel)) { + if (!TextUtils.isEmpty(details.namePrimary) && TextUtils.isEmpty(numberFormattedLabel)) { numberFormattedLabel = details.displayNumber; } return numberFormattedLabel; @@ -284,8 +284,8 @@ public class PhoneCallDetailsHelper { @NeededForTesting public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) { final CharSequence nameText; - if (!TextUtils.isEmpty(details.name)) { - nameText = details.name; + if (!TextUtils.isEmpty(details.namePrimary)) { + nameText = details.namePrimary; } else if (!TextUtils.isEmpty(details.displayNumber)) { nameText = details.displayNumber; } else { diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java index bdd5dc584..a5a61ad46 100644 --- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java +++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java @@ -24,17 +24,13 @@ import android.net.Uri; import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.VoicemailContract; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.telephony.PhoneNumberUtils; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.view.View; +import com.android.contacts.common.preference.ContactsPreferences; import com.android.dialer.contactinfo.ContactInfoCache; -import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener; import com.android.dialer.util.AppCompatConstants; import com.android.dialer.util.TestConstants; import com.google.common.collect.Lists; @@ -54,7 +50,10 @@ public class CallLogAdapterTest extends AndroidTestCase { private static final String EMPTY_STRING = ""; private static final int NO_VALUE_SET = -1; - private static final String TEST_CACHED_NAME = "name"; + private static final String TEST_CACHED_NAME_PRIMARY = "Cached Name"; + private static final String TEST_CACHED_NAME_ALTERNATIVE = "Name Cached"; + private static final String CONTACT_NAME_PRIMARY = "Contact Name"; + private static final String CONTACT_NAME_ALTERNATIVE = "Name, Contact"; private static final String TEST_CACHED_NUMBER_LABEL = "label"; private static final int TEST_CACHED_NUMBER_TYPE = 1; private static final String TEST_COUNTRY_ISO = "US"; @@ -176,6 +175,63 @@ public class CallLogAdapterTest extends AndroidTestCase { assertHasCallAction(mViewHolder); } + @MediumTest + public void testBindView_FirstNameFirstOrder() { + createCallLogEntry(); + + mAdapter.getContactInfoCache() + .mockGetValue(createContactInfo(CONTACT_NAME_PRIMARY, CONTACT_NAME_ALTERNATIVE)); + + setNameDisplayOrder(getContext(), ContactsPreferences.DISPLAY_ORDER_PRIMARY); + + mAdapter.changeCursor(mCursor); + mAdapter.onBindViewHolder(mViewHolder, 0); + assertEquals(CONTACT_NAME_PRIMARY, mViewHolder.phoneCallDetailsViews.nameView.getText()); + } + + @MediumTest + public void testBindView_LastNameFirstOrder() { + createCallLogEntry(); + + mAdapter.getContactInfoCache() + .mockGetValue(createContactInfo(CONTACT_NAME_PRIMARY, CONTACT_NAME_ALTERNATIVE)); + + setNameDisplayOrder(getContext(), ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE); + + mAdapter.changeCursor(mCursor); + mAdapter.onBindViewHolder(mViewHolder, 0); + assertEquals(CONTACT_NAME_ALTERNATIVE, + mViewHolder.phoneCallDetailsViews.nameView.getText()); + } + + @MediumTest + public void testBindView_NameOrderCorrectOnChange() { + createCallLogEntry(); + + mAdapter.getContactInfoCache() + .mockGetValue(createContactInfo(CONTACT_NAME_PRIMARY, CONTACT_NAME_ALTERNATIVE)); + + Context context = getContext(); + setNameDisplayOrder(context, ContactsPreferences.DISPLAY_ORDER_PRIMARY); + + mAdapter.changeCursor(mCursor); + mAdapter.onBindViewHolder(mViewHolder, 0); + assertEquals(CONTACT_NAME_PRIMARY, + mViewHolder.phoneCallDetailsViews.nameView.getText()); + + setNameDisplayOrder(context, ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE); + mAdapter.onResume(); + + mAdapter.onBindViewHolder(mViewHolder, 0); + assertEquals(CONTACT_NAME_ALTERNATIVE, + mViewHolder.phoneCallDetailsViews.nameView.getText()); + } + + private void setNameDisplayOrder(Context context, int displayOrder) { + context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE).edit().putInt( + ContactsPreferences.DISPLAY_ORDER_KEY, displayOrder).commit(); + } + @MediumTest public void testBindView_VoicemailUri() { createVoicemailCallLogEntry(); @@ -278,7 +334,7 @@ public class CallLogAdapterTest extends AndroidTestCase { TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0); // The values passed to the request, match the ones in the call log cache. - assertEquals(TEST_CACHED_NAME, request.callLogInfo.name); + assertEquals(TEST_CACHED_NAME_PRIMARY, request.callLogInfo.name); assertEquals(TEST_CACHED_NUMBER_TYPE, request.callLogInfo.type); assertEquals(TEST_CACHED_NUMBER_LABEL, request.callLogInfo.label); } @@ -487,7 +543,7 @@ public class CallLogAdapterTest extends AndroidTestCase { createCallLogEntryWithCachedValues( TEST_NUMBER, NO_VALUE_SET, - TEST_CACHED_NAME, + TEST_CACHED_NAME_PRIMARY, TEST_CACHED_NUMBER_TYPE, TEST_CACHED_NUMBER_LABEL, EMPTY_STRING, @@ -537,7 +593,7 @@ public class CallLogAdapterTest extends AndroidTestCase { if (inject) { ContactInfo contactInfo = - createContactInfo(cachedName, cachedNumberType, cachedNumberLabel); + createContactInfo(cachedName, cachedName, cachedNumberType, cachedNumberLabel); mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo); } } @@ -578,16 +634,24 @@ public class CallLogAdapterTest extends AndroidTestCase { private ContactInfo createContactInfo() { return createContactInfo( - TEST_CACHED_NAME, + TEST_CACHED_NAME_PRIMARY, + TEST_CACHED_NAME_ALTERNATIVE); + } + + private ContactInfo createContactInfo(String namePrimary, String nameAlternative) { + return createContactInfo( + namePrimary, + nameAlternative, TEST_CACHED_NUMBER_TYPE, TEST_CACHED_NUMBER_LABEL); } /** Returns a contact info with default values. */ - private ContactInfo createContactInfo(String name, int type, String label) { + private ContactInfo createContactInfo(String namePrimary, String nameAlternative, int type, String label) { ContactInfo info = new ContactInfo(); info.number = TEST_NUMBER; - info.name = name; + info.name = namePrimary; + info.nameAlternative = nameAlternative; info.type = type; info.label = label; info.formattedNumber = TEST_FORMATTED_NUMBER; @@ -663,11 +727,35 @@ public class CallLogAdapterTest extends AndroidTestCase { public final List requests = Lists.newArrayList(); + /** + * Dummy contactInfo to return in the even that the getValue method has been mocked + */ + private ContactInfo mContactInfo; + public TestContactInfoCache( ContactInfoHelper contactInfoHelper, OnContactInfoChangedListener listener) { super(contactInfoHelper, listener); } + /** + * Sets the given value to be returned by all calls to + * {@link #getValue(String, String, ContactInfo)} + * + * @param contactInfo the contactInfo + */ + public void mockGetValue(ContactInfo contactInfo) { + this.mContactInfo = contactInfo; + } + + @Override + public ContactInfo getValue(String number, String countryIso, + ContactInfo cachedContactInfo) { + if (mContactInfo != null) { + return mContactInfo; + } + return super.getValue(number, countryIso, cachedContactInfo); + } + @Override protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo, boolean immediate) { diff --git a/tests/src/com/android/dialer/calllog/ContactInfoHelperTest.java b/tests/src/com/android/dialer/calllog/ContactInfoHelperTest.java index 6d3e86042..6db738443 100644 --- a/tests/src/com/android/dialer/calllog/ContactInfoHelperTest.java +++ b/tests/src/com/android/dialer/calllog/ContactInfoHelperTest.java @@ -33,7 +33,7 @@ public class ContactInfoHelperTest extends AndroidTestCase { private static final String TEST_COUNTRY_ISO = "US"; private static final String TEST_DISPLAY_NAME = "Display Name"; private static final String TEST_DISPLAY_NAME_ALTERNATIVE = "Name, Display"; - private static final String[] TEST_DISPLAY_NAME_ALTERNATIVE_ROW = new String[]{null, + private static final String[] TEST_DISPLAY_NAME_ALTERNATIVE_ROW = new String[]{ TEST_DISPLAY_NAME_ALTERNATIVE}; private static final String TEST_LOOKUP_KEY = "lookupKey"; private static final String[] TEST_LOOKUP_ROW = new String[]{null, TEST_DISPLAY_NAME, diff --git a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java index ecbb89878..c30861c8e 100644 --- a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java +++ b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java @@ -319,7 +319,7 @@ public class PhoneCallDetailsHelperTest extends AndroidTestCase { public void testGetCallTypeOrLocation_DisplayNumber() { PhoneCallDetails details = getPhoneCallDetails("", Calls.PRESENTATION_ALLOWED, TEST_FORMATTED_NUMBER); - details.name = "name"; + details.namePrimary = "name"; assertEquals(TEST_FORMATTED_NUMBER, mHelper.getCallTypeOrLocation(details)); } @@ -418,7 +418,7 @@ public class PhoneCallDetailsHelperTest extends AndroidTestCase { private void setCallDetailsHeader(String name) { PhoneCallDetails details = getPhoneCallDetails(); - details.name = name; + details.namePrimary = name; mHelper.setCallDetailsHeader(mNameView, details); } -- cgit v1.2.3