1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.notification; 18 19 import static android.app.Notification.CATEGORY_CALL; 20 import static android.app.NotificationManager.IMPORTANCE_DEFAULT; 21 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE; 22 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT; 23 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE; 24 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; 25 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS; 26 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; 27 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS; 28 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY; 29 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; 30 import static android.provider.Settings.Global.ZEN_MODE_ALARMS; 31 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 32 import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; 33 import static android.provider.Settings.Global.ZEN_MODE_OFF; 34 35 import static junit.framework.Assert.assertFalse; 36 import static junit.framework.Assert.assertTrue; 37 38 import static org.mockito.ArgumentMatchers.any; 39 import static org.mockito.Mockito.mock; 40 import static org.mockito.Mockito.when; 41 42 import android.app.Notification; 43 import android.app.NotificationChannel; 44 import android.app.NotificationManager.Policy; 45 import android.media.AudioAttributes; 46 import android.os.Bundle; 47 import android.os.UserHandle; 48 import android.service.notification.StatusBarNotification; 49 import android.telephony.TelephonyManager; 50 import android.test.suitebuilder.annotation.SmallTest; 51 import android.testing.AndroidTestingRunner; 52 import android.testing.TestableLooper; 53 import android.util.ArraySet; 54 55 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 56 import com.android.internal.util.NotificationMessagingUtil; 57 import com.android.server.UiServiceTestCase; 58 59 import org.junit.After; 60 import org.junit.Before; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 66 @SmallTest 67 @RunWith(AndroidTestingRunner.class) 68 @TestableLooper.RunWithLooper 69 public class ZenModeFilteringTest extends UiServiceTestCase { 70 71 @Mock 72 private NotificationMessagingUtil mMessagingUtil; 73 private ZenModeFiltering mZenModeFiltering; 74 75 @Mock private TelephonyManager mTelephonyManager; 76 77 private long mTestStartTime; 78 79 @Before setUp()80 public void setUp() { 81 MockitoAnnotations.initMocks(this); 82 mZenModeFiltering = new ZenModeFiltering(mContext, mMessagingUtil); 83 84 // for repeat callers / matchesCallFilter 85 mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager); 86 mTestStartTime = System.currentTimeMillis(); 87 } 88 89 @After tearDown()90 public void tearDown() { 91 // make sure to get rid of any data stored in repeat callers 92 mZenModeFiltering.cleanUpCallersAfter(mTestStartTime); 93 } 94 getNotificationRecord()95 private NotificationRecord getNotificationRecord() { 96 return getNotificationRecord(mock(NotificationChannel.class)); 97 } 98 getNotificationRecord(NotificationChannel c)99 private NotificationRecord getNotificationRecord(NotificationChannel c) { 100 StatusBarNotification sbn = mock(StatusBarNotification.class); 101 Notification notification = mock(Notification.class); 102 when(sbn.getNotification()).thenReturn(notification); 103 return new NotificationRecord(mContext, sbn, c); 104 } 105 getConversationRecord(NotificationChannel c, StatusBarNotification sbn)106 private NotificationRecord getConversationRecord(NotificationChannel c, 107 StatusBarNotification sbn) { 108 NotificationRecord r = mock(NotificationRecord.class); 109 when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL); 110 when(r.getSbn()).thenReturn(sbn); 111 when(r.getChannel()).thenReturn(c); 112 when(r.isConversation()).thenReturn(true); 113 return r; 114 } 115 makeExtrasBundleWithPeople(String[] people)116 private Bundle makeExtrasBundleWithPeople(String[] people) { 117 Bundle extras = new Bundle(); 118 extras.putObject(Notification.EXTRA_PEOPLE_LIST, people); 119 return extras; 120 } 121 122 // Create a notification record with the people String array as the 123 // bundled extras, and the numbers ArraySet as additional phone numbers. getCallRecordWithPeopleInfo(String[] people, ArraySet<String> numbers)124 private NotificationRecord getCallRecordWithPeopleInfo(String[] people, 125 ArraySet<String> numbers) { 126 // set up notification record 127 NotificationRecord r = mock(NotificationRecord.class); 128 StatusBarNotification sbn = mock(StatusBarNotification.class); 129 Notification notification = mock(Notification.class); 130 notification.extras = makeExtrasBundleWithPeople(people); 131 when(sbn.getNotification()).thenReturn(notification); 132 when(r.getSbn()).thenReturn(sbn); 133 when(r.getPhoneNumbers()).thenReturn(numbers); 134 when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL); 135 when(r.isCategory(CATEGORY_CALL)).thenReturn(true); 136 return r; 137 } 138 139 @Test testIsMessage()140 public void testIsMessage() { 141 NotificationRecord r = getNotificationRecord(); 142 143 when(mMessagingUtil.isMessaging(any())).thenReturn(true); 144 assertTrue(mZenModeFiltering.isMessage(r)); 145 146 when(mMessagingUtil.isMessaging(any())).thenReturn(false); 147 assertFalse(mZenModeFiltering.isMessage(r)); 148 } 149 150 @Test testIsAlarm()151 public void testIsAlarm() { 152 NotificationChannel c = mock(NotificationChannel.class); 153 when(c.getAudioAttributes()).thenReturn(new AudioAttributes.Builder() 154 .setUsage(AudioAttributes.USAGE_ALARM) 155 .build()); 156 NotificationRecord r = getNotificationRecord(c); 157 assertTrue(mZenModeFiltering.isAlarm(r)); 158 159 r = getNotificationRecord(); 160 r.getSbn().getNotification().category = Notification.CATEGORY_ALARM; 161 assertTrue(mZenModeFiltering.isAlarm(r)); 162 } 163 164 @Test testIsAlarm_wrongCategory()165 public void testIsAlarm_wrongCategory() { 166 NotificationRecord r = getNotificationRecord(); 167 r.getSbn().getNotification().category = CATEGORY_CALL; 168 assertFalse(mZenModeFiltering.isAlarm(r)); 169 } 170 171 @Test testIsAlarm_wrongUsage()172 public void testIsAlarm_wrongUsage() { 173 NotificationChannel c = mock(NotificationChannel.class); 174 when(c.getAudioAttributes()).thenReturn(new AudioAttributes.Builder() 175 .setUsage(AudioAttributes.USAGE_NOTIFICATION) 176 .build()); 177 NotificationRecord r = getNotificationRecord(c); 178 assertFalse(mZenModeFiltering.isAlarm(r)); 179 } 180 181 @Test testSuppressDNDInfo_yes_VisEffectsAllowed()182 public void testSuppressDNDInfo_yes_VisEffectsAllowed() { 183 NotificationRecord r = getNotificationRecord(); 184 when(r.getSbn().getPackageName()).thenReturn("android"); 185 when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE); 186 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects() 187 - SUPPRESSED_EFFECT_STATUS_BAR, 0); 188 189 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 190 } 191 192 @Test testSuppressDNDInfo_yes_WrongId()193 public void testSuppressDNDInfo_yes_WrongId() { 194 NotificationRecord r = getNotificationRecord(); 195 when(r.getSbn().getPackageName()).thenReturn("android"); 196 when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION); 197 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0); 198 199 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 200 } 201 202 @Test testSuppressDNDInfo_yes_WrongPackage()203 public void testSuppressDNDInfo_yes_WrongPackage() { 204 NotificationRecord r = getNotificationRecord(); 205 when(r.getSbn().getPackageName()).thenReturn("android2"); 206 when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE); 207 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0); 208 209 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 210 } 211 212 @Test testSuppressDNDInfo_no()213 public void testSuppressDNDInfo_no() { 214 NotificationRecord r = getNotificationRecord(); 215 when(r.getSbn().getPackageName()).thenReturn("android"); 216 when(r.getSbn().getId()).thenReturn(SystemMessage.NOTE_ZEN_UPGRADE); 217 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0); 218 219 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 220 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_ALARMS, policy, r)); 221 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, policy, r)); 222 } 223 224 @Test testSuppressAnything_yes_ZenModeOff()225 public void testSuppressAnything_yes_ZenModeOff() { 226 NotificationRecord r = getNotificationRecord(); 227 when(r.getSbn().getPackageName()).thenReturn("bananas"); 228 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects()); 229 230 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_OFF, policy, r)); 231 } 232 233 @Test testSuppressAnything_bypass_ZenModeOn()234 public void testSuppressAnything_bypass_ZenModeOn() { 235 NotificationRecord r = getNotificationRecord(); 236 r.setCriticality(CriticalNotificationExtractor.CRITICAL); 237 when(r.getSbn().getPackageName()).thenReturn("bananas"); 238 Policy policy = new Policy(0, 0, 0, Policy.getAllSuppressedVisualEffects(), 0); 239 240 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, policy, r)); 241 242 r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW); 243 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, policy, r)); 244 } 245 246 @Test testConversation_allAllowed()247 public void testConversation_allAllowed() { 248 Notification n = new Notification.Builder(mContext, "a").build(); 249 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 250 UserHandle.SYSTEM, null, 0); 251 252 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 253 channel.setConversationId("parent", "me, work"); 254 255 NotificationRecord r = getConversationRecord(channel, sbn); 256 when(r.isConversation()).thenReturn(true); 257 258 Policy policy = new Policy( 259 PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_ANYONE); 260 261 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 262 } 263 264 @Test testConversation_importantAllowed_isImportant()265 public void testConversation_importantAllowed_isImportant() { 266 Notification n = new Notification.Builder(mContext, "a").build(); 267 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 268 UserHandle.SYSTEM, null, 0); 269 270 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 271 channel.setConversationId("parent", "me, work"); 272 channel.setImportantConversation(true); 273 274 NotificationRecord r = getConversationRecord(channel, sbn); 275 276 Policy policy = new Policy( 277 PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_IMPORTANT); 278 279 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 280 } 281 282 @Test testConversation_importantAllowed_isNotImportant()283 public void testConversation_importantAllowed_isNotImportant() { 284 Notification n = new Notification.Builder(mContext, "a").build(); 285 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 286 UserHandle.SYSTEM, null, 0); 287 288 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 289 channel.setConversationId("parent", "me, work"); 290 291 NotificationRecord r = getConversationRecord(channel, sbn); 292 293 Policy policy = new Policy( 294 PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_IMPORTANT); 295 296 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 297 } 298 299 @Test testConversation_noneAllowed_notCallOrMsg()300 public void testConversation_noneAllowed_notCallOrMsg() { 301 Notification n = new Notification.Builder(mContext, "a").build(); 302 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 303 UserHandle.SYSTEM, null, 0); 304 305 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 306 channel.setConversationId("parent", "me, work"); 307 308 NotificationRecord r = getConversationRecord(channel, sbn); 309 310 Policy policy = 311 new Policy(PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 312 313 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 314 } 315 316 @Test testConversation_noneAllowed_callAllowed()317 public void testConversation_noneAllowed_callAllowed() { 318 Notification n = new Notification.Builder(mContext, "a").build(); 319 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 320 UserHandle.SYSTEM, null, 0); 321 322 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 323 channel.setConversationId("parent", "me, work"); 324 325 NotificationRecord r = getConversationRecord(channel, sbn); 326 when(r.isCategory(CATEGORY_CALL)).thenReturn(true); 327 328 Policy policy = 329 new Policy(PRIORITY_CATEGORY_CALLS, 330 PRIORITY_SENDERS_ANY, 0, 0, CONVERSATION_SENDERS_NONE); 331 332 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 333 } 334 335 @Test testConversation_noneAllowed_msgAllowed()336 public void testConversation_noneAllowed_msgAllowed() { 337 when(mMessagingUtil.isMessaging(any())).thenReturn(true); 338 Notification n = new Notification.Builder(mContext, "a").build(); 339 StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, n, 340 UserHandle.SYSTEM, null, 0); 341 342 NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); 343 channel.setConversationId("parent", "me, work"); 344 345 NotificationRecord r = getConversationRecord(channel, sbn); 346 347 Policy policy = 348 new Policy(PRIORITY_CATEGORY_MESSAGES, 349 0, PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_NONE); 350 351 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 352 } 353 354 @Test testRepeatCallers_checksPhoneNumbers()355 public void testRepeatCallers_checksPhoneNumbers() { 356 // set up telephony manager behavior 357 when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us"); 358 359 // first, record a phone call from a telephone number 360 String[] callNumber = new String[]{"tel:12345678910"}; 361 mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(callNumber, null)); 362 363 // set up policy to only allow repeat callers 364 Policy policy = new Policy( 365 PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 366 367 // make sure that a record with the phone number in extras is correctly allowed through 368 NotificationRecord r = getCallRecordWithPeopleInfo(callNumber, null); 369 assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r)); 370 371 // make sure that a record with the phone number in the phone numbers array is also 372 // allowed through 373 NotificationRecord r2 = getCallRecordWithPeopleInfo(new String[]{"some_contact_uri"}, 374 new ArraySet<>(new String[]{"12345678910"})); 375 assertFalse(mZenModeFiltering.shouldIntercept( 376 ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r2)); 377 378 // A record with the phone number in neither of the above should be intercepted 379 NotificationRecord r3 = getCallRecordWithPeopleInfo(new String[]{"tel:10987654321"}, 380 new ArraySet<>(new String[]{"15555555555"})); 381 assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r3)); 382 } 383 384 @Test testMatchesCallFilter_repeatCallers_directMatch()385 public void testMatchesCallFilter_repeatCallers_directMatch() { 386 // after calls given an email with an exact string match, make sure that 387 // matchesCallFilter returns the right thing 388 String[] mailSource = new String[]{"mailto:hello.world"}; 389 mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(mailSource, null)); 390 391 // set up policy to only allow repeat callers 392 Policy policy = new Policy( 393 PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 394 395 // check whether matchesCallFilter returns the right thing 396 Bundle inputMatches = makeExtrasBundleWithPeople(new String[]{"mailto:hello.world"}); 397 Bundle inputWrong = makeExtrasBundleWithPeople(new String[]{"mailto:nope"}); 398 assertTrue(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 399 policy, UserHandle.SYSTEM, 400 inputMatches, null, 0, 0, 0)); 401 assertFalse(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 402 policy, UserHandle.SYSTEM, 403 inputWrong, null, 0, 0, 0)); 404 } 405 406 @Test testMatchesCallFilter_repeatCallers_telephoneVariants()407 public void testMatchesCallFilter_repeatCallers_telephoneVariants() { 408 // set up telephony manager behavior 409 when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us"); 410 411 String[] telSource = new String[]{"tel:+1-617-555-1212"}; 412 mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null)); 413 414 // set up policy to only allow repeat callers 415 Policy policy = new Policy( 416 PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 417 418 // cases to test: 419 // - identical number 420 // - same number, different formatting 421 // - different number 422 // - garbage 423 Bundle identical = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"}); 424 Bundle same = makeExtrasBundleWithPeople(new String[]{"tel:16175551212"}); 425 Bundle different = makeExtrasBundleWithPeople(new String[]{"tel:123-456-7890"}); 426 Bundle garbage = makeExtrasBundleWithPeople(new String[]{"asdfghjkl;"}); 427 428 assertTrue("identical numbers should match", 429 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 430 policy, UserHandle.SYSTEM, 431 identical, null, 0, 0, 0)); 432 assertTrue("equivalent but non-identical numbers should match", 433 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 434 policy, UserHandle.SYSTEM, 435 same, null, 0, 0, 0)); 436 assertFalse("non-equivalent numbers should not match", 437 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 438 policy, UserHandle.SYSTEM, 439 different, null, 0, 0, 0)); 440 assertFalse("non-tel strings should not match", 441 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 442 policy, UserHandle.SYSTEM, 443 garbage, null, 0, 0, 0)); 444 } 445 446 @Test testMatchesCallFilter_repeatCallers_urlEncodedTels()447 public void testMatchesCallFilter_repeatCallers_urlEncodedTels() { 448 // this is not intended to be a supported case but is one that we have seen 449 // sometimes in the wild, so make sure we handle url-encoded telephone numbers correctly 450 // when somebody provides one. 451 452 // set up telephony manager behavior 453 when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us"); 454 455 String[] telSource = new String[]{"tel:%2B16175551212"}; 456 mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null)); 457 458 // set up policy to only allow repeat callers 459 Policy policy = new Policy( 460 PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 461 462 // test cases for various forms of the same phone number and different ones 463 Bundle same1 = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"}); 464 Bundle same2 = makeExtrasBundleWithPeople(new String[]{"tel:%2B1-617-555-1212"}); 465 Bundle same3 = makeExtrasBundleWithPeople(new String[]{"tel:6175551212"}); 466 Bundle different1 = makeExtrasBundleWithPeople(new String[]{"tel:%2B16175553434"}); 467 Bundle different2 = makeExtrasBundleWithPeople(new String[]{"tel:+16175553434"}); 468 469 assertTrue("same number 1 should match", 470 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 471 policy, UserHandle.SYSTEM, 472 same1, null, 0, 0, 0)); 473 assertTrue("same number 2 should match", 474 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 475 policy, UserHandle.SYSTEM, 476 same2, null, 0, 0, 0)); 477 assertTrue("same number 3 should match", 478 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 479 policy, UserHandle.SYSTEM, 480 same3, null, 0, 0, 0)); 481 assertFalse("different number 1 should not match", 482 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 483 policy, UserHandle.SYSTEM, 484 different1, null, 0, 0, 0)); 485 assertFalse("different number 2 should not match", 486 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 487 policy, UserHandle.SYSTEM, 488 different2, null, 0, 0, 0)); 489 } 490 491 @Test testMatchesCallFilter_repeatCallers_viaRecordPhoneNumbers()492 public void testMatchesCallFilter_repeatCallers_viaRecordPhoneNumbers() { 493 // make sure that phone numbers that are passed in via the NotificationRecord's 494 // cached phone numbers field (from a contact lookup if the record is provided a contact 495 // uri) also get recorded in the repeat callers list. 496 497 // set up telephony manager behavior 498 when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us"); 499 500 String[] contactSource = new String[]{"content://contacts/lookup/uri-here"}; 501 ArraySet<String> contactNumbers = new ArraySet<>( 502 new String[]{"1-617-555-1212", "1-617-555-3434"}); 503 NotificationRecord record = getCallRecordWithPeopleInfo(contactSource, contactNumbers); 504 record.mergePhoneNumbers(contactNumbers); 505 mZenModeFiltering.recordCall(record); 506 507 // set up policy to only allow repeat callers 508 Policy policy = new Policy( 509 PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE); 510 511 // both phone numbers should register here 512 Bundle tel1 = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"}); 513 Bundle tel2 = makeExtrasBundleWithPeople(new String[]{"tel:16175553434"}); 514 Bundle different = makeExtrasBundleWithPeople(new String[]{"tel:16175555656"}); 515 516 assertTrue("contact number 1 should match", 517 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 518 policy, UserHandle.SYSTEM, 519 tel1, null, 0, 0, 0)); 520 assertTrue("contact number 2 should match", 521 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 522 policy, UserHandle.SYSTEM, 523 tel2, null, 0, 0, 0)); 524 assertFalse("different number should not match", 525 ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS, 526 policy, UserHandle.SYSTEM, 527 different, null, 0, 0, 0)); 528 } 529 } 530