Check separate phone numbers in RepeatCallers.isRepeat
In the case where a new call notification comes in with just a contact uri, and the telephone number associated with the call was previously received, we need to also try to check any looked up phone numbers.
Bug: 219562304
Test: ZenModeFilteringTest, NotificationManagerTest
Change-Id: I81b7bf63b7cfd36b8765dc39c225103d4cd48587
Merged-In: I81b7bf63b7cfd36b8765dc39c225103d4cd48587
(cherry picked from commit 49633a3cef)
This commit is contained in:
@@ -106,7 +106,7 @@ public class ZenModeFiltering {
|
|||||||
if (zen == Global.ZEN_MODE_ALARMS) return false; // not an alarm
|
if (zen == Global.ZEN_MODE_ALARMS) return false; // not an alarm
|
||||||
if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
|
if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
|
||||||
if (consolidatedPolicy.allowRepeatCallers()
|
if (consolidatedPolicy.allowRepeatCallers()
|
||||||
&& REPEAT_CALLERS.isRepeat(context, extras)) {
|
&& REPEAT_CALLERS.isRepeat(context, extras, null)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!consolidatedPolicy.allowCalls()) return false; // no other calls get through
|
if (!consolidatedPolicy.allowCalls()) return false; // no other calls get through
|
||||||
@@ -215,7 +215,8 @@ public class ZenModeFiltering {
|
|||||||
}
|
}
|
||||||
if (isCall(record)) {
|
if (isCall(record)) {
|
||||||
if (policy.allowRepeatCallers()
|
if (policy.allowRepeatCallers()
|
||||||
&& REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
|
&& REPEAT_CALLERS.isRepeat(
|
||||||
|
mContext, extras(record), record.getPhoneNumbers())) {
|
||||||
ZenLog.traceNotIntercepted(record, "repeatCaller");
|
ZenLog.traceNotIntercepted(record, "repeatCaller");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -336,6 +337,9 @@ public class ZenModeFiltering {
|
|||||||
private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
|
private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
|
||||||
private int mThresholdMinutes;
|
private int mThresholdMinutes;
|
||||||
|
|
||||||
|
// Record all people URIs in the extras bundle as well as the provided phoneNumbers set
|
||||||
|
// as callers. The phoneNumbers set is used to pass in any additional phone numbers
|
||||||
|
// associated with the people URIs as separately retrieved from contacts.
|
||||||
private synchronized void recordCall(Context context, Bundle extras,
|
private synchronized void recordCall(Context context, Bundle extras,
|
||||||
ArraySet<String> phoneNumbers) {
|
ArraySet<String> phoneNumbers) {
|
||||||
setThresholdMinutes(context);
|
setThresholdMinutes(context);
|
||||||
@@ -348,7 +352,13 @@ public class ZenModeFiltering {
|
|||||||
recordCallers(extraPeople, phoneNumbers, now);
|
recordCallers(extraPeople, phoneNumbers, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized boolean isRepeat(Context context, Bundle extras) {
|
// Determine whether any people in the provided extras bundle or phone number set is
|
||||||
|
// a repeat caller. The extras bundle contains the people associated with a specific
|
||||||
|
// notification, and will suffice for most callers; the phoneNumbers array may be used
|
||||||
|
// to additionally check any specific phone numbers previously retrieved from contacts
|
||||||
|
// associated with the people in the extras bundle.
|
||||||
|
private synchronized boolean isRepeat(Context context, Bundle extras,
|
||||||
|
ArraySet<String> phoneNumbers) {
|
||||||
setThresholdMinutes(context);
|
setThresholdMinutes(context);
|
||||||
if (mThresholdMinutes <= 0 || extras == null) return false;
|
if (mThresholdMinutes <= 0 || extras == null) return false;
|
||||||
final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
|
final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
|
||||||
@@ -356,7 +366,7 @@ public class ZenModeFiltering {
|
|||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
cleanUp(mTelCalls, now);
|
cleanUp(mTelCalls, now);
|
||||||
cleanUp(mOtherCalls, now);
|
cleanUp(mOtherCalls, now);
|
||||||
return checkCallers(context, extraPeople);
|
return checkCallers(context, extraPeople, phoneNumbers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
|
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
|
||||||
@@ -419,7 +429,31 @@ public class ZenModeFiltering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized boolean checkCallers(Context context, String[] people) {
|
// helper function to check mTelCalls array for a number, and also check its decoded
|
||||||
|
// version
|
||||||
|
private synchronized boolean checkForNumber(String number, String defaultCountryCode) {
|
||||||
|
if (mTelCalls.containsKey(number)) {
|
||||||
|
// check directly via map first
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// see if a number that matches via areSameNumber exists
|
||||||
|
String numberToCheck = Uri.decode(number);
|
||||||
|
if (numberToCheck != null) {
|
||||||
|
for (String prev : mTelCalls.keySet()) {
|
||||||
|
if (PhoneNumberUtils.areSamePhoneNumber(
|
||||||
|
numberToCheck, prev, defaultCountryCode)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether anyone in the provided array of people URIs or phone number set matches a
|
||||||
|
// previously recorded phone call.
|
||||||
|
private synchronized boolean checkCallers(Context context, String[] people,
|
||||||
|
ArraySet<String> phoneNumbers) {
|
||||||
// get the default country code for checking telephone numbers
|
// get the default country code for checking telephone numbers
|
||||||
final String defaultCountryCode =
|
final String defaultCountryCode =
|
||||||
context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
|
context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
|
||||||
@@ -429,20 +463,8 @@ public class ZenModeFiltering {
|
|||||||
final Uri uri = Uri.parse(person);
|
final Uri uri = Uri.parse(person);
|
||||||
if ("tel".equals(uri.getScheme())) {
|
if ("tel".equals(uri.getScheme())) {
|
||||||
String number = uri.getSchemeSpecificPart();
|
String number = uri.getSchemeSpecificPart();
|
||||||
if (mTelCalls.containsKey(number)) {
|
if (checkForNumber(number, defaultCountryCode)) {
|
||||||
// check directly via map first
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
// see if a number that matches via areSameNumber exists
|
|
||||||
String numberToCheck = Uri.decode(number);
|
|
||||||
if (numberToCheck != null) {
|
|
||||||
for (String prev : mTelCalls.keySet()) {
|
|
||||||
if (PhoneNumberUtils.areSamePhoneNumber(
|
|
||||||
numberToCheck, prev, defaultCountryCode)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mOtherCalls.containsKey(person)) {
|
if (mOtherCalls.containsKey(person)) {
|
||||||
@@ -450,6 +472,17 @@ public class ZenModeFiltering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// also check any passed-in phone numbers
|
||||||
|
if (phoneNumbers != null) {
|
||||||
|
for (String num : phoneNumbers) {
|
||||||
|
if (checkForNumber(num, defaultCountryCode)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no matches
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
// Create a notification record with the people String array as the
|
// Create a notification record with the people String array as the
|
||||||
// bundled extras, and the numbers ArraySet as additional phone numbers.
|
// bundled extras, and the numbers ArraySet as additional phone numbers.
|
||||||
private NotificationRecord getRecordWithPeopleInfo(String[] people,
|
private NotificationRecord getCallRecordWithPeopleInfo(String[] people,
|
||||||
ArraySet<String> numbers) {
|
ArraySet<String> numbers) {
|
||||||
// set up notification record
|
// set up notification record
|
||||||
NotificationRecord r = mock(NotificationRecord.class);
|
NotificationRecord r = mock(NotificationRecord.class);
|
||||||
@@ -131,6 +131,8 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
when(sbn.getNotification()).thenReturn(notification);
|
when(sbn.getNotification()).thenReturn(notification);
|
||||||
when(r.getSbn()).thenReturn(sbn);
|
when(r.getSbn()).thenReturn(sbn);
|
||||||
when(r.getPhoneNumbers()).thenReturn(numbers);
|
when(r.getPhoneNumbers()).thenReturn(numbers);
|
||||||
|
when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL);
|
||||||
|
when(r.isCategory(CATEGORY_CALL)).thenReturn(true);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,12 +351,42 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
|
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepeatCallers_checksPhoneNumbers() {
|
||||||
|
// set up telephony manager behavior
|
||||||
|
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
|
||||||
|
|
||||||
|
// first, record a phone call from a telephone number
|
||||||
|
String[] callNumber = new String[]{"tel:12345678910"};
|
||||||
|
mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(callNumber, null));
|
||||||
|
|
||||||
|
// set up policy to only allow repeat callers
|
||||||
|
Policy policy = new Policy(
|
||||||
|
PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
|
||||||
|
|
||||||
|
// make sure that a record with the phone number in extras is correctly allowed through
|
||||||
|
NotificationRecord r = getCallRecordWithPeopleInfo(callNumber, null);
|
||||||
|
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
|
||||||
|
|
||||||
|
// make sure that a record with the phone number in the phone numbers array is also
|
||||||
|
// allowed through
|
||||||
|
NotificationRecord r2 = getCallRecordWithPeopleInfo(new String[]{"some_contact_uri"},
|
||||||
|
new ArraySet<>(new String[]{"12345678910"}));
|
||||||
|
assertFalse(mZenModeFiltering.shouldIntercept(
|
||||||
|
ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r2));
|
||||||
|
|
||||||
|
// A record with the phone number in neither of the above should be intercepted
|
||||||
|
NotificationRecord r3 = getCallRecordWithPeopleInfo(new String[]{"tel:10987654321"},
|
||||||
|
new ArraySet<>(new String[]{"15555555555"}));
|
||||||
|
assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r3));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatchesCallFilter_repeatCallers_directMatch() {
|
public void testMatchesCallFilter_repeatCallers_directMatch() {
|
||||||
// after calls given an email with an exact string match, make sure that
|
// after calls given an email with an exact string match, make sure that
|
||||||
// matchesCallFilter returns the right thing
|
// matchesCallFilter returns the right thing
|
||||||
String[] mailSource = new String[]{"mailto:hello.world"};
|
String[] mailSource = new String[]{"mailto:hello.world"};
|
||||||
mZenModeFiltering.recordCall(getRecordWithPeopleInfo(mailSource, null));
|
mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(mailSource, null));
|
||||||
|
|
||||||
// set up policy to only allow repeat callers
|
// set up policy to only allow repeat callers
|
||||||
Policy policy = new Policy(
|
Policy policy = new Policy(
|
||||||
@@ -377,7 +409,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
|
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
|
||||||
|
|
||||||
String[] telSource = new String[]{"tel:+1-617-555-1212"};
|
String[] telSource = new String[]{"tel:+1-617-555-1212"};
|
||||||
mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
|
mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
|
||||||
|
|
||||||
// set up policy to only allow repeat callers
|
// set up policy to only allow repeat callers
|
||||||
Policy policy = new Policy(
|
Policy policy = new Policy(
|
||||||
@@ -421,7 +453,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
|
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
|
||||||
|
|
||||||
String[] telSource = new String[]{"tel:%2B16175551212"};
|
String[] telSource = new String[]{"tel:%2B16175551212"};
|
||||||
mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
|
mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
|
||||||
|
|
||||||
// set up policy to only allow repeat callers
|
// set up policy to only allow repeat callers
|
||||||
Policy policy = new Policy(
|
Policy policy = new Policy(
|
||||||
@@ -468,7 +500,7 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
|
|||||||
String[] contactSource = new String[]{"content://contacts/lookup/uri-here"};
|
String[] contactSource = new String[]{"content://contacts/lookup/uri-here"};
|
||||||
ArraySet<String> contactNumbers = new ArraySet<>(
|
ArraySet<String> contactNumbers = new ArraySet<>(
|
||||||
new String[]{"1-617-555-1212", "1-617-555-3434"});
|
new String[]{"1-617-555-1212", "1-617-555-3434"});
|
||||||
NotificationRecord record = getRecordWithPeopleInfo(contactSource, contactNumbers);
|
NotificationRecord record = getCallRecordWithPeopleInfo(contactSource, contactNumbers);
|
||||||
record.mergePhoneNumbers(contactNumbers);
|
record.mergePhoneNumbers(contactNumbers);
|
||||||
mZenModeFiltering.recordCall(record);
|
mZenModeFiltering.recordCall(record);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user