1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; 4 import static android.os.Build.VERSION_CODES.M; 5 import static android.os.Build.VERSION_CODES.N; 6 import static android.os.Build.VERSION_CODES.O; 7 import static android.os.Build.VERSION_CODES.Q; 8 import static android.os.Build.VERSION_CODES.R; 9 import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; 10 import static com.google.common.truth.Truth.assertThat; 11 import static org.junit.Assert.assertThrows; 12 import static org.mockito.ArgumentMatchers.eq; 13 import static org.mockito.Mockito.times; 14 import static org.mockito.Mockito.verify; 15 import static org.mockito.Mockito.verifyNoMoreInteractions; 16 import static org.robolectric.Shadows.shadowOf; 17 18 import android.app.Activity; 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.pm.PackageManager.NameNotFoundException; 24 import android.net.Uri; 25 import android.os.Build; 26 import android.os.Bundle; 27 import android.telecom.ConnectionRequest; 28 import android.telecom.PhoneAccount; 29 import android.telecom.PhoneAccountHandle; 30 import android.telecom.TelecomManager; 31 import android.telecom.VideoProfile; 32 import androidx.test.core.app.ApplicationProvider; 33 import androidx.test.ext.junit.runners.AndroidJUnit4; 34 import java.util.List; 35 import org.junit.Before; 36 import org.junit.Rule; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.mockito.ArgumentCaptor; 40 import org.mockito.Mock; 41 import org.mockito.junit.MockitoJUnit; 42 import org.mockito.junit.MockitoRule; 43 import org.robolectric.Robolectric; 44 import org.robolectric.android.controller.ActivityController; 45 import org.robolectric.android.controller.ServiceController; 46 import org.robolectric.annotation.Config; 47 import org.robolectric.shadows.ShadowTelecomManager.CallRequestMode; 48 import org.robolectric.shadows.testing.TestConnectionService; 49 50 @RunWith(AndroidJUnit4.class) 51 public class ShadowTelecomManagerTest { 52 53 @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); 54 55 @Mock TestConnectionService.Listener connectionServiceListener; 56 57 private TelecomManager telecomService; 58 private Context context; 59 60 @Before setUp()61 public void setUp() { 62 telecomService = 63 (TelecomManager) 64 ApplicationProvider.getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 65 TestConnectionService.setListener(connectionServiceListener); 66 context = ApplicationProvider.getApplicationContext(); 67 } 68 69 @Test getSimCallManager()70 public void getSimCallManager() { 71 PhoneAccountHandle handle = createHandle("id"); 72 73 shadowOf(telecomService).setSimCallManager(handle); 74 75 assertThat(telecomService.getConnectionManager().getId()).isEqualTo("id"); 76 } 77 78 @Test registerAndUnRegister()79 public void registerAndUnRegister() { 80 assertThat(shadowOf(telecomService).getAllPhoneAccountsCount()).isEqualTo(0); 81 assertThat(shadowOf(telecomService).getAllPhoneAccounts()).hasSize(0); 82 83 PhoneAccountHandle handler = createHandle("id"); 84 PhoneAccount phoneAccount = PhoneAccount.builder(handler, "main_account").build(); 85 telecomService.registerPhoneAccount(phoneAccount); 86 87 assertThat(shadowOf(telecomService).getAllPhoneAccountsCount()).isEqualTo(1); 88 assertThat(shadowOf(telecomService).getAllPhoneAccounts()).hasSize(1); 89 assertThat(telecomService.getAllPhoneAccountHandles()).hasSize(1); 90 assertThat(telecomService.getAllPhoneAccountHandles()).contains(handler); 91 assertThat(telecomService.getPhoneAccount(handler).getLabel().toString()) 92 .isEqualTo(phoneAccount.getLabel().toString()); 93 94 telecomService.unregisterPhoneAccount(handler); 95 96 assertThat(shadowOf(telecomService).getAllPhoneAccountsCount()).isEqualTo(0); 97 assertThat(shadowOf(telecomService).getAllPhoneAccounts()).hasSize(0); 98 assertThat(telecomService.getAllPhoneAccountHandles()).hasSize(0); 99 } 100 101 @Test 102 @Config(minSdk = UPSIDE_DOWN_CAKE) registerWithTransactionalCapabilites_addsSelfManagedCapability()103 public void registerWithTransactionalCapabilites_addsSelfManagedCapability() { 104 PhoneAccountHandle handle = createHandle("id"); 105 PhoneAccount phoneAccount = 106 PhoneAccount.builder(handle, "main_account") 107 // Transactional, but not explicitly self-managed. 108 .setCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS) 109 .build(); 110 telecomService.registerPhoneAccount(phoneAccount); 111 112 assertThat(telecomService.getSelfManagedPhoneAccounts()).contains(handle); 113 } 114 115 @Test getPhoneAccount_noPermission_throwsSecurityException()116 public void getPhoneAccount_noPermission_throwsSecurityException() { 117 shadowOf(telecomService).setReadPhoneStatePermission(false); 118 119 PhoneAccountHandle handler = createHandle("id"); 120 assertThrows(SecurityException.class, () -> telecomService.getPhoneAccount(handler)); 121 } 122 123 @Test clearAccounts()124 public void clearAccounts() { 125 PhoneAccountHandle anotherPackageHandle = 126 createHandle("some.other.package", "OtherConnectionService", "id"); 127 telecomService.registerPhoneAccount( 128 PhoneAccount.builder(anotherPackageHandle, "another_package").build()); 129 } 130 131 @Test 132 @Config(minSdk = LOLLIPOP_MR1) clearAccountsForPackage()133 public void clearAccountsForPackage() { 134 PhoneAccountHandle accountHandle1 = createHandle("a.package", "OtherConnectionService", "id1"); 135 telecomService.registerPhoneAccount( 136 PhoneAccount.builder(accountHandle1, "another_package").build()); 137 138 PhoneAccountHandle accountHandle2 = 139 createHandle("some.other.package", "OtherConnectionService", "id2"); 140 telecomService.registerPhoneAccount( 141 PhoneAccount.builder(accountHandle2, "another_package").build()); 142 143 telecomService.clearAccountsForPackage(accountHandle1.getComponentName().getPackageName()); 144 145 assertThat(telecomService.getPhoneAccount(accountHandle1)).isNull(); 146 assertThat(telecomService.getPhoneAccount(accountHandle2)).isNotNull(); 147 } 148 149 @Test 150 @Config(minSdk = M) enableNonRegisteredAccountDoesNothing()151 public void enableNonRegisteredAccountDoesNothing() { 152 PhoneAccountHandle accountHandle1 = createHandle("a.package", "OtherConnectionService", "id1"); 153 telecomService.registerPhoneAccount( 154 PhoneAccount.builder(accountHandle1, "another_package").build()); 155 156 // Attempt to enable phone account that hasn't been registered should do nothing. 157 PhoneAccountHandle accountHandle2 = 158 createHandle("some.other.package", "OtherConnectionService", "id2"); 159 telecomService.enablePhoneAccount(accountHandle2, /* isEnabled= */ true); 160 161 assertThat(telecomService.getPhoneAccount(accountHandle1).isEnabled()).isFalse(); 162 } 163 164 @Test getPhoneAccountsSupportingScheme()165 public void getPhoneAccountsSupportingScheme() { 166 PhoneAccountHandle handleMatchingScheme = createHandle("id1"); 167 telecomService.registerPhoneAccount( 168 PhoneAccount.builder(handleMatchingScheme, "some_scheme") 169 .addSupportedUriScheme("some_scheme") 170 .build()); 171 PhoneAccountHandle handleNotMatchingScheme = createHandle("id2"); 172 telecomService.registerPhoneAccount( 173 PhoneAccount.builder(handleNotMatchingScheme, "another_scheme") 174 .addSupportedUriScheme("another_scheme") 175 .build()); 176 177 List<PhoneAccountHandle> actual = 178 telecomService.getPhoneAccountsSupportingScheme("some_scheme"); 179 180 assertThat(actual).contains(handleMatchingScheme); 181 assertThat(actual).doesNotContain(handleNotMatchingScheme); 182 } 183 184 @Test 185 @Config(minSdk = M) getCallCapablePhoneAccounts()186 public void getCallCapablePhoneAccounts() { 187 PhoneAccountHandle callCapableHandle = createHandle("id1"); 188 telecomService.registerPhoneAccount( 189 PhoneAccount.builder(callCapableHandle, "enabled").setIsEnabled(true).build()); 190 PhoneAccountHandle notCallCapableHandler = createHandle("id2"); 191 telecomService.registerPhoneAccount( 192 PhoneAccount.builder(notCallCapableHandler, "disabled").setIsEnabled(false).build()); 193 194 List<PhoneAccountHandle> callCapablePhoneAccounts = 195 telecomService.getCallCapablePhoneAccounts(); 196 assertThat(callCapablePhoneAccounts).contains(callCapableHandle); 197 assertThat(callCapablePhoneAccounts).doesNotContain(notCallCapableHandler); 198 } 199 200 @Test 201 @Config(minSdk = M) getCallCapablePhoneAccounts_noPermission_throwsSecurityException()202 public void getCallCapablePhoneAccounts_noPermission_throwsSecurityException() { 203 shadowOf(telecomService).setReadPhoneStatePermission(false); 204 205 assertThrows(SecurityException.class, () -> telecomService.getCallCapablePhoneAccounts()); 206 } 207 208 @Test 209 @Config(minSdk = O) getSelfManagedPhoneAccounts()210 public void getSelfManagedPhoneAccounts() { 211 PhoneAccountHandle selfManagedPhoneAccountHandle = createHandle("id1"); 212 telecomService.registerPhoneAccount( 213 PhoneAccount.builder(selfManagedPhoneAccountHandle, "self-managed") 214 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED) 215 .build()); 216 PhoneAccountHandle nonSelfManagedPhoneAccountHandle = createHandle("id2"); 217 telecomService.registerPhoneAccount( 218 PhoneAccount.builder(nonSelfManagedPhoneAccountHandle, "not-self-managed").build()); 219 220 List<PhoneAccountHandle> selfManagedPhoneAccounts = 221 telecomService.getSelfManagedPhoneAccounts(); 222 assertThat(selfManagedPhoneAccounts).containsExactly(selfManagedPhoneAccountHandle); 223 } 224 225 @Test 226 @Config(minSdk = LOLLIPOP_MR1) getPhoneAccountsForPackage()227 public void getPhoneAccountsForPackage() { 228 PhoneAccountHandle handleInThisApplicationsPackage = createHandle("id1"); 229 telecomService.registerPhoneAccount( 230 PhoneAccount.builder(handleInThisApplicationsPackage, "this_package").build()); 231 232 PhoneAccountHandle anotherPackageHandle = 233 createHandle("some.other.package", "OtherConnectionService", "id2"); 234 telecomService.registerPhoneAccount( 235 PhoneAccount.builder(anotherPackageHandle, "another_package").build()); 236 237 List<PhoneAccountHandle> phoneAccountsForPackage = telecomService.getPhoneAccountsForPackage(); 238 239 assertThat(phoneAccountsForPackage).contains(handleInThisApplicationsPackage); 240 assertThat(phoneAccountsForPackage).doesNotContain(anotherPackageHandle); 241 } 242 243 @Test testAddNewIncomingCall()244 public void testAddNewIncomingCall() { 245 telecomService.addNewIncomingCall(createHandle("id"), null); 246 247 assertThat(shadowOf(telecomService).getAllIncomingCalls()).hasSize(1); 248 assertThat(shadowOf(telecomService).getLastIncomingCall()).isNotNull(); 249 assertThat(shadowOf(telecomService).getOnlyIncomingCall()).isNotNull(); 250 } 251 252 @Test testAllowNewIncomingCall()253 public void testAllowNewIncomingCall() { 254 shadowOf(telecomService).setCallRequestMode(CallRequestMode.ALLOW_ALL); 255 256 Uri address = Uri.parse("tel:+1-201-555-0123"); 257 PhoneAccountHandle phoneAccount = createHandle("id"); 258 Bundle extras = new Bundle(); 259 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, address); 260 extras.putInt( 261 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); 262 extras.putString("TEST_EXTRA_KEY", "TEST_EXTRA_VALUE"); 263 telecomService.addNewIncomingCall(createHandle("id"), extras); 264 265 verify(connectionServiceListener).onCreate(); 266 ArgumentCaptor<ConnectionRequest> requestCaptor = 267 ArgumentCaptor.forClass(ConnectionRequest.class); 268 verify(connectionServiceListener) 269 .onCreateIncomingConnection(eq(phoneAccount), requestCaptor.capture()); 270 verifyNoMoreInteractions(connectionServiceListener); 271 272 ConnectionRequest request = requestCaptor.getValue(); 273 assertThat(request.getAccountHandle()).isEqualTo(phoneAccount); 274 assertThat(request.getExtras().getString("TEST_EXTRA_KEY")).isEqualTo("TEST_EXTRA_VALUE"); 275 assertThat(request.getAddress()).isEqualTo(address); 276 assertThat(request.getVideoState()).isEqualTo(VideoProfile.STATE_BIDIRECTIONAL); 277 } 278 279 @Test testAllowTwoNewIncomingCalls()280 public void testAllowTwoNewIncomingCalls() { 281 shadowOf(telecomService).setCallRequestMode(CallRequestMode.ALLOW_ALL); 282 283 PhoneAccountHandle phoneAccount = createHandle("id"); 284 Uri address1 = Uri.parse("tel:+1-201-555-0123"); 285 Bundle call1 = new Bundle(); 286 call1.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, address1); 287 telecomService.addNewIncomingCall(createHandle("id"), call1); 288 289 Uri address2 = Uri.parse("tel:+1-201-555-0124"); 290 Bundle call2 = new Bundle(); 291 call2.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, address2); 292 telecomService.addNewIncomingCall(createHandle("id"), call2); 293 294 verify(connectionServiceListener, times(1)).onCreate(); 295 ArgumentCaptor<ConnectionRequest> requestCaptor = 296 ArgumentCaptor.forClass(ConnectionRequest.class); 297 verify(connectionServiceListener, times(2)) 298 .onCreateIncomingConnection(eq(phoneAccount), requestCaptor.capture()); 299 verifyNoMoreInteractions(connectionServiceListener); 300 301 List<ConnectionRequest> values = requestCaptor.getAllValues(); 302 assertThat(values.size()).isEqualTo(2); 303 ConnectionRequest request1 = values.get(0); 304 ConnectionRequest request2 = values.get(1); 305 assertThat(request1.getAddress()).isEqualTo(address1); 306 assertThat(request2.getAddress()).isEqualTo(address2); 307 } 308 309 @Test testAllowNewIncomingCallUsingCustomConnectionService()310 public void testAllowNewIncomingCallUsingCustomConnectionService() { 311 shadowOf(telecomService).setCallRequestMode(CallRequestMode.ALLOW_ALL); 312 TestConnectionService connectionService = 313 ServiceController.of(new TestConnectionService(), null).create().get(); 314 shadowOf(telecomService).setConnectionService(connectionService); 315 316 PhoneAccountHandle phoneAccount = createHandle("id"); 317 Uri address = Uri.parse("tel:+1-201-555-0123"); 318 Bundle call = new Bundle(); 319 call.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, address); 320 telecomService.addNewIncomingCall(createHandle("id"), call); 321 322 verify(connectionServiceListener).onCreate(); 323 ArgumentCaptor<ConnectionRequest> requestCaptor = 324 ArgumentCaptor.forClass(ConnectionRequest.class); 325 verify(connectionServiceListener) 326 .onCreateIncomingConnection(eq(phoneAccount), requestCaptor.capture()); 327 verifyNoMoreInteractions(connectionServiceListener); 328 329 ConnectionRequest request = requestCaptor.getValue(); 330 assertThat(request.getAddress()).isEqualTo(address); 331 } 332 333 @Test 334 @Config(minSdk = O) testDenyNewIncomingCall()335 public void testDenyNewIncomingCall() { 336 shadowOf(telecomService).setCallRequestMode(CallRequestMode.DENY_ALL); 337 338 Uri address = Uri.parse("tel:+1-201-555-0123"); 339 PhoneAccountHandle phoneAccount = createHandle("id"); 340 Bundle extras = new Bundle(); 341 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, address); 342 extras.putInt( 343 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); 344 extras.putString("TEST_EXTRA_KEY", "TEST_EXTRA_VALUE"); 345 telecomService.addNewIncomingCall(createHandle("id"), extras); 346 347 verify(connectionServiceListener).onCreate(); 348 ArgumentCaptor<ConnectionRequest> requestCaptor = 349 ArgumentCaptor.forClass(ConnectionRequest.class); 350 verify(connectionServiceListener) 351 .onCreateIncomingConnectionFailed(eq(phoneAccount), requestCaptor.capture()); 352 verifyNoMoreInteractions(connectionServiceListener); 353 354 ConnectionRequest request = requestCaptor.getValue(); 355 assertThat(request.getAccountHandle()).isEqualTo(phoneAccount); 356 assertThat(request.getExtras().getString("TEST_EXTRA_KEY")).isEqualTo("TEST_EXTRA_VALUE"); 357 assertThat(request.getAddress()).isEqualTo(address); 358 assertThat(request.getVideoState()).isEqualTo(VideoProfile.STATE_BIDIRECTIONAL); 359 } 360 361 @Test 362 @Config(minSdk = M) testPlaceCall()363 public void testPlaceCall() { 364 Bundle extras = new Bundle(); 365 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, createHandle("id")); 366 telecomService.placeCall(Uri.parse("tel:+1-201-555-0123"), extras); 367 368 assertThat(shadowOf(telecomService).getAllOutgoingCalls()).hasSize(1); 369 assertThat(shadowOf(telecomService).getLastOutgoingCall()).isNotNull(); 370 assertThat(shadowOf(telecomService).getOnlyOutgoingCall()).isNotNull(); 371 } 372 373 @Test 374 @Config(minSdk = M) testPlaceCall_noPermission_throwsSecurityException()375 public void testPlaceCall_noPermission_throwsSecurityException() { 376 shadowOf(telecomService).setCallPhonePermission(false); 377 378 Bundle extras = new Bundle(); 379 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, createHandle("id")); 380 381 assertThrows( 382 SecurityException.class, 383 () -> telecomService.placeCall(Uri.parse("tel:+1-201-555-0123"), extras)); 384 } 385 386 @Test 387 @Config(minSdk = M) testAllowPlaceCall()388 public void testAllowPlaceCall() { 389 shadowOf(telecomService).setCallRequestMode(CallRequestMode.ALLOW_ALL); 390 391 Uri address = Uri.parse("tel:+1-201-555-0123"); 392 PhoneAccountHandle phoneAccount = createHandle("id"); 393 Bundle outgoingCallExtras = new Bundle(); 394 outgoingCallExtras.putString("TEST_EXTRA_KEY", "TEST_EXTRA_VALUE"); 395 Bundle extras = new Bundle(); 396 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccount); 397 extras.putInt( 398 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); 399 extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, outgoingCallExtras); 400 telecomService.placeCall(address, extras); 401 402 verify(connectionServiceListener).onCreate(); 403 ArgumentCaptor<ConnectionRequest> requestCaptor = 404 ArgumentCaptor.forClass(ConnectionRequest.class); 405 verify(connectionServiceListener) 406 .onCreateOutgoingConnection(eq(phoneAccount), requestCaptor.capture()); 407 verifyNoMoreInteractions(connectionServiceListener); 408 409 ConnectionRequest request = requestCaptor.getValue(); 410 assertThat(request.getAccountHandle()).isEqualTo(phoneAccount); 411 assertThat(request.getExtras().getString("TEST_EXTRA_KEY")).isEqualTo("TEST_EXTRA_VALUE"); 412 assertThat(request.getAddress()).isEqualTo(address); 413 assertThat(request.getVideoState()).isEqualTo(VideoProfile.STATE_BIDIRECTIONAL); 414 } 415 416 @Test 417 @Config(minSdk = O) testDenyPlaceCall()418 public void testDenyPlaceCall() { 419 shadowOf(telecomService).setCallRequestMode(CallRequestMode.DENY_ALL); 420 421 Uri address = Uri.parse("tel:+1-201-555-0123"); 422 PhoneAccountHandle phoneAccount = createHandle("id"); 423 Bundle outgoingCallExtras = new Bundle(); 424 outgoingCallExtras.putString("TEST_EXTRA_KEY", "TEST_EXTRA_VALUE"); 425 Bundle extras = new Bundle(); 426 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccount); 427 extras.putInt( 428 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL); 429 extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, outgoingCallExtras); 430 telecomService.placeCall(address, extras); 431 432 verify(connectionServiceListener).onCreate(); 433 ArgumentCaptor<ConnectionRequest> requestCaptor = 434 ArgumentCaptor.forClass(ConnectionRequest.class); 435 verify(connectionServiceListener) 436 .onCreateOutgoingConnectionFailed(eq(phoneAccount), requestCaptor.capture()); 437 verifyNoMoreInteractions(connectionServiceListener); 438 439 ConnectionRequest request = requestCaptor.getValue(); 440 assertThat(request.getAccountHandle()).isEqualTo(phoneAccount); 441 assertThat(request.getExtras().getString("TEST_EXTRA_KEY")).isEqualTo("TEST_EXTRA_VALUE"); 442 assertThat(request.getAddress()).isEqualTo(address); 443 assertThat(request.getVideoState()).isEqualTo(VideoProfile.STATE_BIDIRECTIONAL); 444 } 445 446 @Test testAddUnknownCall()447 public void testAddUnknownCall() { 448 telecomService.addNewUnknownCall(createHandle("id"), null); 449 450 assertThat(shadowOf(telecomService).getAllUnknownCalls()).hasSize(1); 451 assertThat(shadowOf(telecomService).getLastUnknownCall()).isNotNull(); 452 assertThat(shadowOf(telecomService).getOnlyUnknownCall()).isNotNull(); 453 } 454 455 @Test testIsRinging_noIncomingOrUnknownCallsAdded_shouldBeFalse()456 public void testIsRinging_noIncomingOrUnknownCallsAdded_shouldBeFalse() { 457 assertThat(shadowOf(telecomService).isRinging()).isFalse(); 458 } 459 460 @Test testIsRinging_incomingCallAdded_shouldBeTrue()461 public void testIsRinging_incomingCallAdded_shouldBeTrue() { 462 telecomService.addNewIncomingCall(createHandle("id"), null); 463 464 assertThat(shadowOf(telecomService).isRinging()).isTrue(); 465 } 466 467 @Test testIsRinging_unknownCallAdded_shouldBeTrue()468 public void testIsRinging_unknownCallAdded_shouldBeTrue() { 469 shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null); 470 471 assertThat(shadowOf(telecomService).isRinging()).isTrue(); 472 } 473 474 @Test testIsRinging_incomingCallAdded_thenRingerSilenced_shouldBeFalse()475 public void testIsRinging_incomingCallAdded_thenRingerSilenced_shouldBeFalse() { 476 telecomService.addNewIncomingCall(createHandle("id"), null); 477 telecomService.silenceRinger(); 478 479 assertThat(shadowOf(telecomService).isRinging()).isFalse(); 480 } 481 482 @Test testIsRinging_unknownCallAdded_thenRingerSilenced_shouldBeFalse()483 public void testIsRinging_unknownCallAdded_thenRingerSilenced_shouldBeFalse() { 484 shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null); 485 telecomService.silenceRinger(); 486 487 assertThat(shadowOf(telecomService).isRinging()).isFalse(); 488 } 489 490 @Test testIsRinging_ringerSilenced_thenIncomingCallAdded_shouldBeTrue()491 public void testIsRinging_ringerSilenced_thenIncomingCallAdded_shouldBeTrue() { 492 telecomService.silenceRinger(); 493 telecomService.addNewIncomingCall(createHandle("id"), null); 494 495 assertThat(shadowOf(telecomService).isRinging()).isTrue(); 496 } 497 498 @Test testIsRinging_ringerSilenced_thenUnknownCallAdded_shouldBeTrue()499 public void testIsRinging_ringerSilenced_thenUnknownCallAdded_shouldBeTrue() { 500 telecomService.silenceRinger(); 501 shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null); 502 503 assertThat(shadowOf(telecomService).isRinging()).isTrue(); 504 } 505 506 @Test 507 @Config(minSdk = M) setDefaultDialer()508 public void setDefaultDialer() { 509 assertThat(telecomService.getDefaultDialerPackage()).isNull(); 510 shadowOf(telecomService).setDefaultDialer("some.package"); 511 assertThat(telecomService.getDefaultDialerPackage()).isEqualTo("some.package"); 512 } 513 514 @Test 515 @Config(minSdk = M) setDefaultDialerPackage()516 public void setDefaultDialerPackage() { 517 assertThat(telecomService.getDefaultDialerPackage()).isNull(); 518 shadowOf(telecomService).setDefaultDialerPackage("some.package"); 519 assertThat(telecomService.getDefaultDialerPackage()).isEqualTo("some.package"); 520 } 521 522 @Test 523 @Config(minSdk = Q) setSystemDefaultDialerPackage()524 public void setSystemDefaultDialerPackage() { 525 assertThat(telecomService.getSystemDialerPackage()).isNull(); 526 shadowOf(telecomService).setSystemDialerPackage("some.package"); 527 assertThat(telecomService.getSystemDialerPackage()).isEqualTo("some.package"); 528 } 529 530 @Test setTtySupported()531 public void setTtySupported() { 532 assertThat(telecomService.isTtySupported()).isFalse(); 533 shadowOf(telecomService).setTtySupported(true); 534 assertThat(telecomService.isTtySupported()).isTrue(); 535 } 536 537 @Test setTtySupported_noPermission_throwsSecurityException()538 public void setTtySupported_noPermission_throwsSecurityException() { 539 shadowOf(telecomService).setReadPhoneStatePermission(false); 540 541 assertThrows(SecurityException.class, () -> telecomService.isTtySupported()); 542 } 543 544 @Test canSetAndGetIsInCall()545 public void canSetAndGetIsInCall() { 546 shadowOf(telecomService).setIsInCall(true); 547 assertThat(telecomService.isInCall()).isTrue(); 548 } 549 550 @Test isInCall_setIsInCallNotCalled_shouldReturnFalse()551 public void isInCall_setIsInCallNotCalled_shouldReturnFalse() { 552 assertThat(telecomService.isInCall()).isFalse(); 553 } 554 555 @Test 556 @Config(minSdk = Q) canSetAndGetIsInEmergencyCall_setsBothInCallAndInEmergencyCall()557 public void canSetAndGetIsInEmergencyCall_setsBothInCallAndInEmergencyCall() { 558 shadowOf(telecomService).setIsInEmergencyCall(true); 559 assertThat(telecomService.isInEmergencyCall()).isTrue(); 560 assertThat(telecomService.isInCall()).isTrue(); 561 } 562 563 @Test 564 @Config(minSdk = Q) isInEmergencyCall_setIsInEmergencyCallNotCalled_shouldReturnFalse()565 public void isInEmergencyCall_setIsInEmergencyCallNotCalled_shouldReturnFalse() { 566 assertThat(telecomService.isInEmergencyCall()).isFalse(); 567 } 568 569 @Test getDefaultOutgoingPhoneAccount()570 public void getDefaultOutgoingPhoneAccount() { 571 // Check initial state 572 assertThat(telecomService.getDefaultOutgoingPhoneAccount("abc")).isNull(); 573 574 // After setting 575 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 576 shadowOf(telecomService).setDefaultOutgoingPhoneAccount("abc", phoneAccountHandle); 577 assertThat(telecomService.getDefaultOutgoingPhoneAccount("abc")).isEqualTo(phoneAccountHandle); 578 579 // After removing 580 shadowOf(telecomService).removeDefaultOutgoingPhoneAccount("abc"); 581 assertThat(telecomService.getDefaultOutgoingPhoneAccount("abc")).isNull(); 582 } 583 584 @Config(minSdk = R) 585 @Test createLaunchEmergencyDialerIntent_shouldReturnValidIntent()586 public void createLaunchEmergencyDialerIntent_shouldReturnValidIntent() { 587 Intent intent = telecomService.createLaunchEmergencyDialerIntent(/* number= */ null); 588 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_DIAL_EMERGENCY); 589 } 590 591 @Config(minSdk = R) 592 @Test createLaunchEmergencyDialerIntent_whenPackageAvailable_shouldContainPackage()593 public void createLaunchEmergencyDialerIntent_whenPackageAvailable_shouldContainPackage() 594 throws NameNotFoundException { 595 ComponentName componentName = new ComponentName("com.android.phone", "EmergencyDialer"); 596 shadowOf(context.getPackageManager()).addActivityIfNotPresent(componentName); 597 598 IntentFilter intentFilter = new IntentFilter(); 599 intentFilter.addAction(Intent.ACTION_DIAL_EMERGENCY); 600 601 shadowOf(context.getPackageManager()).addIntentFilterForActivity(componentName, intentFilter); 602 603 Intent intent = telecomService.createLaunchEmergencyDialerIntent(/* number= */ null); 604 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_DIAL_EMERGENCY); 605 assertThat(intent.getPackage()).isEqualTo("com.android.phone"); 606 } 607 608 @Config(minSdk = R) 609 @Test 610 public void createLaunchEmergencyDialerIntent_whenSetPhoneNumber_shouldReturnValidIntentWithPhoneNumber()611 createLaunchEmergencyDialerIntent_whenSetPhoneNumber_shouldReturnValidIntentWithPhoneNumber() { 612 Intent intent = telecomService.createLaunchEmergencyDialerIntent("1234"); 613 assertThat(intent.getAction()).isEqualTo(Intent.ACTION_DIAL_EMERGENCY); 614 Uri uri = intent.getData(); 615 assertThat(uri.toString()).isEqualTo("tel:1234"); 616 } 617 618 @Test 619 @Config(minSdk = Q) getUserSelectedOutgoingPhoneAccount()620 public void getUserSelectedOutgoingPhoneAccount() { 621 // Check initial state 622 assertThat(telecomService.getUserSelectedOutgoingPhoneAccount()).isNull(); 623 624 // Set a phone account and verify 625 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 626 shadowOf(telecomService).setUserSelectedOutgoingPhoneAccount(phoneAccountHandle); 627 assertThat(telecomService.getUserSelectedOutgoingPhoneAccount()).isEqualTo(phoneAccountHandle); 628 } 629 630 @Test 631 @Config(minSdk = N) testSetManageBlockNumbersIntent()632 public void testSetManageBlockNumbersIntent() { 633 // Check initial state 634 Intent targetIntent = telecomService.createManageBlockedNumbersIntent(); 635 assertThat(targetIntent).isNull(); 636 637 // Set intent and verify 638 Intent initialIntent = new Intent(); 639 shadowOf(telecomService).setManageBlockNumbersIntent(initialIntent); 640 641 targetIntent = telecomService.createManageBlockedNumbersIntent(); 642 assertThat(initialIntent).isEqualTo(targetIntent); 643 } 644 645 @Test 646 @Config(minSdk = M) isVoicemailNumber()647 public void isVoicemailNumber() { 648 // Check initial state 649 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 650 assertThat(telecomService.isVoiceMailNumber(phoneAccountHandle, "123")).isFalse(); 651 652 // After setting 653 shadowOf(telecomService).setVoicemailNumber(phoneAccountHandle, "123"); 654 assertThat(telecomService.isVoiceMailNumber(phoneAccountHandle, "123")).isTrue(); 655 656 // After reset 657 shadowOf(telecomService).setVoicemailNumber(phoneAccountHandle, null); 658 assertThat(telecomService.isVoiceMailNumber(phoneAccountHandle, "123")).isFalse(); 659 } 660 661 @Test 662 @Config(minSdk = M) getVoicemailNumber()663 public void getVoicemailNumber() { 664 // Check initial state 665 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 666 assertThat(telecomService.getVoiceMailNumber(phoneAccountHandle)).isNull(); 667 668 // After setting 669 shadowOf(telecomService).setVoicemailNumber(phoneAccountHandle, "123"); 670 assertThat(telecomService.getVoiceMailNumber(phoneAccountHandle)).isEqualTo("123"); 671 672 // After reset 673 shadowOf(telecomService).setVoicemailNumber(phoneAccountHandle, null); 674 assertThat(telecomService.getVoiceMailNumber(phoneAccountHandle)).isNull(); 675 } 676 677 @Test 678 @Config(minSdk = LOLLIPOP_MR1) getLine1Number()679 public void getLine1Number() { 680 // Check initial state 681 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 682 assertThat(telecomService.getLine1Number(phoneAccountHandle)).isNull(); 683 684 // After setting 685 shadowOf(telecomService).setLine1Number(phoneAccountHandle, "123"); 686 assertThat(telecomService.getLine1Number(phoneAccountHandle)).isEqualTo("123"); 687 688 // After reset 689 shadowOf(telecomService).setLine1Number(phoneAccountHandle, null); 690 assertThat(telecomService.getLine1Number(phoneAccountHandle)).isNull(); 691 } 692 693 @Test 694 @Config(minSdk = LOLLIPOP_MR1) getLine1Number_noPermission_throwsSecurityException()695 public void getLine1Number_noPermission_throwsSecurityException() { 696 shadowOf(telecomService).setReadPhoneStatePermission(false); 697 698 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 699 assertThrows(SecurityException.class, () -> telecomService.getLine1Number(phoneAccountHandle)); 700 } 701 702 @Test handleMmi_defaultValueFalse()703 public void handleMmi_defaultValueFalse() { 704 assertThat(telecomService.handleMmi("123")).isFalse(); 705 } 706 707 @Test handleMmi()708 public void handleMmi() { 709 shadowOf(telecomService).setHandleMmiValue(true); 710 711 assertThat(telecomService.handleMmi("123")).isTrue(); 712 } 713 714 @Test 715 @Config(minSdk = M) handleMmiWithHandle_defaultValueFalse()716 public void handleMmiWithHandle_defaultValueFalse() { 717 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 718 assertThat(telecomService.handleMmi("123", phoneAccountHandle)).isFalse(); 719 } 720 721 @Test 722 @Config(minSdk = M) handleMmiWithHandle()723 public void handleMmiWithHandle() { 724 shadowOf(telecomService).setHandleMmiValue(true); 725 PhoneAccountHandle phoneAccountHandle = createHandle("id1"); 726 727 assertThat(telecomService.handleMmi("123", phoneAccountHandle)).isTrue(); 728 } 729 730 @Test 731 @Config(minSdk = O) isOutgoingCallPermitted_false()732 public void isOutgoingCallPermitted_false() { 733 shadowOf(telecomService).setIsOutgoingCallPermitted(false); 734 735 assertThat(telecomService.isOutgoingCallPermitted(/* phoneAccountHandle= */ null)).isFalse(); 736 } 737 738 @Test 739 @Config(minSdk = O) isOutgoingCallPermitted_true()740 public void isOutgoingCallPermitted_true() { 741 shadowOf(telecomService).setIsOutgoingCallPermitted(true); 742 743 assertThat(telecomService.isOutgoingCallPermitted(/* phoneAccountHandle= */ null)).isTrue(); 744 } 745 createHandle(String id)746 private static PhoneAccountHandle createHandle(String id) { 747 return new PhoneAccountHandle( 748 new ComponentName(ApplicationProvider.getApplicationContext(), TestConnectionService.class), 749 id); 750 } 751 createHandle(String packageName, String className, String id)752 private static PhoneAccountHandle createHandle(String packageName, String className, String id) { 753 return new PhoneAccountHandle(new ComponentName(packageName, className), id); 754 } 755 756 @Test 757 @Config(minSdk = Build.VERSION_CODES.O) telecomManager_activityContextEnabled_differentInstancesRetrieveDefaultDialer()758 public void telecomManager_activityContextEnabled_differentInstancesRetrieveDefaultDialer() { 759 String originalProperty = System.getProperty("robolectric.createActivityContexts", ""); 760 System.setProperty("robolectric.createActivityContexts", "true"); 761 try (ActivityController<Activity> controller = 762 Robolectric.buildActivity(Activity.class).setup()) { 763 TelecomManager applicationTelecomManager = 764 (TelecomManager) 765 ApplicationProvider.getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 766 767 Activity activity = controller.get(); 768 TelecomManager activityTelecomManager = 769 (TelecomManager) activity.getSystemService(Context.TELECOM_SERVICE); 770 771 String applicationDefaultDialer = applicationTelecomManager.getDefaultDialerPackage(); 772 String activityDefaultDialer = activityTelecomManager.getDefaultDialerPackage(); 773 774 assertThat(activityDefaultDialer).isEqualTo(applicationDefaultDialer); 775 } finally { 776 System.setProperty("robolectric.createActivityContexts", originalProperty); 777 } 778 } 779 } 780