diff options
6 files changed, 172 insertions, 94 deletions
diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java index c9c053cea..7071ab5c1 100644 --- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java +++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java @@ -42,10 +42,9 @@ public class AnnotatedCallLogContract { String TIMESTAMP = "timestamp"; /** - * Copied from {@link android.provider.CallLog.Calls#CACHED_NAME}. - * - * <p>This is exactly how it should appear to the user. If the user's locale or name display - * preferences change, this column should be rewritten. + * The name (which may be a person's name or business name, but not a number) formatted exactly + * as it should appear to the user. If the user's locale or name display preferences change, + * this column should be rewritten. * * <p>Type: TEXT */ @@ -61,28 +60,29 @@ public class AnnotatedCallLogContract { String NUMBER = "number"; /** - * Copied from {@link android.provider.CallLog.Calls#CACHED_FORMATTED_NUMBER}. + * The number formatted as it should be displayed to the user. Note that it may not always be + * displayed, for example if the number has a corresponding person or business name. * * <p>Type: TEXT */ String FORMATTED_NUMBER = "formatted_number"; /** - * Copied from {@link android.provider.CallLog.Calls#CACHED_PHOTO_URI}. + * A photo URI for the contact to display in the call log list view. * * <p>TYPE: TEXT */ String PHOTO_URI = "photo_uri"; /** - * Copied from {@link android.provider.CallLog.Calls#CACHED_PHOTO_ID}. + * A photo ID (from the contacts provider) for the contact to display in the call log list view. * * <p>Type: INTEGER (long) */ String PHOTO_ID = "photo_id"; /** - * Copied from {@link android.provider.CallLog.Calls#CACHED_LOOKUP_URI}. + * The contacts provider lookup URI for the contact associated with the call. * * <p>TYPE: TEXT */ diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java index fa7d3be16..93e841409 100644 --- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java @@ -32,6 +32,7 @@ import com.android.dialer.DialerPhoneNumber; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.CallLogMutations; +import com.android.dialer.calllog.datasources.util.RowCombiner; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.Annotations.LightweightExecutor; @@ -260,8 +261,13 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @WorkerThread @Override public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) { - // TODO(zachh): Implementation. - return new ContentValues(); + return new RowCombiner(individualRowsSortedByTimestampDesc) + .useMostRecentString(AnnotatedCallLog.NAME) + .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL) + .useMostRecentString(AnnotatedCallLog.PHOTO_URI) + .useMostRecentLong(AnnotatedCallLog.PHOTO_ID) + .useMostRecentString(AnnotatedCallLog.LOOKUP_URI) + .combine(); } @MainThread @@ -434,7 +440,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { PhoneLookupInfo phoneLookupInfo = existingInfo.get(id); // Existing info might be missing if data was cleared or for other reasons. if (phoneLookupInfo != null) { - contentValues.put(AnnotatedCallLog.NAME, selectName(phoneLookupInfo)); + updateContentValues(contentValues, phoneLookupInfo); } } } @@ -474,17 +480,17 @@ public final class PhoneLookupDataSource implements CallLogDataSource { * mutations from PhoneLookupHistory; in this case "John" would be copied during * populateInserts() and there wouldn't be further updates needed here. */ - contentValuesToInsert.put(AnnotatedCallLog.NAME, selectName(phoneLookupInfo)); + updateContentValues(contentValuesToInsert, phoneLookupInfo); continue; } ContentValues contentValuesToUpdate = mutations.getUpdates().get(id); if (contentValuesToUpdate != null) { - contentValuesToUpdate.put(AnnotatedCallLog.NAME, selectName(phoneLookupInfo)); + updateContentValues(contentValuesToUpdate, phoneLookupInfo); continue; } // Else this row is not already scheduled for insert or update and we need to schedule it. ContentValues contentValues = new ContentValues(); - contentValues.put(AnnotatedCallLog.NAME, selectName(phoneLookupInfo)); + updateContentValues(contentValues, phoneLookupInfo); mutations.getUpdates().put(id, contentValues); } } @@ -525,8 +531,17 @@ public final class PhoneLookupDataSource implements CallLogDataSource { return normalizedNumbersToDelete; } - private static String selectName(PhoneLookupInfo phoneLookupInfo) { - return PhoneLookupSelector.selectName(phoneLookupInfo); + private static void updateContentValues( + ContentValues contentValues, PhoneLookupInfo phoneLookupInfo) { + contentValues.put(AnnotatedCallLog.NAME, PhoneLookupSelector.selectName(phoneLookupInfo)); + contentValues.put( + AnnotatedCallLog.PHOTO_URI, PhoneLookupSelector.selectPhotoUri(phoneLookupInfo)); + contentValues.put( + AnnotatedCallLog.PHOTO_ID, PhoneLookupSelector.selectPhotoId(phoneLookupInfo)); + contentValues.put( + AnnotatedCallLog.LOOKUP_URI, PhoneLookupSelector.selectLookupUri(phoneLookupInfo)); + contentValues.put( + AnnotatedCallLog.NUMBER_TYPE_LABEL, PhoneLookupSelector.selectNumberLabel(phoneLookupInfo)); } private static Uri numberUri(String number) { diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index 91db915ef..0ed185966 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -27,7 +27,6 @@ import android.os.Build; import android.os.Handler; import android.provider.CallLog; import android.provider.CallLog.Calls; -import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.annotation.ColorInt; import android.support.annotation.MainThread; import android.support.annotation.Nullable; @@ -35,6 +34,7 @@ import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; +import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.ArraySet; import com.android.dialer.DialerPhoneNumber; @@ -174,23 +174,16 @@ public class SystemCallLogDataSource implements CallLogDataSource { @Override public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) { - // TODO(zachh): Complete implementation. - assertNoVoicemailsInRows(individualRowsSortedByTimestampDesc); return new RowCombiner(individualRowsSortedByTimestampDesc) .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) .useMostRecentLong(AnnotatedCallLog.NEW) - .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL) - .useMostRecentString(AnnotatedCallLog.NAME) // Two different DialerPhoneNumbers could be combined if they are different but considered // to be an "exact match" by libphonenumber; in this case we arbitrarily select the most // recent one. .useMostRecentBlob(AnnotatedCallLog.NUMBER) .useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER) - .useMostRecentString(AnnotatedCallLog.PHOTO_URI) - .useMostRecentLong(AnnotatedCallLog.PHOTO_ID) - .useMostRecentString(AnnotatedCallLog.LOOKUP_URI) .useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION) .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME) .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_ID) @@ -233,13 +226,6 @@ public class SystemCallLogDataSource implements CallLogDataSource { Calls.NUMBER, Calls.TYPE, Calls.COUNTRY_ISO, - Calls.CACHED_NAME, - Calls.CACHED_FORMATTED_NUMBER, - Calls.CACHED_PHOTO_URI, - Calls.CACHED_PHOTO_ID, - Calls.CACHED_LOOKUP_URI, - Calls.CACHED_NUMBER_TYPE, - Calls.CACHED_NUMBER_LABEL, Calls.DURATION, Calls.DATA_USAGE, Calls.TRANSCRIPTION, @@ -272,14 +258,6 @@ public class SystemCallLogDataSource implements CallLogDataSource { int numberColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER); int typeColumn = cursor.getColumnIndexOrThrow(Calls.TYPE); int countryIsoColumn = cursor.getColumnIndexOrThrow(Calls.COUNTRY_ISO); - int cachedNameColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NAME); - int cachedFormattedNumberColumn = - cursor.getColumnIndexOrThrow(Calls.CACHED_FORMATTED_NUMBER); - int cachedPhotoUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_URI); - int cachedPhotoIdColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_ID); - int cachedLookupUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_LOOKUP_URI); - int cachedNumberTypeColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_TYPE); - int cachedNumberLabelColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_LABEL); int durationsColumn = cursor.getColumnIndexOrThrow(Calls.DURATION); int dataUsageColumn = cursor.getColumnIndexOrThrow(Calls.DATA_USAGE); int transcriptionColumn = cursor.getColumnIndexOrThrow(Calls.TRANSCRIPTION); @@ -301,13 +279,6 @@ public class SystemCallLogDataSource implements CallLogDataSource { String numberAsStr = cursor.getString(numberColumn); long type = cursor.getInt(typeColumn); String countryIso = cursor.getString(countryIsoColumn); - String cachedName = cursor.getString(cachedNameColumn); - String formattedNumber = cursor.getString(cachedFormattedNumberColumn); - String cachedPhotoUri = cursor.getString(cachedPhotoUriColumn); - long cachedPhotoId = cursor.getLong(cachedPhotoIdColumn); - String cachedLookupUri = cursor.getString(cachedLookupUriColumn); - int cachedNumberType = cursor.getInt(cachedNumberTypeColumn); - String cachedNumberLabel = cursor.getString(cachedNumberLabelColumn); int duration = cursor.getInt(durationsColumn); int dataUsage = cursor.getInt(dataUsageColumn); String transcription = cursor.getString(transcriptionColumn); @@ -323,31 +294,19 @@ public class SystemCallLogDataSource implements CallLogDataSource { contentValues.put(AnnotatedCallLog.TIMESTAMP, date); if (!TextUtils.isEmpty(numberAsStr)) { - byte[] numberAsProtoBytes = - dialerPhoneNumberUtil.parse(numberAsStr, countryIso).toByteArray(); + DialerPhoneNumber dialerPhoneNumber = + dialerPhoneNumberUtil.parse(numberAsStr, countryIso); + + contentValues.put(AnnotatedCallLog.NUMBER, dialerPhoneNumber.toByteArray()); + contentValues.put( + AnnotatedCallLog.FORMATTED_NUMBER, + PhoneNumberUtils.formatNumber(numberAsStr, countryIso)); // TODO(zachh): Need to handle post-dial digits; different on N and M. - contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes); } else { contentValues.put( AnnotatedCallLog.NUMBER, DialerPhoneNumber.getDefaultInstance().toByteArray()); } - contentValues.put(AnnotatedCallLog.CALL_TYPE, type); - contentValues.put(AnnotatedCallLog.NAME, cachedName); - // TODO(zachh): Format the number using DialerPhoneNumberUtil here. - contentValues.put(AnnotatedCallLog.FORMATTED_NUMBER, formattedNumber); - contentValues.put(AnnotatedCallLog.PHOTO_URI, cachedPhotoUri); - contentValues.put(AnnotatedCallLog.PHOTO_ID, cachedPhotoId); - contentValues.put(AnnotatedCallLog.LOOKUP_URI, cachedLookupUri); - - // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just - // omit setting the label if there's no information for it. - if (cachedNumberType != 0 || cachedNumberLabel != null) { - contentValues.put( - AnnotatedCallLog.NUMBER_TYPE_LABEL, - Phone.getTypeLabel(appContext.getResources(), cachedNumberType, cachedNumberLabel) - .toString()); - } contentValues.put(AnnotatedCallLog.IS_READ, isRead); contentValues.put(AnnotatedCallLog.NEW, isNew); contentValues.put(AnnotatedCallLog.GEOCODED_LOCATION, geocodedLocation); diff --git a/java/com/android/dialer/phonelookup/PhoneLookupSelector.java b/java/com/android/dialer/phonelookup/PhoneLookupSelector.java index a746ea44f..af8b849e5 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupSelector.java +++ b/java/com/android/dialer/phonelookup/PhoneLookupSelector.java @@ -16,6 +16,8 @@ package com.android.dialer.phonelookup; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo; /** * Prioritizes information from a {@link PhoneLookupInfo}. @@ -37,11 +39,80 @@ public final class PhoneLookupSelector { */ @NonNull public static String selectName(PhoneLookupInfo phoneLookupInfo) { - if (phoneLookupInfo.getCp2Info().getCp2ContactInfoCount() > 0) { - // Arbitrarily select the first contact's name. In the future, it may make sense to join the - // names such as "Mom, Dad" in the case that multiple contacts share the same number. - return phoneLookupInfo.getCp2Info().getCp2ContactInfo(0).getName(); + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); + if (firstLocalContact != null) { + String name = firstLocalContact.getName(); + if (!name.isEmpty()) { + return firstLocalContact.getName(); + } + } + return ""; + } + + /** Select the photo URI associated with this number. */ + @NonNull + public static String selectPhotoUri(PhoneLookupInfo phoneLookupInfo) { + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); + if (firstLocalContact != null) { + String photoUri = firstLocalContact.getPhotoUri(); + if (!photoUri.isEmpty()) { + return photoUri; + } + } + return ""; + } + + /** Select the photo ID associated with this number, or 0 if there is none. */ + public static long selectPhotoId(PhoneLookupInfo phoneLookupInfo) { + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); + if (firstLocalContact != null) { + long photoId = firstLocalContact.getPhotoId(); + if (photoId > 0) { + return photoId; + } + } + return 0; + } + + /** Select the lookup URI associated with this number. */ + @NonNull + public static String selectLookupUri(PhoneLookupInfo phoneLookupInfo) { + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); + if (firstLocalContact != null) { + String lookupUri = firstLocalContact.getLookupUri(); + if (!lookupUri.isEmpty()) { + return lookupUri; + } } return ""; } + + /** + * A localized string representing the number type such as "Home" or "Mobile", or a custom value + * set by the user. + */ + @NonNull + public static String selectNumberLabel(PhoneLookupInfo phoneLookupInfo) { + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); + if (firstLocalContact != null) { + String label = firstLocalContact.getLabel(); + if (!label.isEmpty()) { + return label; + } + } + return ""; + } + + /** + * Arbitrarily select the first contact. In the future, it may make sense to display contact + * information from all contacts with the same number (for example show the name as "Mom, Dad" or + * show a synthesized photo containing photos of both "Mom" and "Dad"). + */ + @Nullable + private static Cp2ContactInfo firstLocalContact(PhoneLookupInfo phoneLookupInfo) { + if (phoneLookupInfo.getCp2Info().getCp2ContactInfoCount() > 0) { + return phoneLookupInfo.getCp2Info().getCp2ContactInfo(0); + } + return null; + } } diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java index 03e05b563..3829a8df1 100644 --- a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java +++ b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java @@ -58,17 +58,21 @@ public final class Cp2PhoneLookup implements PhoneLookup { Phone.DISPLAY_NAME_PRIMARY, // 0 Phone.PHOTO_THUMBNAIL_URI, // 1 Phone.PHOTO_ID, // 2 - Phone.LABEL, // 3 - Phone.NORMALIZED_NUMBER, // 4 - Phone.CONTACT_ID, // 5 + Phone.TYPE, // 3 + Phone.LABEL, // 4 + Phone.NORMALIZED_NUMBER, // 5 + Phone.CONTACT_ID, // 6 + Phone.LOOKUP_KEY // 7 }; private static final int CP2_INFO_NAME_INDEX = 0; private static final int CP2_INFO_PHOTO_URI_INDEX = 1; private static final int CP2_INFO_PHOTO_ID_INDEX = 2; - private static final int CP2_INFO_LABEL_INDEX = 3; - private static final int CP2_INFO_NUMBER_INDEX = 4; - private static final int CP2_INFO_CONTACT_ID_INDEX = 5; + private static final int CP2_INFO_TYPE_INDEX = 3; + private static final int CP2_INFO_LABEL_INDEX = 4; + private static final int CP2_INFO_NUMBER_INDEX = 5; + private static final int CP2_INFO_CONTACT_ID_INDEX = 6; + private static final int CP2_INFO_LOOKUP_KEY_INDEX = 7; private final Context appContext; private final SharedPreferences sharedPreferences; @@ -89,6 +93,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { @Override public ListenableFuture<PhoneLookupInfo> lookup(@NonNull Call call) { // TODO(zachh): Implementation. + // TODO(zachh): Note: Should write empty Cp2Info even when no contact found. return backgroundExecutorService.submit(PhoneLookupInfo::getDefaultInstance); } @@ -207,7 +212,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { // For each DialerPhoneNumber that was associated with a contact or added to a contact, // build a map of those DialerPhoneNumbers to a set Cp2ContactInfos, where each Cp2ContactInfo // represents a contact. - ImmutableMap<DialerPhoneNumber, Set<Cp2ContactInfo>> updatedContacts = + Map<DialerPhoneNumber, Set<Cp2ContactInfo>> updatedContacts = buildMapForUpdatedOrAddedContacts(existingInfoMap, lastModified, deletedPhoneNumbers); // Start build a new map of updated info. This will replace existing info. @@ -216,23 +221,26 @@ public final class Cp2PhoneLookup implements PhoneLookup { // For each DialerPhoneNumber in existing info... for (Entry<DialerPhoneNumber, PhoneLookupInfo> entry : existingInfoMap.entrySet()) { + DialerPhoneNumber dialerPhoneNumber = entry.getKey(); + PhoneLookupInfo existingInfo = entry.getValue(); + // Build off the existing info - PhoneLookupInfo.Builder infoBuilder = PhoneLookupInfo.newBuilder(entry.getValue()); + PhoneLookupInfo.Builder infoBuilder = PhoneLookupInfo.newBuilder(existingInfo); // If the contact was updated, replace the Cp2ContactInfo list - if (updatedContacts.containsKey(entry.getKey())) { + if (updatedContacts.containsKey(dialerPhoneNumber)) { infoBuilder.setCp2Info( - Cp2Info.newBuilder().addAllCp2ContactInfo(updatedContacts.get(entry.getKey()))); + Cp2Info.newBuilder().addAllCp2ContactInfo(updatedContacts.get(dialerPhoneNumber))); // If it was deleted and not added to a new contact, replace the Cp2ContactInfo list with // the default instance of Cp2ContactInfo - } else if (deletedPhoneNumbers.contains(entry.getKey())) { + } else if (deletedPhoneNumbers.contains(dialerPhoneNumber)) { infoBuilder.setCp2Info( Cp2Info.newBuilder().addCp2ContactInfo(Cp2ContactInfo.getDefaultInstance())); } // If the DialerPhoneNumber didn't change, add the unchanged existing info. - newInfoMapBuilder.put(entry.getKey(), infoBuilder.build()); + newInfoMapBuilder.put(dialerPhoneNumber, infoBuilder.build()); } return newInfoMapBuilder.build(); } @@ -260,7 +268,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { * @return Map of {@link DialerPhoneNumber} to {@link PhoneLookupInfo} with updated {@link * Cp2ContactInfo}. */ - private ImmutableMap<DialerPhoneNumber, Set<Cp2ContactInfo>> buildMapForUpdatedOrAddedContacts( + private Map<DialerPhoneNumber, Set<Cp2ContactInfo>> buildMapForUpdatedOrAddedContacts( ImmutableMap<DialerPhoneNumber, PhoneLookupInfo> existingInfoMap, long lastModified, Set<DialerPhoneNumber> deletedPhoneNumbers) { @@ -270,16 +278,24 @@ public final class Cp2PhoneLookup implements PhoneLookup { Set<Long> contactIds = new ArraySet<>(); for (Entry<DialerPhoneNumber, PhoneLookupInfo> entry : existingInfoMap.entrySet()) { + DialerPhoneNumber dialerPhoneNumber = entry.getKey(); + PhoneLookupInfo existingInfo = entry.getValue(); + // If the number was deleted, we need to check if it was added to a new contact. - if (deletedPhoneNumbers.contains(entry.getKey())) { - updatedNumbers.add(entry.getKey()); + if (deletedPhoneNumbers.contains(dialerPhoneNumber)) { + updatedNumbers.add(dialerPhoneNumber); continue; } + // Note: Methods in this class must always set at least one Cp2Info, setting it to + // getDefaultInstance() if there is no information for the contact. + Assert.checkState( + existingInfo.getCp2Info().getCp2ContactInfoCount() > 0, "existing info has no cp2 infos"); + // For each Cp2ContactInfo for each existing DialerPhoneNumber... // Store the contact id if it exist, else automatically add the DialerPhoneNumber to our // set of DialerPhoneNumbers we want to update. - for (Cp2ContactInfo cp2ContactInfo : entry.getValue().getCp2Info().getCp2ContactInfoList()) { + for (Cp2ContactInfo cp2ContactInfo : existingInfo.getCp2Info().getCp2ContactInfoList()) { if (Objects.equals(cp2ContactInfo, Cp2ContactInfo.getDefaultInstance())) { // If the number doesn't have any Cp2ContactInfo set to it, for various reasons, we need // to look up the number to check if any exists. @@ -287,7 +303,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { // - An existing contact that wasn't in the call log is now in the call log. // - A number was in the call log before but has now been added to a contact. // - A number is in the call log, but isn't associated with any contact. - updatedNumbers.add(entry.getKey()); + updatedNumbers.add(dialerPhoneNumber); } else { contactIds.add(cp2ContactInfo.getContactId()); } @@ -322,7 +338,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { // Map each dialer phone number to it's new cp2 info Set<DialerPhoneNumber> phoneNumbers = getDialerPhoneNumbers(updatedNumbers, cursor.getString(CP2_INFO_NUMBER_INDEX)); - Cp2ContactInfo info = buildCp2ContactInfoFromUpdatedContactsCursor(cursor); + Cp2ContactInfo info = buildCp2ContactInfoFromUpdatedContactsCursor(appContext, cursor); for (DialerPhoneNumber phoneNumber : phoneNumbers) { if (map.containsKey(phoneNumber)) { map.get(phoneNumber).add(info); @@ -334,7 +350,7 @@ public final class Cp2PhoneLookup implements PhoneLookup { } } } - return ImmutableMap.copyOf(map); + return map; } /** @@ -358,10 +374,15 @@ public final class Cp2PhoneLookup implements PhoneLookup { * @param cursor with projection {@link #CP2_INFO_PROJECTION}. * @return new {@link Cp2ContactInfo} based on current row of {@code cursor}. */ - private static Cp2ContactInfo buildCp2ContactInfoFromUpdatedContactsCursor(Cursor cursor) { + private static Cp2ContactInfo buildCp2ContactInfoFromUpdatedContactsCursor( + Context appContext, Cursor cursor) { String displayName = cursor.getString(CP2_INFO_NAME_INDEX); String photoUri = cursor.getString(CP2_INFO_PHOTO_URI_INDEX); + int photoId = cursor.getInt(CP2_INFO_PHOTO_ID_INDEX); + int type = cursor.getInt(CP2_INFO_TYPE_INDEX); String label = cursor.getString(CP2_INFO_LABEL_INDEX); + int contactId = cursor.getInt(CP2_INFO_CONTACT_ID_INDEX); + String lookupKey = cursor.getString(CP2_INFO_LOOKUP_KEY_INDEX); Cp2ContactInfo.Builder infoBuilder = Cp2ContactInfo.newBuilder(); if (!TextUtils.isEmpty(displayName)) { @@ -370,11 +391,19 @@ public final class Cp2PhoneLookup implements PhoneLookup { if (!TextUtils.isEmpty(photoUri)) { infoBuilder.setPhotoUri(photoUri); } - if (!TextUtils.isEmpty(label)) { - infoBuilder.setLabel(label); + if (photoId > 0) { + infoBuilder.setPhotoId(photoId); + } + + // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just + // omit setting the label if there's no information for it. + if (type != 0 || !TextUtils.isEmpty(label)) { + infoBuilder.setLabel(Phone.getTypeLabel(appContext.getResources(), type, label).toString()); + } + infoBuilder.setContactId(contactId); + if (!TextUtils.isEmpty(lookupKey)) { + infoBuilder.setLookupUri(Contacts.getLookupUri(contactId, lookupKey).toString()); } - infoBuilder.setPhotoId(cursor.getLong(CP2_INFO_PHOTO_ID_INDEX)); - infoBuilder.setContactId(cursor.getLong(CP2_INFO_CONTACT_ID_INDEX)); return infoBuilder.build(); } diff --git a/java/com/android/dialer/phonelookup/phone_lookup_info.proto b/java/com/android/dialer/phonelookup/phone_lookup_info.proto index 93dd01e86..36596c1a2 100644 --- a/java/com/android/dialer/phonelookup/phone_lookup_info.proto +++ b/java/com/android/dialer/phonelookup/phone_lookup_info.proto @@ -34,9 +34,13 @@ message PhoneLookupInfo { // android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID optional fixed64 contact_id = 5; + + // android.provider.ContactsContract.CONTENT_LOOKUP_URI + optional string lookup_uri = 6; } // Repeated because one phone number can be associated with multiple CP2 - // contacts. + // contacts. If no contact is found for a number, this will contain exactly + // one element which is the default Cp2ContactInfo instance. repeated Cp2ContactInfo cp2_contact_info = 1; } optional Cp2Info cp2_info = 1; |