1 /* 2 * Copyright (C) 2016 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 package com.android.providers.blockednumber; 17 18 import static org.mockito.Matchers.anyInt; 19 import static org.mockito.Matchers.anyString; 20 import static org.mockito.Matchers.eq; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.reset; 23 import static org.mockito.Mockito.spy; 24 import static org.mockito.Mockito.times; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.app.AppOpsManager; 29 import android.content.ContentResolver; 30 import android.content.ContentUris; 31 import android.content.ContentValues; 32 import android.content.pm.PackageManager; 33 import android.database.ContentObserver; 34 import android.database.Cursor; 35 import android.database.sqlite.SQLiteException; 36 import android.location.Country; 37 import android.net.Uri; 38 import android.os.PersistableBundle; 39 import android.os.SystemProperties; 40 import android.provider.BlockedNumberContract; 41 import android.provider.BlockedNumberContract.BlockedNumbers; 42 import android.provider.BlockedNumberContract.SystemContract; 43 import android.telephony.CarrierConfigManager; 44 import android.telephony.TelephonyManager; 45 import android.test.AndroidTestCase; 46 import android.test.MoreAsserts; 47 import android.test.suitebuilder.annotation.MediumTest; 48 49 import junit.framework.Assert; 50 51 import java.util.concurrent.CountDownLatch; 52 import java.util.concurrent.TimeUnit; 53 54 /** 55 * runtest --path packages/providers/BlockedNumberProvider/tests 56 */ 57 @MediumTest 58 public class BlockedNumberProviderTest extends AndroidTestCase { 59 private MyMockContext mMockContext; 60 private ContentResolver mResolver; 61 62 @Override setUp()63 protected void setUp() throws Exception { 64 super.setUp(); 65 BlockedNumberProvider.ALLOW_SELF_CALL = false; 66 67 mMockContext = spy(new MyMockContext(getContext())); 68 mMockContext.initializeContext(); 69 mResolver = mMockContext.getContentResolver(); 70 71 when(mMockContext.mUserManager.isPrimaryUser()).thenReturn(true); 72 when(mMockContext.mCountryDetector.detectCountry()) 73 .thenReturn(new Country("US", Country.COUNTRY_SOURCE_LOCATION)); 74 when(mMockContext.mAppOpsManager.noteOp( 75 eq(AppOpsManager.OP_WRITE_SMS), anyInt(), anyString())) 76 .thenReturn(AppOpsManager.MODE_ERRORED); 77 } 78 79 @Override tearDown()80 protected void tearDown() throws Exception { 81 mMockContext.shutdown(); 82 83 super.tearDown(); 84 } 85 cv(Object... namesAndValues)86 private static ContentValues cv(Object... namesAndValues) { 87 Assert.assertTrue((namesAndValues.length % 2) == 0); 88 89 final ContentValues ret = new ContentValues(); 90 for (int i = 1; i < namesAndValues.length; i += 2) { 91 final String name = namesAndValues[i - 1].toString(); 92 final Object value = namesAndValues[i]; 93 if (value == null) { 94 ret.putNull(name); 95 } else if (value instanceof String) { 96 ret.put(name, (String) value); 97 } else if (value instanceof Integer) { 98 ret.put(name, (Integer) value); 99 } else if (value instanceof Long) { 100 ret.put(name, (Long) value); 101 } else { 102 Assert.fail("Unsupported type: " + value.getClass().getSimpleName()); 103 } 104 } 105 return ret; 106 } 107 assertRowCount(int count, Uri uri)108 private void assertRowCount(int count, Uri uri) { 109 try (Cursor c = mResolver.query(uri, null, null, null, null)) { 110 assertEquals(count, c.getCount()); 111 } 112 } 113 testGetType()114 public void testGetType() { 115 assertEquals(BlockedNumbers.CONTENT_TYPE, mResolver.getType( 116 BlockedNumbers.CONTENT_URI)); 117 118 assertEquals(BlockedNumbers.CONTENT_ITEM_TYPE, mResolver.getType( 119 ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 1))); 120 121 assertNull(mResolver.getType( 122 Uri.withAppendedPath(BlockedNumberContract.AUTHORITY_URI, "invalid"))); 123 } 124 testInsert()125 public void testInsert() { 126 insertExpectingFailure(cv()); 127 insertExpectingFailure(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, null)); 128 insertExpectingFailure(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "")); 129 insertExpectingFailure(cv(BlockedNumbers.COLUMN_ID, 1)); 130 insertExpectingFailure(cv(BlockedNumbers.COLUMN_E164_NUMBER, "1")); 131 132 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 133 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-2-3")); 134 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-408-454-1111")); 135 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-408-454-2222")); 136 // Re-inserting the same number should be ok, but the E164 number is replaced. 137 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-408-454-2222", 138 BlockedNumbers.COLUMN_E164_NUMBER, "+814084542222")); 139 140 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-408-4542222")); 141 142 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "045-381-1111", 143 BlockedNumbers.COLUMN_E164_NUMBER, "+81453811111")); 144 145 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "12345")); 146 147 148 149 assertRowCount(7, BlockedNumbers.CONTENT_URI); 150 151 assertContents(1, "123", ""); 152 assertContents(2, "+1-2-3", ""); 153 assertContents(3, "+1-408-454-1111", "+14084541111"); 154 // Missing 4 due to re-insertion of the same number. 155 assertContents(5, "1-408-454-2222", "+814084542222"); 156 assertContents(6, "1-408-4542222", "+14084542222"); 157 assertContents(7, "045-381-1111", "+81453811111"); 158 assertContents(8, "12345", ""); 159 } 160 testChangesNotified()161 public void testChangesNotified() throws Exception { 162 Cursor c = mResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null); 163 164 final CountDownLatch latch = new CountDownLatch(2); 165 ContentObserver contentObserver = new ContentObserver(null) { 166 @Override 167 public void onChange(boolean selfChange) { 168 Assert.assertFalse(selfChange); 169 latch.notify(); 170 } 171 }; 172 c.registerContentObserver(contentObserver); 173 174 try { 175 Uri uri = insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "14506507000")); 176 mResolver.delete(uri, null, null); 177 latch.await(10, TimeUnit.SECONDS); 178 verify(mMockContext.mBackupManager, times(2)).dataChanged(); 179 } catch (Exception e) { 180 fail(e.toString()); 181 } finally { 182 c.unregisterContentObserver(contentObserver); 183 } 184 } 185 insert(ContentValues cv)186 private Uri insert(ContentValues cv) { 187 final Uri uri = mResolver.insert(BlockedNumbers.CONTENT_URI, cv); 188 assertNotNull(uri); 189 190 // Make sure the URI exists. 191 try (Cursor c = mResolver.query(uri, null, null, null, null)) { 192 assertEquals(1, c.getCount()); 193 } 194 return uri; 195 } 196 insertExpectingFailure(ContentValues cv)197 private void insertExpectingFailure(ContentValues cv) { 198 try { 199 mResolver.insert( 200 BlockedNumbers.CONTENT_URI, cv); 201 fail(); 202 } catch (IllegalArgumentException expected) { 203 } 204 } 205 testDelete()206 public void testDelete() { 207 // Prepare test data 208 Uri u1 = insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 209 Uri u2 = insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-2-3")); 210 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-408-454-1111")); 211 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-408-454-2222")); 212 213 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "045-381-1111", 214 BlockedNumbers.COLUMN_E164_NUMBER, "12345")); 215 216 assertRowCount(5, BlockedNumbers.CONTENT_URI); 217 218 // Delete and check the # of remaining rows. 219 220 mResolver.delete(u1, null, null); 221 assertRowCount(4, BlockedNumbers.CONTENT_URI); 222 223 try { 224 mResolver.delete(u2, "1=1", null); 225 fail(); 226 } catch (IllegalArgumentException expected) { 227 MoreAsserts.assertContainsRegex("selection must be null", expected.getMessage()); 228 } 229 230 mResolver.delete(u2, null, null); 231 assertRowCount(3, BlockedNumbers.CONTENT_URI); 232 233 mResolver.delete(BlockedNumbers.CONTENT_URI, 234 BlockedNumbers.COLUMN_E164_NUMBER + "=?", 235 new String[]{"12345"}); 236 assertRowCount(2, BlockedNumbers.CONTENT_URI); 237 238 // SQL injection should be detected. 239 try { 240 mResolver.delete(BlockedNumbers.CONTENT_URI, "; DROP TABLE blocked; ", null); 241 fail(); 242 } catch (SQLiteException expected) { 243 } 244 assertRowCount(2, BlockedNumbers.CONTENT_URI); 245 246 mResolver.delete(BlockedNumbers.CONTENT_URI, null, null); 247 assertRowCount(0, BlockedNumbers.CONTENT_URI); 248 } 249 testUpdate()250 public void testUpdate() { 251 try { 252 mResolver.update(BlockedNumbers.CONTENT_URI, cv(), 253 /* selection =*/ null, /* args =*/ null); 254 fail(); 255 } catch (UnsupportedOperationException expected) { 256 MoreAsserts.assertContainsRegex("Update is not supported", expected.getMessage()); 257 } 258 } 259 testBlockSuppressionAfterEmergencyContact()260 public void testBlockSuppressionAfterEmergencyContact() { 261 int blockSuppressionSeconds = 1000; 262 when(mMockContext.mCarrierConfigManager.getConfig()) 263 .thenReturn(getBundleWithInt(blockSuppressionSeconds)); 264 265 String phoneNumber = "5004541111"; 266 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, phoneNumber)); 267 268 // No emergency contact: Blocks should not be suppressed. 269 assertIsBlocked(true, phoneNumber); 270 assertShouldSystemBlock(true, phoneNumber); 271 verifyBlocksNotSuppressed(); 272 assertTrue(mMockContext.mIntentsBroadcasted.isEmpty()); 273 274 // No emergency contact yet: Ending block suppression should be a no-op. 275 SystemContract.endBlockSuppression(mMockContext); 276 assertIsBlocked(true, phoneNumber); 277 assertShouldSystemBlock(true, phoneNumber); 278 verifyBlocksNotSuppressed(); 279 assertTrue(mMockContext.mIntentsBroadcasted.isEmpty()); 280 281 // After emergency contact blocks should be suppressed. 282 long timestampMillisBeforeEmergencyContact = System.currentTimeMillis(); 283 SystemContract.notifyEmergencyContact(mMockContext); 284 assertIsBlocked(true, phoneNumber); 285 assertShouldSystemBlock(false, phoneNumber); 286 SystemContract.BlockSuppressionStatus status = 287 SystemContract.getBlockSuppressionStatus(mMockContext); 288 assertTrue(status.isSuppressed); 289 assertValidBlockSuppressionExpiration(timestampMillisBeforeEmergencyContact, 290 blockSuppressionSeconds, status.untilTimestampMillis); 291 assertEquals(1, mMockContext.mIntentsBroadcasted.size()); 292 assertEquals(SystemContract.ACTION_BLOCK_SUPPRESSION_STATE_CHANGED, 293 mMockContext.mIntentsBroadcasted.get(0)); 294 mMockContext.mIntentsBroadcasted.clear(); 295 296 // Ending block suppression should work. 297 SystemContract.endBlockSuppression(mMockContext); 298 assertIsBlocked(true, phoneNumber); 299 assertShouldSystemBlock(true, phoneNumber); 300 verifyBlocksNotSuppressed(); 301 assertEquals(1, mMockContext.mIntentsBroadcasted.size()); 302 assertEquals(SystemContract.ACTION_BLOCK_SUPPRESSION_STATE_CHANGED, 303 mMockContext.mIntentsBroadcasted.get(0)); 304 } 305 testBlockSuppressionAfterEmergencyContact_invalidCarrierConfigDefaultValueUsed()306 public void testBlockSuppressionAfterEmergencyContact_invalidCarrierConfigDefaultValueUsed() { 307 int invalidBlockSuppressionSeconds = 700000; // > 1 week 308 when(mMockContext.mCarrierConfigManager.getConfig()) 309 .thenReturn(getBundleWithInt(invalidBlockSuppressionSeconds)); 310 311 String phoneNumber = "5004541111"; 312 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, phoneNumber)); 313 314 long timestampMillisBeforeEmergencyContact = System.currentTimeMillis(); 315 SystemContract.notifyEmergencyContact(mMockContext); 316 assertIsBlocked(true, phoneNumber); 317 assertShouldSystemBlock(false, phoneNumber); 318 SystemContract.BlockSuppressionStatus status = 319 SystemContract.getBlockSuppressionStatus(mMockContext); 320 assertTrue(status.isSuppressed); 321 assertValidBlockSuppressionExpiration(timestampMillisBeforeEmergencyContact, 322 7200 /* Default value of 2 hours */, status.untilTimestampMillis); 323 assertEquals(1, mMockContext.mIntentsBroadcasted.size()); 324 assertEquals(SystemContract.ACTION_BLOCK_SUPPRESSION_STATE_CHANGED, 325 mMockContext.mIntentsBroadcasted.get(0)); 326 } 327 testRegularAppCannotAccessApis()328 public void testRegularAppCannotAccessApis() { 329 doReturn(PackageManager.PERMISSION_DENIED) 330 .when(mMockContext).checkCallingPermission(anyString()); 331 332 try { 333 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 334 fail("SecurityException expected"); 335 } catch (SecurityException expected) { 336 } 337 338 try { 339 mResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null); 340 fail("SecurityException expected"); 341 } catch (SecurityException expected) { 342 } 343 344 try { 345 mResolver.delete(BlockedNumbers.CONTENT_URI, null, null); 346 fail("SecurityException expected"); 347 } catch (SecurityException expected) { 348 } 349 350 try { 351 BlockedNumberContract.isBlocked(mMockContext, "123"); 352 fail("SecurityException expected"); 353 } catch (SecurityException expected) { 354 } 355 356 try { 357 BlockedNumberContract.unblock(mMockContext, "123"); 358 fail("SecurityException expected"); 359 } catch (SecurityException expected) { 360 } 361 362 try { 363 SystemContract.notifyEmergencyContact(mMockContext); 364 fail("SecurityException expected"); 365 } catch (SecurityException expected) { 366 } 367 368 try { 369 SystemContract.endBlockSuppression(mMockContext); 370 fail("SecurityException expected"); 371 } catch (SecurityException expected) { 372 } 373 374 try { 375 SystemContract.shouldSystemBlockNumber(mMockContext, "123"); 376 fail("SecurityException expected"); 377 } catch (SecurityException expected) { 378 } 379 380 try { 381 SystemContract.getBlockSuppressionStatus(mMockContext); 382 fail("SecurityException expected"); 383 } catch (SecurityException expected) { 384 } 385 } 386 testCarrierAppCanAccessApis()387 public void testCarrierAppCanAccessApis() { 388 doReturn(PackageManager.PERMISSION_DENIED) 389 .when(mMockContext).checkCallingPermission(anyString()); 390 when(mMockContext.mTelephonyManager.checkCarrierPrivilegesForPackage(anyString())) 391 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS); 392 393 mResolver.insert( 394 BlockedNumbers.CONTENT_URI, cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 395 assertIsBlocked(true, "123"); 396 397 398 // Dialer check is executed twice: once for insert, and once for isBlocked. 399 verify(mMockContext.mTelephonyManager, times(2)) 400 .checkCarrierPrivilegesForPackage(anyString()); 401 } 402 testSelfCanAccessApis()403 public void testSelfCanAccessApis() { 404 BlockedNumberProvider.ALLOW_SELF_CALL = true; 405 doReturn(PackageManager.PERMISSION_DENIED) 406 .when(mMockContext).checkCallingPermission(anyString()); 407 408 mResolver.insert( 409 BlockedNumbers.CONTENT_URI, cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 410 assertIsBlocked(true, "123"); 411 } 412 testDefaultDialerCanAccessApis()413 public void testDefaultDialerCanAccessApis() { 414 doReturn(PackageManager.PERMISSION_DENIED) 415 .when(mMockContext).checkCallingPermission(anyString()); 416 when(mMockContext.mTelecomManager.getDefaultDialerPackage()) 417 .thenReturn(getContext().getPackageName()); 418 419 mResolver.insert( 420 BlockedNumbers.CONTENT_URI, cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 421 assertIsBlocked(true, "123"); 422 423 // Dialer check is executed twice: once for insert, and once for isBlocked. 424 verify(mMockContext.mTelecomManager, times(2)).getDefaultDialerPackage(); 425 } 426 testPrivilegedAppCannotUseSystemApis()427 public void testPrivilegedAppCannotUseSystemApis() { 428 reset(mMockContext.mAppOpsManager); 429 doReturn(PackageManager.PERMISSION_DENIED) 430 .when(mMockContext).checkCallingPermission(anyString()); 431 432 // Pretend to be the Default SMS app. 433 when(mMockContext.mAppOpsManager.noteOp( 434 eq(AppOpsManager.OP_WRITE_SMS), anyInt(), anyString())) 435 .thenReturn(AppOpsManager.MODE_ALLOWED); 436 437 // Public APIs should work. 438 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 439 assertIsBlocked(true, "123"); 440 441 try { 442 SystemContract.notifyEmergencyContact(mMockContext); 443 fail("SecurityException expected"); 444 } catch (SecurityException expected) { 445 } 446 447 try { 448 SystemContract.endBlockSuppression(mMockContext); 449 fail("SecurityException expected"); 450 } catch (SecurityException expected) { 451 } 452 453 try { 454 SystemContract.shouldSystemBlockNumber(mMockContext, "123"); 455 fail("SecurityException expected"); 456 } catch (SecurityException expected) { 457 } 458 459 try { 460 SystemContract.getBlockSuppressionStatus(mMockContext); 461 fail("SecurityException expected"); 462 } catch (SecurityException expected) { 463 } 464 } 465 testIsBlocked()466 public void testIsBlocked() { 467 assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mMockContext)); 468 469 // Prepare test data 470 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 471 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1.2-3")); 472 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-500-454-1111")); 473 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-500-454-2222")); 474 475 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "045-111-2222", 476 BlockedNumbers.COLUMN_E164_NUMBER, "+81451112222")); 477 478 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "abc.def@gmail.com")); 479 480 // Check 481 assertIsBlocked(false, ""); 482 assertIsBlocked(false, null); 483 assertIsBlocked(true, "123"); 484 assertIsBlocked(false, "1234"); 485 assertIsBlocked(true, "+81451112222"); 486 assertIsBlocked(true, "+81 45 111 2222"); 487 assertIsBlocked(true, "045-111-2222"); 488 assertIsBlocked(false, "045 111 2222"); 489 490 assertIsBlocked(true, "500-454 1111"); 491 assertIsBlocked(true, "500-454 2222"); 492 assertIsBlocked(true, "+1 500-454 1111"); 493 assertIsBlocked(true, "1 500-454 1111"); 494 495 assertIsBlocked(true, "abc.def@gmail.com"); 496 assertIsBlocked(false, "abc.def@gmail.co"); 497 assertIsBlocked(false, "bc.def@gmail.com"); 498 assertIsBlocked(false, "abcdef@gmail.com"); 499 } 500 testUnblock()501 public void testUnblock() { 502 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "+1-500-454-1111")); 503 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1500-454-1111")); 504 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "abc.def@gmail.com")); 505 506 // Unblocking non-existent number is a no-op. 507 assertEquals(0, BlockedNumberContract.unblock(mMockContext, "12345")); 508 509 // Both rows which map to the same E164 number are deleted. 510 assertEquals(2, BlockedNumberContract.unblock(mMockContext, "5004541111")); 511 assertIsBlocked(false, "1-500-454-1111"); 512 513 assertEquals(1, BlockedNumberContract.unblock(mMockContext, "abc.def@gmail.com")); 514 assertIsBlocked(false, "abc.def@gmail.com"); 515 } 516 testEmergencyNumbersAreNotBlockedBySystem()517 public void testEmergencyNumbersAreNotBlockedBySystem() { 518 String emergencyNumber = getEmergencyNumberFromSystemPropertiesOrDefault(); 519 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, emergencyNumber)); 520 521 assertIsBlocked(true, emergencyNumber); 522 assertFalse(SystemContract.shouldSystemBlockNumber(mMockContext, emergencyNumber)); 523 } 524 testPrivilegedAppAccessingApisAsSecondaryUser()525 public void testPrivilegedAppAccessingApisAsSecondaryUser() { 526 when(mMockContext.mUserManager.isPrimaryUser()).thenReturn(false); 527 528 assertFalse(BlockedNumberContract.canCurrentUserBlockNumbers(mMockContext)); 529 530 try { 531 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 532 fail("SecurityException expected"); 533 } catch (SecurityException expected) { 534 assertTrue(expected.getMessage().contains("current user")); 535 } 536 537 try { 538 mResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null); 539 fail("SecurityException expected"); 540 } catch (SecurityException expected) { 541 } 542 543 try { 544 mResolver.delete(BlockedNumbers.CONTENT_URI, null, null); 545 fail("SecurityException expected"); 546 } catch (SecurityException expected) { 547 } 548 549 try { 550 BlockedNumberContract.isBlocked(mMockContext, "123"); 551 fail("SecurityException expected"); 552 } catch (SecurityException expected) { 553 } 554 555 try { 556 BlockedNumberContract.unblock(mMockContext, "123"); 557 fail("SecurityException expected"); 558 } catch (SecurityException expected) { 559 } 560 } 561 testRegularAppAccessingApisAsSecondaryUser()562 public void testRegularAppAccessingApisAsSecondaryUser() { 563 when(mMockContext.mUserManager.isPrimaryUser()).thenReturn(false); 564 doReturn(PackageManager.PERMISSION_DENIED) 565 .when(mMockContext).checkCallingPermission(anyString()); 566 567 assertFalse(BlockedNumberContract.canCurrentUserBlockNumbers(mMockContext)); 568 569 try { 570 insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123")); 571 fail("SecurityException expected"); 572 } catch (SecurityException expected) { 573 } 574 575 try { 576 mResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null); 577 fail("SecurityException expected"); 578 } catch (SecurityException expected) { 579 } 580 581 try { 582 mResolver.delete(BlockedNumbers.CONTENT_URI, null, null); 583 fail("SecurityException expected"); 584 } catch (SecurityException expected) { 585 } 586 587 try { 588 BlockedNumberContract.isBlocked(mMockContext, "123"); 589 fail("SecurityException expected"); 590 } catch (SecurityException expected) { 591 } 592 593 try { 594 BlockedNumberContract.unblock(mMockContext, "123"); 595 fail("SecurityException expected"); 596 } catch (SecurityException expected) { 597 } 598 } 599 assertIsBlocked(boolean expected, String phoneNumber)600 private void assertIsBlocked(boolean expected, String phoneNumber) { 601 assertEquals(expected, BlockedNumberContract.isBlocked(mMockContext, phoneNumber)); 602 } 603 assertShouldSystemBlock(boolean expected, String phoneNumber)604 private void assertShouldSystemBlock(boolean expected, String phoneNumber) { 605 assertEquals(expected, SystemContract.shouldSystemBlockNumber(mMockContext, phoneNumber)); 606 } 607 getBundleWithInt(int value)608 private PersistableBundle getBundleWithInt(int value) { 609 PersistableBundle bundle = new PersistableBundle(); 610 bundle.putInt( 611 CarrierConfigManager.KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT, value); 612 return bundle; 613 } 614 verifyBlocksNotSuppressed()615 private void verifyBlocksNotSuppressed() { 616 SystemContract.BlockSuppressionStatus status = 617 SystemContract.getBlockSuppressionStatus(mMockContext); 618 assertFalse(status.isSuppressed); 619 assertEquals(0, status.untilTimestampMillis); 620 } 621 assertValidBlockSuppressionExpiration(long timestampMillisBeforeEmergencyContact, int blockSuppressionSeconds, long actualExpirationMillis)622 private void assertValidBlockSuppressionExpiration(long timestampMillisBeforeEmergencyContact, 623 int blockSuppressionSeconds, 624 long actualExpirationMillis) { 625 assertTrue(actualExpirationMillis 626 >= timestampMillisBeforeEmergencyContact + blockSuppressionSeconds * 1000); 627 assertTrue(actualExpirationMillis < timestampMillisBeforeEmergencyContact + 628 2 * blockSuppressionSeconds * 1000); 629 } 630 631 private void assertContents(int rowId, String originalNumber, String e164Number) { 632 Uri uri = ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, rowId); 633 try (Cursor c = mResolver.query(uri, null, null, null, null)) { 634 assertEquals(1, c.getCount()); 635 c.moveToNext(); 636 assertEquals(3, c.getColumnCount()); 637 assertEquals(rowId, c.getInt(c.getColumnIndex(BlockedNumbers.COLUMN_ID))); 638 assertEquals(originalNumber, 639 c.getString(c.getColumnIndex(BlockedNumbers.COLUMN_ORIGINAL_NUMBER))); 640 assertEquals(e164Number, 641 c.getString(c.getColumnIndex(BlockedNumbers.COLUMN_E164_NUMBER))); 642 } 643 } 644 645 private String getEmergencyNumberFromSystemPropertiesOrDefault() { 646 String systemEmergencyNumbers = SystemProperties.get("ril.ecclist"); 647 if (systemEmergencyNumbers == null) { 648 return "911"; 649 } else { 650 return systemEmergencyNumbers.split(",")[0]; 651 } 652 } 653 } 654