summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java')
-rw-r--r--java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java75
1 files changed, 75 insertions, 0 deletions
diff --git a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
index cc9b73081..84cbb6947 100644
--- a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
+++ b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
@@ -17,6 +17,8 @@
package com.android.dialer.phonenumberutil;
import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Trace;
import android.provider.CallLog;
import android.support.annotation.Nullable;
@@ -24,6 +26,7 @@ import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
import com.android.dialer.compat.telephony.TelephonyManagerCompat;
@@ -47,6 +50,78 @@ public class PhoneNumberHelper {
}
/**
+ * Find the cursor pointing to a number that matches the number in a contact lookup URI.
+ *
+ * <p>When determining whether two phone numbers are identical enough for caller ID purposes, the
+ * Contacts Provider uses {@link PhoneNumberUtils#compare(String, String)}, which ignores special
+ * dialable characters such as '#', '*', '+', etc. This makes it possible for the cursor returned
+ * by the Contacts Provider to have multiple rows even when the URI asks for a specific number.
+ *
+ * <p>For example, suppose the user has two contacts whose numbers are "#123" and "123",
+ * respectively. When the URI asks for number "123", both numbers will be returned. Therefore, the
+ * following strategy is employed to find a match.
+ *
+ * <p>If the cursor points to a global phone number (i.e., a number that can be accepted by {@link
+ * PhoneNumberUtils#isGlobalPhoneNumber(String)}) and the lookup number in the URI is a PARTIAL
+ * match, return the cursor.
+ *
+ * <p>If the cursor points to a number that is not a global phone number, return the cursor iff
+ * the lookup number in the URI is an EXACT match.
+ *
+ * <p>Return null in all other circumstances.
+ *
+ * @param cursor A cursor returned by the Contacts Provider.
+ * @param columnIndexForNumber The index of the column where phone numbers are stored. It is the
+ * caller's responsibility to pass the correct column index.
+ * @param contactLookupUri A URI used to retrieve a contact via the Contacts Provider. It is the
+ * caller's responsibility to ensure the URI is one that asks for a specific phone number.
+ * @return The cursor considered as a match by the description above or null if no such cursor can
+ * be found.
+ */
+ public static Cursor getCursorMatchForContactLookupUri(
+ Cursor cursor, int columnIndexForNumber, Uri contactLookupUri) {
+ if (cursor == null || contactLookupUri == null) {
+ return null;
+ }
+
+ if (!cursor.moveToFirst()) {
+ return null;
+ }
+
+ Assert.checkArgument(
+ 0 <= columnIndexForNumber && columnIndexForNumber < cursor.getColumnCount());
+
+ String lookupNumber = contactLookupUri.getLastPathSegment();
+ if (lookupNumber == null) {
+ return null;
+ }
+
+ boolean isMatchFound;
+ do {
+ // All undialable characters should be converted/removed before comparing the lookup number
+ // and the existing contact number.
+ String rawExistingContactNumber =
+ PhoneNumberUtils.stripSeparators(
+ PhoneNumberUtils.convertKeypadLettersToDigits(
+ cursor.getString(columnIndexForNumber)));
+ String rawQueryNumber =
+ PhoneNumberUtils.stripSeparators(
+ PhoneNumberUtils.convertKeypadLettersToDigits(lookupNumber));
+
+ isMatchFound =
+ PhoneNumberUtils.isGlobalPhoneNumber(rawExistingContactNumber)
+ ? rawExistingContactNumber.contains(rawQueryNumber)
+ : rawExistingContactNumber.equals(rawQueryNumber);
+
+ if (isMatchFound) {
+ return cursor;
+ }
+ } while (cursor.moveToNext());
+
+ return null;
+ }
+
+ /**
* Returns true if the given number is the number of the configured voicemail. To be able to
* mock-out this, it is not a static method.
*/