Skip suffix match if mUseStrictPhoneNumberComparison is true

Don't do the suffix match during the phone number lookup match if
mUseStrictPhoneNumberComparison is true.
Bug: 7000177
Change-Id: I77e60117449cec6c37a9605ba4333a067d02a54c
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 81112aa..95008d7 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -4541,28 +4541,33 @@
                 sb.append(" OR ");
             }
             if (hasNumber) {
-                int numberLen = number.length();
-                sb.append(" lookup.len <= ");
-                sb.append(numberLen);
-                sb.append(" AND substr(");
-                DatabaseUtils.appendEscapedSQLString(sb, number);
-                sb.append(',');
-                sb.append(numberLen);
-                sb.append(" - lookup.len + 1) = lookup.normalized_number");
+                // skip the suffix match entirely if we are using strict number comparison
+                if (!mUseStrictPhoneNumberComparison) {
+                    int numberLen = number.length();
+                    sb.append(" lookup.len <= ");
+                    sb.append(numberLen);
+                    sb.append(" AND substr(");
+                    DatabaseUtils.appendEscapedSQLString(sb, number);
+                    sb.append(',');
+                    sb.append(numberLen);
+                    sb.append(" - lookup.len + 1) = lookup.normalized_number");
 
-                // Some countries (e.g. Brazil) can have incoming calls which contain only the local
-                // number (no country calling code and no area code). This case is handled below.
-                // Details see b/5197612.
-                // This also handles a Gingerbread -> ICS upgrade issue; see b/5638376.
-                sb.append(" OR (");
-                sb.append(" lookup.len > ");
-                sb.append(numberLen);
-                sb.append(" AND substr(lookup.normalized_number,");
-                sb.append("lookup.len + 1 - ");
-                sb.append(numberLen);
-                sb.append(") = ");
-                DatabaseUtils.appendEscapedSQLString(sb, number);
-                sb.append(")");
+                    // Some countries (e.g. Brazil) can have incoming calls which contain only the local
+                    // number (no country calling code and no area code). This case is handled below.
+                    // Details see b/5197612.
+                    // This also handles a Gingerbread -> ICS upgrade issue; see b/5638376.
+                    sb.append(" OR (");
+                    sb.append(" lookup.len > ");
+                    sb.append(numberLen);
+                    sb.append(" AND substr(lookup.normalized_number,");
+                    sb.append("lookup.len + 1 - ");
+                    sb.append(numberLen);
+                    sb.append(") = ");
+                    DatabaseUtils.appendEscapedSQLString(sb, number);
+                    sb.append(")");
+                } else {
+                    sb.append("0");
+                }
             }
             sb.append(')');
         }
@@ -5291,6 +5296,16 @@
     }
 
     @NeededForTesting
+    /* package */ void setUseStrictPhoneNumberComparisonForTest(boolean useStrict) {
+        mUseStrictPhoneNumberComparison = useStrict;
+    }
+
+    @NeededForTesting
+    /* package */ boolean getUseStrictPhoneNumberComparisonForTest() {
+        return mUseStrictPhoneNumberComparison;
+    }
+
+    @NeededForTesting
     /* package */ String querySearchIndexContentForTest(long contactId) {
         return DatabaseUtils.stringForQuery(getReadableDatabase(),
                 "SELECT " + SearchIndexColumns.CONTENT +
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 8970e5d..77789c3 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -67,6 +67,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.providers.contacts.ContactsDatabaseHelper;
 import com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
@@ -1431,6 +1432,63 @@
                 PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
     }
 
+    public void testPhoneLookupUseStrictPhoneNumberCompare() {
+        // Test lookup cases when mUseStrictPhoneNumberComparison is true
+        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
+        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
+        // Get and save the original value of mUseStrictPhoneNumberComparison so that we
+        // can restore it when we are done with the test
+        final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
+        dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
+
+
+        try {
+            String fullNumber = "01197297427289";
+            ContentValues values = new ContentValues();
+            values.put(RawContacts.CUSTOM_RINGTONE, "d");
+            values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
+            long rawContactId = ContentUris.parseId(
+                    mResolver.insert(RawContacts.CONTENT_URI, values));
+            insertStructuredName(rawContactId, "Senor", "Chang");
+            insertPhoneNumber(rawContactId, fullNumber);
+            insertPhoneNumber(rawContactId, "5103337596");
+            insertPhoneNumber(rawContactId, "+19012345678");
+            // One match for full number
+            assertEquals(1, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
+
+            // No matches for extra digit at the front
+            assertEquals(0, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
+            // No matches for mispelled area code
+            assertEquals(0, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
+
+            // One match for matching number with dashes
+            assertEquals(1, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
+
+            // One match for matching number with international code
+            assertEquals(1, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
+            values.clear();
+
+            // No matches for extra 0 in front
+            assertEquals(0, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
+            values.clear();
+
+            // No matches for different country code
+            assertEquals(0, getCount(Uri.withAppendedPath(
+                    PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
+            values.clear();
+        } finally {
+            // restore the original value of mUseStrictPhoneNumberComparison
+            // upon test completion or failure
+            dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
+        }
+    }
+
     public void testPhoneUpdate() {
         ContentValues values = new ContentValues();
         Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);