summaryrefslogtreecommitdiffstats
path: root/src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java
diff options
context:
space:
mode:
authorBrian Attwell <brianattwell@google.com>2014-02-27 12:19:46 -0800
committerBrian Attwell <brianattwell@google.com>2014-02-28 16:52:58 -0800
commitbf98e55afd5f39f72dc05c704409655b89a7fa25 (patch)
tree9aa421b6c5e51c9e901491602e31a99b39ae3590 /src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java
parent120ca86ad7873be1bc02a4228035749f60358024 (diff)
downloadpackages_providers_ContactsProvider-bf98e55afd5f39f72dc05c704409655b89a7fa25.zip
packages_providers_ContactsProvider-bf98e55afd5f39f72dc05c704409655b89a7fa25.tar.gz
packages_providers_ContactsProvider-bf98e55afd5f39f72dc05c704409655b89a7fa25.tar.bz2
Do not ignore leading "*"s in phone lookups
After a phone lookup, "remove" entries from the cursor that don't match the queried number w.r.t. to whether it has a leading "*". "Removing" entries from a cursor involves making a partial copy of the cursor. This CL affects as little functionality as possible, so that it can make it into MR2. Ie, we continue to ignore leading "*"s in other CP2 queries. MANUAL TESTS: -Add a "*123" Emergency contact and "123" Voicemail contact -Call "*123", then call "123". You should see two seperate entries in your call log. In addition, the incall screens should show Emergency and Voicemail respectively (although the "123" call doesn't work properly inside the incall UI right now. This is a seperate bug b/13195342). Bug: 13195334 Change-Id: I7e1938ccb085630072611eb63148c5714b62fee8
Diffstat (limited to 'src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java')
-rw-r--r--src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java b/src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java
new file mode 100644
index 0000000..a05dd05
--- /dev/null
+++ b/src/com/android/providers/contacts/PhoneLookupWithStarPrefix.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.providers.contacts;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.provider.ContactsContract.PhoneLookup;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Helper class for PHONE_LOOKUP's that involve numbers with "*" prefixes.
+ */
+/* package-protected */ final class PhoneLookupWithStarPrefix {
+ private static final String TAG = "PhoneLookupWSP";
+
+ /**
+ * Returns a cursor with a subset of the rows passed into this function. If {@param number}
+ * starts with a "*" then only rows from {@param cursor} that have a number equal to
+ * {@param number} will be returned. If {@param number} doesn't start with a "*", then
+ * only rows from {@param cursor} that have numbers without starting "*" characters
+ * will be returned.
+ *
+ * This function is used to resolve b/13195334.
+ *
+ * @param number unnormalized phone number.
+ * @param cursor this function takes ownership of the cursor. The calling scope MUST NOT
+ * use or close() the cursor passed into this function. The cursor must contain
+ * PhoneLookup.NUMBER.
+ *
+ * @return a cursor that the calling context owns
+ */
+ public static Cursor removeNonStarMatchesFromCursor(String number, Cursor cursor) {
+
+ // Close cursors that we don't return.
+ Cursor unreturnedCursor = cursor;
+
+ try {
+ if (TextUtils.isEmpty(number)) {
+ unreturnedCursor = null;
+ return cursor;
+ }
+
+ final String queryPhoneNumberNormalized = normalizeNumberWithStar(number);
+ if (!queryPhoneNumberNormalized.startsWith("*")
+ && !matchingNumberStartsWithStar(cursor)) {
+ cursor.moveToPosition(-1);
+ unreturnedCursor = null;
+ return cursor;
+ }
+
+ final MatrixCursor matrixCursor = new MatrixCursor(cursor.getColumnNames());
+
+ // Close cursors that we don't return.
+ Cursor unreturnedMatrixCursor = matrixCursor;
+
+ try {
+ cursor.moveToPosition(-1);
+ while (cursor.moveToNext()) {
+ final int numberIndex = cursor.getColumnIndex(PhoneLookup.NUMBER);
+ final String matchingNumberNormalized
+ = normalizeNumberWithStar(cursor.getString(numberIndex));
+ if (!matchingNumberNormalized.startsWith("*")
+ && !queryPhoneNumberNormalized.startsWith("*")
+ || matchingNumberNormalized.equals(queryPhoneNumberNormalized)) {
+ // Copy row from cursor into matrixCursor
+ final MatrixCursor.RowBuilder b = matrixCursor.newRow();
+ for (int column = 0; column < cursor.getColumnCount(); column++) {
+ b.add(cursor.getColumnName(column), cursorValue(cursor, column));
+ }
+ }
+ }
+ unreturnedMatrixCursor = null;
+ return matrixCursor;
+ } finally {
+ if (unreturnedMatrixCursor != null) {
+ unreturnedMatrixCursor.close();
+ }
+ }
+ } finally {
+ if (unreturnedCursor != null) {
+ unreturnedCursor.close();
+ }
+ }
+ }
+
+ @VisibleForTesting
+ static String normalizeNumberWithStar(String phoneNumber) {
+ if (TextUtils.isEmpty(phoneNumber)) {
+ return phoneNumber;
+ }
+ if (phoneNumber.startsWith("*")) {
+ // Use PhoneNumberUtils.normalizeNumber() to normalize the rest of the number after
+ // the leading "*". Strip out the "+" since "+"s are only allowed as leading
+ // characters. NOTE: This statement has poor performance. Fortunately, it won't be
+ // called very often.
+ return "*" + PhoneNumberUtils.normalizeNumber(
+ phoneNumber.substring(1).replace("+", ""));
+ }
+ return PhoneNumberUtils.normalizeNumber(phoneNumber);
+ }
+
+ /**
+ * @return whether {@param cursor} contain any numbers that start with "*"
+ */
+ private static boolean matchingNumberStartsWithStar(Cursor cursor) {
+ cursor.moveToPosition(-1);
+ while (cursor.moveToNext()) {
+ final int numberIndex = cursor.getColumnIndex(PhoneLookup.NUMBER);
+ final String phoneNumber = normalizeNumberWithStar(cursor.getString(numberIndex));
+ if (phoneNumber.startsWith("*")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Object cursorValue(Cursor cursor, int column) {
+ switch(cursor.getType(column)) {
+ case Cursor.FIELD_TYPE_BLOB:
+ return cursor.getBlob(column);
+ case Cursor.FIELD_TYPE_INTEGER:
+ return cursor.getInt(column);
+ case Cursor.FIELD_TYPE_FLOAT:
+ return cursor.getFloat(column);
+ case Cursor.FIELD_TYPE_STRING:
+ return cursor.getString(column);
+ case Cursor.FIELD_TYPE_NULL:
+ return null;
+ default:
+ Log.d(TAG, "Invalid value in cursor: " + cursor.getType(column));
+ return null;
+ }
+ }
+}