summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/phonelookup
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/phonelookup')
-rw-r--r--java/com/android/dialer/phonelookup/PhoneLookupSelector.java79
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java77
-rw-r--r--java/com/android/dialer/phonelookup/phone_lookup_info.proto6
3 files changed, 133 insertions, 29 deletions
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;