Dedup NANPA numbers
Reverts changes from Bug 5779336 that stopped using libphonenumber for
detecting dups, although keep matching as strict except when one number
begins with +1, in which case collapse. Change Collapser to allow
preferred collapse direction.
Bug:7519057
Change-Id: Ib8ba6da611638d05781ed4363d71bc2628d907b7
diff --git a/src/com/android/contacts/common/Collapser.java b/src/com/android/contacts/common/Collapser.java
index d586add..39ae681 100644
--- a/src/com/android/contacts/common/Collapser.java
+++ b/src/com/android/contacts/common/Collapser.java
@@ -37,7 +37,7 @@
* can be used for example to collapse similar contact data items into a single item.
*/
public interface Collapsible<T> {
- public boolean collapseWith(T t);
+ public void collapseWith(T t);
public boolean shouldCollapseWith(T t);
}
@@ -61,6 +61,10 @@
if (iItem.shouldCollapseWith(jItem)) {
iItem.collapseWith(jItem);
list.set(j, null);
+ } else if (jItem.shouldCollapseWith(iItem)) {
+ jItem.collapseWith(iItem);
+ list.set(i, null);
+ break;
}
}
}
diff --git a/src/com/android/contacts/common/MoreContactUtils.java b/src/com/android/contacts/common/MoreContactUtils.java
index b32e7cf..fe414e1 100644
--- a/src/com/android/contacts/common/MoreContactUtils.java
+++ b/src/com/android/contacts/common/MoreContactUtils.java
@@ -16,6 +16,9 @@
package com.android.contacts.common;
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
@@ -33,6 +36,8 @@
*/
public class MoreContactUtils {
+ private static final String WAIT_SYMBOL_AS_STRING = String.valueOf(PhoneNumberUtils.WAIT);
+
/**
* Returns true if two data with mimetypes which represent values in contact entries are
* considered equal for collapsing in the GUI. For caller-id, use
@@ -40,7 +45,7 @@
* instead
*/
public static boolean shouldCollapse(CharSequence mimetype1, CharSequence data1,
- CharSequence mimetype2, CharSequence data2) {
+ CharSequence mimetype2, CharSequence data2) {
// different mimetypes? don't collapse
if (!TextUtils.equals(mimetype1, mimetype2)) return false;
@@ -60,38 +65,50 @@
return shouldCollapsePhoneNumbers(data1.toString(), data2.toString());
}
- private static boolean shouldCollapsePhoneNumbers(
- String number1WithLetters, String number2WithLetters) {
- final String number1 = PhoneNumberUtils.convertKeypadLettersToDigits(number1WithLetters);
- final String number2 = PhoneNumberUtils.convertKeypadLettersToDigits(number2WithLetters);
+ private static boolean shouldCollapsePhoneNumbers(String number1, String number2) {
+ // Now do the full phone number thing. split into parts, separated by waiting symbol
+ // and compare them individually
+ final String[] dataParts1 = number1.split(WAIT_SYMBOL_AS_STRING);
+ final String[] dataParts2 = number2.split(WAIT_SYMBOL_AS_STRING);
+ if (dataParts1.length != dataParts2.length) return false;
+ final PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ for (int i = 0; i < dataParts1.length; i++) {
+ // Match phone numbers represented by keypad letters, in which case prefer the
+ // phone number with letters.
+ final String dataPart1 = PhoneNumberUtils.convertKeypadLettersToDigits(dataParts1[i]);
+ final String dataPart2 = dataParts2[i];
- int index1 = 0;
- int index2 = 0;
- for (;;) {
- // Skip formatting characters.
- while (index1 < number1.length() &&
- !PhoneNumberUtils.isNonSeparator(number1.charAt(index1))) {
- index1++;
- }
- while (index2 < number2.length() &&
- !PhoneNumberUtils.isNonSeparator(number2.charAt(index2))) {
- index2++;
- }
- // If both have finished, match. If only one has finished, not match.
- final boolean number1End = (index1 == number1.length());
- final boolean number2End = (index2 == number2.length());
- if (number1End) {
- return number2End;
- }
- if (number2End) return false;
+ // substrings equal? shortcut, don't parse
+ if (TextUtils.equals(dataPart1, dataPart2)) continue;
- // If the non-formatting characters are different, not match.
- if (number1.charAt(index1) != number2.charAt(index2)) return false;
-
- // Go to the next characters.
- index1++;
- index2++;
+ // do a full parse of the numbers
+ switch (util.isNumberMatch(dataPart1, dataPart2)) {
+ case NOT_A_NUMBER:
+ // don't understand the numbers? let's play it safe
+ return false;
+ case NO_MATCH:
+ return false;
+ case EXACT_MATCH:
+ break;
+ case NSN_MATCH:
+ try {
+ // For NANP phone numbers, match when one has +1 and the other does not.
+ // In this case, prefer the +1 version.
+ if (util.parse(dataPart1, null).getCountryCode() == 1) {
+ break;
+ }
+ } catch (NumberParseException e) {
+ // Ignore
+ }
+ return false;
+ case SHORT_NSN_MATCH:
+ return false;
+ default:
+ throw new IllegalStateException("Unknown result value from phone number " +
+ "library");
+ }
}
+ return true;
}
/**