From 62a8ebb5a86efd88e0eb1eb3c1d1401fca13338e Mon Sep 17 00:00:00 2001 From: Yuri Lin Date: Wed, 9 Feb 2022 17:12:40 -0500 Subject: Small improvements to matchesCallFilter functionality Check both NORMALIZED_NUMBER and NUMBER for a phone call contact, in case one or the other is populated but not both, for more phone number coverage. Use Uri.decode instead of URLDecoder as it seems simpler and more directly relevant. Bug: 183924362 Test: NotificationManagerTest, ValidateNotificationPeopleTest, ZenModeFilteringTest Change-Id: I29c39bf1e3d7dc69cc1f83854a23f6b33a6eac58 Merged-In: I29c39bf1e3d7dc69cc1f83854a23f6b33a6eac58 (cherry picked from commit b9290319b63f35dd8d9d85762755c7ee0ad0555b) --- .../notification/ValidateNotificationPeople.java | 25 ++++++++++----- .../server/notification/ZenModeFiltering.java | 36 ++++++++-------------- .../ValidateNotificationPeopleTest.java | 6 ++-- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java index dc4d04feab72..bdc571103ffd 100644 --- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java +++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java @@ -70,11 +70,15 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor { "validate_notification_people_enabled"; private static final String[] LOOKUP_PROJECTION = { Contacts._ID, Contacts.LOOKUP_KEY, Contacts.STARRED, Contacts.HAS_PHONE_NUMBER }; - private static final String[] PHONE_LOOKUP_PROJECTION = - { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }; private static final int MAX_PEOPLE = 10; private static final int PEOPLE_CACHE_SIZE = 200; + /** Columns used to look up phone numbers for contacts. */ + @VisibleForTesting + static final String[] PHONE_LOOKUP_PROJECTION = + { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER, + ContactsContract.CommonDataKinds.Phone.NUMBER }; + /** Indicates that the notification does not reference any valid contacts. */ static final float NONE = 0f; @@ -548,14 +552,21 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor { return mPhoneLookupKey; } - // Merge phone number found in this lookup and store it in mPhoneNumbers. + // Merge phone numbers found in this lookup and store them in mPhoneNumbers. public void mergePhoneNumber(Cursor cursor) { - final int phoneNumIdx = cursor.getColumnIndex( + final int normalizedNumIdx = cursor.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER); - if (phoneNumIdx >= 0) { - mPhoneNumbers.add(cursor.getString(phoneNumIdx)); + if (normalizedNumIdx >= 0) { + mPhoneNumbers.add(cursor.getString(normalizedNumIdx)); + } else { + if (DEBUG) Slog.d(TAG, "cursor data not found: no NORMALIZED_NUMBER"); + } + + final int numIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + if (numIdx >= 0) { + mPhoneNumbers.add(cursor.getString(numIdx)); } else { - if (DEBUG) Slog.d(TAG, "invalid cursor: no NORMALIZED_NUMBER"); + if (DEBUG) Slog.d(TAG, "cursor data not found: no NUMBER"); } } diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java index f9a7c4658245..45e0080c69fb 100644 --- a/services/core/java/com/android/server/notification/ZenModeFiltering.java +++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java @@ -40,8 +40,6 @@ import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.util.NotificationMessagingUtil; import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; import java.util.Date; public class ZenModeFiltering { @@ -402,16 +400,10 @@ public class ZenModeFiltering { if (person == null) continue; final Uri uri = Uri.parse(person); if ("tel".equals(uri.getScheme())) { - String tel = uri.getSchemeSpecificPart(); - // while ideally we should not need to do this, sometimes we have seen tel - // numbers given in a url-encoded format - try { - tel = URLDecoder.decode(tel, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // ignore, keep the original tel string - Slog.w(TAG, "unsupported encoding in tel: uri input"); - } - mTelCalls.put(tel, now); + // while ideally we should not need to decode this, sometimes we have seen tel + // numbers given in an encoded format + String tel = Uri.decode(uri.getSchemeSpecificPart()); + if (tel != null) mTelCalls.put(tel, now); } else { // for non-tel calls, store the entire string, uri-component and all mOtherCalls.put(person, now); @@ -422,7 +414,7 @@ public class ZenModeFiltering { // provided; these are in the format of just a phone number string if (phoneNumbers != null) { for (String num : phoneNumbers) { - mTelCalls.put(num, now); + if (num != null) mTelCalls.put(num, now); } } } @@ -442,17 +434,13 @@ public class ZenModeFiltering { return true; } else { // see if a number that matches via areSameNumber exists - String numberToCheck = number; - try { - numberToCheck = URLDecoder.decode(number, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // ignore, continue to use the original string - Slog.w(TAG, "unsupported encoding in tel: uri input"); - } - for (String prev : mTelCalls.keySet()) { - if (PhoneNumberUtils.areSamePhoneNumber( - numberToCheck, prev, defaultCountryCode)) { - return true; + String numberToCheck = Uri.decode(number); + if (numberToCheck != null) { + for (String prev : mTelCalls.keySet()) { + if (PhoneNumberUtils.areSamePhoneNumber( + numberToCheck, prev, defaultCountryCode)) { + return true; + } } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java index 0552a8350329..c12f0a965146 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java @@ -274,7 +274,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase { new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri); verify(mockContentResolver, never()).query( eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI), - eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }), + eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION), contains(ContactsContract.Contacts.LOOKUP_KEY), any(), // selection args isNull()); // sort order @@ -308,7 +308,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase { // in the case of a phone lookup, return null cursor; that's not an error case // and we're not checking the actual storing of the phone data here. when(mockContentResolver.query(eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI), - eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }), + eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION), contains(ContactsContract.Contacts.LOOKUP_KEY), any(), isNull())).thenReturn(null); @@ -317,7 +317,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase { new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri); verify(mockContentResolver, times(1)).query( eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI), - eq(new String[] { ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER }), + eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION), contains(ContactsContract.Contacts.LOOKUP_KEY), eq(new String[] { "testlookupkey" }), // selection args isNull()); // sort order -- cgit v1.2.3-59-g8ed1b