summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/com/android/dialer/dialpad/SmartDialNameMatcher.java25
-rw-r--r--src/com/android/dialer/dialpad/SmartDialTrie.java57
-rw-r--r--tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java11
-rw-r--r--tests/src/com/android/dialer/dialpad/SmartDialTrieTest.java24
4 files changed, 89 insertions, 28 deletions
diff --git a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
index f8877c665..f7ae1c232 100644
--- a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
+++ b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java
@@ -18,6 +18,8 @@ package com.android.dialer.dialpad;
import android.text.TextUtils;
+import com.android.dialer.dialpad.SmartDialTrie.CountryCodeWithOffset;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
@@ -426,8 +428,19 @@ public class SmartDialNameMatcher {
* @return Phone number consisting of digits from 0-9
*/
public static String normalizeNumber(String number) {
+ return normalizeNumber(number, 0);
+ }
+
+ /**
+ * Strips a phone number of unnecessary characters (spaces, dashes, etc.)
+ *
+ * @param number Phone number we want to normalize
+ * @param offset Offset to start from
+ * @return Phone number consisting of digits from 0-9
+ */
+ public static String normalizeNumber(String number, int offset) {
final StringBuilder s = new StringBuilder();
- for (int i = 0; i < number.length(); i++) {
+ for (int i = offset; i < number.length(); i++) {
char ch = number.charAt(i);
if (ch >= '0' && ch <= '9') {
s.append(ch);
@@ -452,10 +465,12 @@ public class SmartDialNameMatcher {
SmartDialMatchPosition matchPos = matchesNumberWithOffset(phoneNumber, query, 0);
if (matchPos == null) {
// Try matching the number without the '+' prefix, if any
- int offset = SmartDialTrie.getOffsetWithoutCountryCode(phoneNumber);
- if (offset > 0) {
- matchPos = matchesNumberWithOffset(phoneNumber, query, offset);
- } else if (matchNanp) {
+ final CountryCodeWithOffset code = SmartDialTrie.getOffsetWithoutCountryCode(
+ phoneNumber);
+ if (code != null) {
+ matchPos = matchesNumberWithOffset(phoneNumber, query, code.offset);
+ }
+ if (matchPos == null && matchNanp) {
// Try matching NANP numbers
final int[] offsets = SmartDialTrie.getOffsetForNANPNumbers(phoneNumber);
for (int i = 0; i < offsets.length; i++) {
diff --git a/src/com/android/dialer/dialpad/SmartDialTrie.java b/src/com/android/dialer/dialpad/SmartDialTrie.java
index 04ff64c5b..ab935b73a 100644
--- a/src/com/android/dialer/dialpad/SmartDialTrie.java
+++ b/src/com/android/dialer/dialpad/SmartDialTrie.java
@@ -45,13 +45,33 @@ public class SmartDialTrie {
int nthLastTokenPos;
}
- private static final int LAST_TOKENS_FOR_INITIALS = 2;
- private static final int FIRST_TOKENS_FOR_INITIALS = 2;
+ /**
+ * A country code and integer offset pair that represents the parsed country code in a
+ * phone number. The country code is a string containing the numeric country-code prefix in
+ * a phone number (e.g. 1 or 852). The offset is the integer position of where the country code
+ * ends in a phone number.
+ */
+ public static class CountryCodeWithOffset {
+ public static final CountryCodeWithOffset NO_COUNTRY_CODE = new CountryCodeWithOffset(0,
+ "");
+
+ final String countryCode;
+ final int offset;
+
+ public CountryCodeWithOffset(int offset, String countryCode) {
+ this.countryCode = countryCode;
+ this.offset = offset;
+ }
+ }
+
final Node mRoot = new Node();
private int mSize = 0;
private final char[] mCharacterMap;
private final boolean mFormatNanp;
+ private static final int LAST_TOKENS_FOR_INITIALS = 2;
+ private static final int FIRST_TOKENS_FOR_INITIALS = 2;
+
// Static set of all possible country codes in the world
public static Set<String> sCountryCodes = null;
@@ -134,12 +154,14 @@ public class SmartDialTrie {
// Strip the calling code from the phone number here
if (!TextUtils.isEmpty(contact.phoneNumber)) {
// Handle country codes for numbers with a + prefix
- final int offset = getOffsetWithoutCountryCode(contact.phoneNumber);
- if (offset > 0) {
- putNumber(contact, contact.phoneNumber, offset);
- } else if (mFormatNanp) {
+ final CountryCodeWithOffset code = getOffsetWithoutCountryCode(contact.phoneNumber);
+ if (code.offset != 0) {
+ putNumber(contact, contact.phoneNumber, code.offset);
+ }
+ if ((code.countryCode.equals("1") || code.offset == 0) && mFormatNanp) {
// Special case handling for NANP numbers (1-xxx-xxx-xxxx)
- final String stripped = SmartDialNameMatcher.normalizeNumber(contact.phoneNumber);
+ final String stripped = SmartDialNameMatcher.normalizeNumber(
+ contact.phoneNumber, code.offset);
if (!TextUtils.isEmpty(stripped)) {
int trunkPrefixOffset = 0;
if (stripped.charAt(0) == '1') {
@@ -159,24 +181,25 @@ public class SmartDialTrie {
}
}
}
- putNumber(contact, contact.phoneNumber);
+ putNumber(contact, contact.phoneNumber, 0);
}
mSize++;
}
- public static int getOffsetWithoutCountryCode(String number) {
+ public static CountryCodeWithOffset getOffsetWithoutCountryCode(String number) {
if (!TextUtils.isEmpty(number)) {
if (number.charAt(0) == '+') {
// check for international code here
for (int i = 1; i <= 1 + 3; i++) {
if (number.length() <= i) break;
- if (isValidCountryCode(number.substring(1, i))) {
- return i;
+ final String countryCode = number.substring(1, i);
+ if (isValidCountryCode(countryCode)) {
+ return new CountryCodeWithOffset(i, countryCode);
}
}
}
}
- return -1;
+ return CountryCodeWithOffset.NO_COUNTRY_CODE;
}
/**
@@ -278,16 +301,6 @@ public class SmartDialTrie {
*
* @param contact - Contact to add to the trie
* @param phoneNumber - Phone number of the contact
- */
- private void putNumber(ContactNumber contact, String phoneNumber) {
- putNumber(contact, phoneNumber, 0);
- }
-
- /**
- * Puts a phone number and its associated contact into the prefix trie.
- *
- * @param contact - Contact to add to the trie
- * @param phoneNumber - Phone number of the contact
* @param offSet - The nth character of the phone number to start from
*/
private void putNumber(ContactNumber contact, String phoneNumber, int offSet) {
diff --git a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
index 83b856059..eb6f05087 100644
--- a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
+++ b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
@@ -201,6 +201,17 @@ public class SmartDialNameMatcherTest extends TestCase {
checkMatchesNumber("1-510-333-7596", "5103337596", true, true, 2, 14);
checkMatchesNumber("1-510-333-7596", "3337596", true, true, 6, 14);
+ // An 11 digit number prefixed with +1 should be matched by the 10 digit number, as well as
+ // the 7 digit number (without area code)
+ checkMatchesNumber("+1-510-333-7596", "5103337596", true, true, 3, 15);
+ checkMatchesNumber("+1-510-333-7596", "3337596", true, true, 7, 15);
+ checkMatchesNumber("+1-510-333-7596", "103337596", false, true, 0, 0);
+ checkMatchesNumber("+1-510-333-7596", "337596", false, true, 0, 0);
+ checkMatchesNumber("+1510 3337596", "5103337596", true, true, 2, 13);
+ checkMatchesNumber("+1510 3337596", "3337596", true, true, 6, 13);
+ checkMatchesNumber("+1510 3337596", "103337596", false, true, 0, 0);
+ checkMatchesNumber("+1510 3337596", "37596", false, true, 0, 0);
+
// Invalid NANP numbers should not be matched
checkMatchesNumber("1-510-333-759", "510333759", false, true, 0, 0);
checkMatchesNumber("510-333-759", "333759", false, true, 0, 0);
diff --git a/tests/src/com/android/dialer/dialpad/SmartDialTrieTest.java b/tests/src/com/android/dialer/dialpad/SmartDialTrieTest.java
index 876e00de7..f0c4cbb46 100644
--- a/tests/src/com/android/dialer/dialpad/SmartDialTrieTest.java
+++ b/tests/src/com/android/dialer/dialpad/SmartDialTrieTest.java
@@ -294,7 +294,6 @@ public class SmartDialTrieTest extends TestCase{
// Tests special case handling for NANP numbers
public void testPutNumbersNANP() {
-
final SmartDialTrie trie = new SmartDialTrie(true /* formatNanp */);
// Unformatted number with 1 prefix
final ContactNumber contactno1 = new ContactNumber(0, "James", "16503337596", "0", 1);
@@ -340,6 +339,29 @@ public class SmartDialTrieTest extends TestCase{
// But the NANP special case handling should not work
assertFalse(checkContains(trie, contactno6, "123123"));
+ // Number with +1 prefix and is a NANP number
+ final ContactNumber contactno7 = new ContactNumber(0, "Mike", "+1-510-284-9170", "0", 1);
+ trie.put(contactno7);
+ assertTrue(checkContains(trie, contactno7, "15102849170"));
+ assertTrue(checkContains(trie, contactno7, "5102849170"));
+ assertTrue(checkContains(trie, contactno7, "2849170"));
+ assertFalse(checkContains(trie, contactno7, "849170"));
+ assertFalse(checkContains(trie, contactno7, "10849170"));
+
+ // Number with +1 prefix but is an invalid NANP number
+ final ContactNumber contactno8 = new ContactNumber(0, "Invalid", "+1-510-284-917", "0", 1);
+ trie.put(contactno8);
+ assertTrue(checkContains(trie, contactno8, "1510284917"));
+ assertTrue(checkContains(trie, contactno8, "510284917"));
+ assertFalse(checkContains(trie, contactno8, "2849170"));
+
+ // Number with invalid country code prefix
+ final ContactNumber contactno9 = new ContactNumber(0, "Inv", "+857-510-284-9170", "0", 1);
+ trie.put(contactno9);
+ assertTrue(checkContains(trie, contactno9, "8575102849170"));
+ assertFalse(checkContains(trie, contactno9, "5102849170"));
+ assertFalse(checkContains(trie, contactno9, "2849170"));
+
// If user's region is determined to be not in North America, then the NANP number
// workarounds should not be applied
final SmartDialTrie trieNonNANP = new SmartDialTrie();