• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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