1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.telecom.tests; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertTrue; 23 import static org.mockito.Matchers.any; 24 import static org.mockito.Matchers.anyInt; 25 import static org.mockito.Matchers.anyString; 26 import static org.mockito.Matchers.eq; 27 import static org.mockito.Matchers.isNull; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.timeout; 30 import static org.mockito.Mockito.times; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.verifyZeroInteractions; 33 import static org.mockito.Mockito.when; 34 35 import android.content.Context; 36 import android.content.IContentProvider; 37 import android.media.AudioManager; 38 import android.net.Uri; 39 import android.os.Bundle; 40 import android.os.Handler; 41 import android.os.Looper; 42 import android.os.Process; 43 import android.provider.BlockedNumberContract; 44 import android.telecom.Call; 45 import android.telecom.CallAudioState; 46 import android.telecom.Connection; 47 import android.telecom.ConnectionRequest; 48 import android.telecom.DisconnectCause; 49 import android.telecom.Log; 50 import android.telecom.ParcelableCall; 51 import android.telecom.PhoneAccount; 52 import android.telecom.PhoneAccountHandle; 53 import android.telecom.TelecomManager; 54 import android.telecom.VideoProfile; 55 import android.support.test.filters.FlakyTest; 56 import android.test.suitebuilder.annotation.LargeTest; 57 import android.test.suitebuilder.annotation.MediumTest; 58 59 import com.android.internal.telecom.IInCallAdapter; 60 import com.android.internal.telephony.CallerInfo; 61 62 import com.google.common.base.Predicate; 63 64 import org.junit.After; 65 import org.junit.Before; 66 import org.junit.Test; 67 import org.junit.runner.RunWith; 68 import org.junit.runners.JUnit4; 69 import org.mockito.invocation.InvocationOnMock; 70 import org.mockito.stubbing.Answer; 71 72 import java.util.List; 73 import java.util.concurrent.BrokenBarrierException; 74 import java.util.concurrent.CountDownLatch; 75 import java.util.concurrent.CyclicBarrier; 76 import java.util.concurrent.TimeUnit; 77 78 import org.mockito.ArgumentCaptor; 79 80 /** 81 * Performs various basic call tests in Telecom. 82 */ 83 @RunWith(JUnit4.class) 84 public class BasicCallTests extends TelecomSystemTest { 85 private static final String TEST_BUNDLE_KEY = "android.telecom.extra.TEST"; 86 private static final String TEST_EVENT = "android.telecom.event.TEST"; 87 88 @Override 89 @Before 90 public void setUp() throws Exception { 91 super.setUp(); 92 } 93 94 @Override 95 @After 96 public void tearDown() throws Exception { 97 super.tearDown(); 98 } 99 100 @LargeTest 101 @Test 102 public void testSingleOutgoingCallLocalDisconnect() throws Exception { 103 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 104 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 105 106 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 107 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 108 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 109 110 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 111 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 112 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 113 assertEquals(Call.STATE_DISCONNECTED, 114 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 115 assertEquals(Call.STATE_DISCONNECTED, 116 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 117 assertEquals(TEST_CONNECT_TIME, 118 mInCallServiceFixtureX.getCall(ids.mCallId).getConnectTimeMillis()); 119 assertEquals(TEST_CONNECT_TIME, 120 mInCallServiceFixtureY.getCall(ids.mCallId).getConnectTimeMillis()); 121 assertEquals(TEST_CREATE_TIME, 122 mInCallServiceFixtureX.getCall(ids.mCallId).getCreationTimeMillis()); 123 assertEquals(TEST_CREATE_TIME, 124 mInCallServiceFixtureY.getCall(ids.mCallId).getCreationTimeMillis()); 125 126 verifyNoBlockChecks(); 127 } 128 129 @LargeTest 130 @Test 131 public void testSingleOutgoingCallRemoteDisconnect() throws Exception { 132 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 133 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 134 135 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 136 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 137 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 138 assertEquals(Call.STATE_DISCONNECTED, 139 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 140 assertEquals(Call.STATE_DISCONNECTED, 141 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 142 verifyNoBlockChecks(); 143 } 144 145 /** 146 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 147 * audio-only call. 148 * 149 * @throws Exception 150 */ 151 @LargeTest 152 @Test 153 public void testTelecomManagerAcceptRingingCall() throws Exception { 154 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 155 mConnectionServiceFixtureA); 156 157 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 158 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 159 160 // Use TelecomManager API to answer the ringing call. 161 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 162 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 163 telecomManager.acceptRingingCall(); 164 165 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 166 .answer(eq(ids.mConnectionId), any()); 167 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 168 169 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 170 } 171 172 /** 173 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 174 * video call, which should be answered as video. 175 * 176 * @throws Exception 177 */ 178 @LargeTest 179 @Test 180 public void testTelecomManagerAcceptRingingVideoCall() throws Exception { 181 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 182 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 183 184 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 185 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 186 187 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 188 // answer using whatever video state the ringing call requests. 189 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 190 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 191 telecomManager.acceptRingingCall(); 192 193 // Answer video API should be called 194 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 195 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 196 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 197 198 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 199 } 200 201 /** 202 * Tests the {@link TelecomManager#acceptRingingCall(int)} API. Tests answering a video call 203 * as an audio call. 204 * 205 * @throws Exception 206 */ 207 @LargeTest 208 @Test 209 public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception { 210 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 211 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 212 213 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 214 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 215 216 // Use TelecomManager API to answer the ringing call. 217 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 218 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 219 telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY); 220 221 // The generic answer method on the ConnectionService is used to answer audio-only calls. 222 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 223 .answer(eq(ids.mConnectionId), any()); 224 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 225 226 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 227 } 228 229 /** 230 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 231 * video call, where an attempt is made to answer with an invalid video state. 232 * 233 * @throws Exception 234 */ 235 @LargeTest 236 @Test 237 public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception { 238 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 239 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 240 241 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 242 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 243 244 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 245 // answer using whatever video state the ringing call requests. 246 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 247 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 248 telecomManager.acceptRingingCall(999 /* invalid videostate */); 249 250 // Answer video API should be called 251 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 252 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 253 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 254 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 255 } 256 257 @LargeTest 258 @Test 259 public void testSingleIncomingCallLocalDisconnect() throws Exception { 260 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 261 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 262 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 263 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 264 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 265 266 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 267 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 268 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 269 assertEquals(Call.STATE_DISCONNECTED, 270 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 271 assertEquals(Call.STATE_DISCONNECTED, 272 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 273 } 274 275 @LargeTest 276 @Test 277 public void testSingleIncomingCallRemoteDisconnect() throws Exception { 278 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 279 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 280 281 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 282 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 283 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 284 assertEquals(Call.STATE_DISCONNECTED, 285 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 286 assertEquals(Call.STATE_DISCONNECTED, 287 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 288 } 289 290 @LargeTest 291 @Test 292 public void testIncomingEmergencyCallback() throws Exception { 293 // Make an outgoing emergency call 294 String phoneNumber = "650-555-1212"; 295 IdPair ids = startAndMakeDialingEmergencyCall(phoneNumber, 296 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 297 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 298 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 299 300 // Incoming call should be marked as a potential emergency callback 301 Bundle extras = new Bundle(); 302 extras.putParcelable( 303 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 304 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 305 mTelecomSystem.getTelecomServiceImpl().getBinder() 306 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 307 308 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 309 ArgumentCaptor<ConnectionRequest> connectionRequestCaptor 310 = ArgumentCaptor.forClass(ConnectionRequest.class); 311 verify(mConnectionServiceFixtureA.getTestDouble()) 312 .createConnection(any(PhoneAccountHandle.class), anyString(), 313 connectionRequestCaptor.capture(), eq(true), eq(false), any()); 314 315 assertTrue(connectionRequestCaptor.getValue().getExtras().containsKey( 316 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS)); 317 assertTrue(connectionRequestCaptor.getValue().getExtras().getLong( 318 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS, 0) > 0); 319 assertTrue(connectionRequestCaptor.getValue().getExtras().containsKey( 320 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS)); 321 } 322 323 @LargeTest 324 @Test 325 public void testOutgoingCallAndSelectPhoneAccount() throws Exception { 326 // Remove default PhoneAccount so that the Call moves into the correct 327 // SELECT_PHONE_ACCOUNT state. 328 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount( 329 null, Process.myUserHandle()); 330 int startingNumConnections = mConnectionServiceFixtureA.mConnectionById.size(); 331 int startingNumCalls = mInCallServiceFixtureX.mCallById.size(); 332 String callId = startOutgoingPhoneCallWithNoPhoneAccount("650-555-1212", 333 mConnectionServiceFixtureA); 334 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 335 mInCallServiceFixtureX.getCall(callId).getState()); 336 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 337 mInCallServiceFixtureY.getCall(callId).getState()); 338 mInCallServiceFixtureX.mInCallAdapter.phoneAccountSelected(callId, 339 mPhoneAccountA0.getAccountHandle(), false); 340 341 IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(), 342 startingNumConnections, startingNumCalls, mConnectionServiceFixtureA); 343 344 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 345 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 346 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 347 assertEquals(Call.STATE_DISCONNECTED, 348 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 349 assertEquals(Call.STATE_DISCONNECTED, 350 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 351 } 352 353 @LargeTest 354 @Test 355 public void testIncomingCallFromContactWithSendToVoicemailIsRejected() throws Exception { 356 Bundle extras = new Bundle(); 357 extras.putParcelable( 358 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 359 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 360 mTelecomSystem.getTelecomServiceImpl().getBinder() 361 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 362 363 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 364 verify(mConnectionServiceFixtureA.getTestDouble()) 365 .createConnection(any(PhoneAccountHandle.class), anyString(), 366 any(ConnectionRequest.class), eq(true), eq(false), any()); 367 368 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 369 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 370 for (CallerInfoAsyncQueryFactoryFixture.Request request : 371 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 372 CallerInfo sendToVoicemailCallerInfo = new CallerInfo(); 373 sendToVoicemailCallerInfo.shouldSendToVoicemail = true; 374 request.replyWithCallerInfo(sendToVoicemailCallerInfo); 375 } 376 377 assertTrueWithTimeout(new Predicate<Void>() { 378 @Override 379 public boolean apply(Void aVoid) { 380 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 381 } 382 }); 383 assertTrueWithTimeout(new Predicate<Void>() { 384 @Override 385 public boolean apply(Void aVoid) { 386 return mMissedCallNotifier.missedCallsNotified.size() == 1; 387 } 388 }); 389 390 verify(mInCallServiceFixtureX.getTestDouble(), never()) 391 .setInCallAdapter(any(IInCallAdapter.class)); 392 verify(mInCallServiceFixtureY.getTestDouble(), never()) 393 .setInCallAdapter(any(IInCallAdapter.class)); 394 } 395 396 @LargeTest 397 @Test 398 public void testIncomingCallCallerInfoLookupTimesOutIsAllowed() throws Exception { 399 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME); 400 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME); 401 Bundle extras = new Bundle(); 402 extras.putParcelable( 403 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 404 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 405 mTelecomSystem.getTelecomServiceImpl().getBinder() 406 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 407 408 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 409 verify(mConnectionServiceFixtureA.getTestDouble()) 410 .createConnection(any(PhoneAccountHandle.class), anyString(), 411 any(ConnectionRequest.class), eq(true), eq(false), any()); 412 413 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 414 // Never reply to the caller info lookup. 415 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 416 417 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 418 .setInCallAdapter(any(IInCallAdapter.class)); 419 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 420 .setInCallAdapter(any(IInCallAdapter.class)); 421 422 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 423 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 424 425 assertTrueWithTimeout(new Predicate<Void>() { 426 @Override 427 public boolean apply(Void v) { 428 return mInCallServiceFixtureX.mInCallAdapter != null; 429 } 430 }); 431 432 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 433 .addCall(any(ParcelableCall.class)); 434 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 435 .addCall(any(ParcelableCall.class)); 436 437 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME); 438 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME); 439 disconnectCall(mInCallServiceFixtureX.mLatestCallId, 440 mConnectionServiceFixtureA.mLatestConnectionId); 441 } 442 443 @LargeTest 444 @Test 445 @FlakyTest 446 public void testIncomingCallFromBlockedNumberIsRejected() throws Exception { 447 String phoneNumber = "650-555-1212"; 448 blockNumber(phoneNumber); 449 450 Bundle extras = new Bundle(); 451 extras.putParcelable( 452 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 453 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 454 mTelecomSystem.getTelecomServiceImpl().getBinder() 455 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 456 457 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 458 verify(mConnectionServiceFixtureA.getTestDouble()) 459 .createConnection(any(PhoneAccountHandle.class), anyString(), 460 any(ConnectionRequest.class), eq(true), eq(false), any()); 461 462 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 463 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 464 for (CallerInfoAsyncQueryFactoryFixture.Request request : 465 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 466 request.reply(); 467 } 468 469 assertTrueWithTimeout(new Predicate<Void>() { 470 @Override 471 public boolean apply(Void aVoid) { 472 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 473 } 474 }); 475 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 476 477 verify(mInCallServiceFixtureX.getTestDouble(), never()) 478 .setInCallAdapter(any(IInCallAdapter.class)); 479 verify(mInCallServiceFixtureY.getTestDouble(), never()) 480 .setInCallAdapter(any(IInCallAdapter.class)); 481 } 482 483 @LargeTest 484 @Test 485 public void testIncomingCallBlockCheckTimesoutIsAllowed() throws Exception { 486 final CountDownLatch latch = new CountDownLatch(1); 487 String phoneNumber = "650-555-1212"; 488 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 489 @Override 490 public Bundle answer(InvocationOnMock invocation) throws Throwable { 491 latch.await(TEST_TIMEOUT * 2, TimeUnit.MILLISECONDS); 492 Bundle bundle = new Bundle(); 493 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 494 return bundle; 495 } 496 }); 497 498 IdPair ids = startAndMakeActiveIncomingCall( 499 phoneNumber, mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 500 latch.countDown(); 501 502 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 503 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 504 disconnectCall(ids.mCallId, ids.mConnectionId); 505 } 506 507 public void do_testDeadlockOnOutgoingCall() throws Exception { 508 final IdPair ids = startOutgoingPhoneCall("650-555-1212", 509 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA, 510 Process.myUserHandle()); 511 rapidFire( 512 new Runnable() { 513 @Override 514 public void run() { 515 while (mCallerInfoAsyncQueryFactoryFixture.mRequests.size() > 0) { 516 mCallerInfoAsyncQueryFactoryFixture.mRequests.remove(0).reply(); 517 } 518 } 519 }, 520 new Runnable() { 521 @Override 522 public void run() { 523 try { 524 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 525 } catch (Exception e) { 526 Log.e(this, e, ""); 527 } 528 } 529 }); 530 } 531 532 @LargeTest 533 @Test 534 public void testIncomingThenOutgoingCalls() throws Exception { 535 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 536 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 537 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 538 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 539 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 540 541 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 542 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 543 } 544 545 @LargeTest 546 @Test 547 public void testOutgoingThenIncomingCalls() throws Exception { 548 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 549 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 550 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 551 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 552 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 553 verify(mConnectionServiceFixtureA.getTestDouble()) 554 .hold(eq(outgoing.mConnectionId), any()); 555 mConnectionServiceFixtureA.mConnectionById.get(outgoing.mConnectionId).state = 556 Connection.STATE_HOLDING; 557 mConnectionServiceFixtureA.sendSetOnHold(outgoing.mConnectionId); 558 assertEquals(Call.STATE_HOLDING, 559 mInCallServiceFixtureX.getCall(outgoing.mCallId).getState()); 560 assertEquals(Call.STATE_HOLDING, 561 mInCallServiceFixtureY.getCall(outgoing.mCallId).getState()); 562 563 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 564 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 565 } 566 567 @LargeTest 568 @Test 569 public void testAudioManagerOperations() throws Exception { 570 AudioManager audioManager = (AudioManager) mComponentContextFixture.getTestDouble() 571 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE); 572 573 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 574 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 575 576 verify(audioManager, timeout(TEST_TIMEOUT)).requestAudioFocusForCall(anyInt(), anyInt()); 577 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 578 .setMode(AudioManager.MODE_IN_CALL); 579 580 mInCallServiceFixtureX.mInCallAdapter.mute(true); 581 verify(mAudioService, timeout(TEST_TIMEOUT)) 582 .setMicrophoneMute(eq(true), any(String.class), any(Integer.class)); 583 mInCallServiceFixtureX.mInCallAdapter.mute(false); 584 verify(mAudioService, timeout(TEST_TIMEOUT)) 585 .setMicrophoneMute(eq(false), any(String.class), any(Integer.class)); 586 587 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER, null); 588 verify(audioManager, timeout(TEST_TIMEOUT)) 589 .setSpeakerphoneOn(true); 590 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE, null); 591 verify(audioManager, timeout(TEST_TIMEOUT)) 592 .setSpeakerphoneOn(false); 593 594 mConnectionServiceFixtureA. 595 sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); 596 597 verify(audioManager, timeout(TEST_TIMEOUT)) 598 .abandonAudioFocusForCall(); 599 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 600 .setMode(AudioManager.MODE_NORMAL); 601 } 602 603 private void rapidFire(Runnable... tasks) { 604 final CyclicBarrier barrier = new CyclicBarrier(tasks.length); 605 final CountDownLatch latch = new CountDownLatch(tasks.length); 606 for (int i = 0; i < tasks.length; i++) { 607 final Runnable task = tasks[i]; 608 new Thread(new Runnable() { 609 @Override 610 public void run() { 611 try { 612 barrier.await(); 613 task.run(); 614 } catch (InterruptedException | BrokenBarrierException e){ 615 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 616 } finally { 617 latch.countDown(); 618 } 619 } 620 }).start(); 621 } 622 try { 623 latch.await(); 624 } catch (InterruptedException e) { 625 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 626 } 627 } 628 629 @MediumTest 630 @Test 631 public void testBasicConferenceCall() throws Exception { 632 makeConferenceCall(); 633 } 634 635 @MediumTest 636 @Test 637 public void testAddCallToConference1() throws Exception { 638 ParcelableCall conferenceCall = makeConferenceCall(); 639 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 640 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 641 // testAddCallToConference{1,2} differ in the order of arguments to InCallAdapter#conference 642 mInCallServiceFixtureX.getInCallAdapter().conference( 643 conferenceCall.getId(), callId3.mCallId); 644 Thread.sleep(200); 645 646 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 647 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 648 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 649 assertEquals(3, updatedConference.getChildCallIds().size()); 650 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 651 } 652 653 @MediumTest 654 @Test 655 public void testAddCallToConference2() throws Exception { 656 ParcelableCall conferenceCall = makeConferenceCall(); 657 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 658 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 659 mInCallServiceFixtureX.getInCallAdapter() 660 .conference(callId3.mCallId, conferenceCall.getId()); 661 Thread.sleep(200); 662 663 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 664 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 665 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 666 assertEquals(3, updatedConference.getChildCallIds().size()); 667 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 668 } 669 670 /** 671 * Tests the {@link Call#pullExternalCall()} API. Verifies that if a call is not an external 672 * call, no pull call request is made to the connection service. 673 * 674 * @throws Exception 675 */ 676 @MediumTest 677 @Test 678 public void testPullNonExternalCall() throws Exception { 679 // TODO: Revisit this unit test once telecom support for filtering external calls from 680 // InCall services is implemented. 681 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 682 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 683 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 684 685 // Attempt to pull the call and verify the API call makes it through 686 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 687 Thread.sleep(TEST_TIMEOUT); 688 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 689 .pullExternalCall(eq(ids.mCallId), any()); 690 } 691 692 /** 693 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 694 * 695 * @throws Exception 696 */ 697 @MediumTest 698 @Test 699 public void testSendConnectionEventNull() throws Exception { 700 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 701 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 702 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 703 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, null); 704 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 705 .onConnectionEvent(ids.mCallId, TEST_EVENT, null); 706 } 707 708 /** 709 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 710 * 711 * @throws Exception 712 */ 713 @MediumTest 714 @Test 715 public void testSendConnectionEventNotNull() throws Exception { 716 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 717 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 718 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 719 720 Bundle testBundle = new Bundle(); 721 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 722 723 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 724 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, testBundle); 725 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 726 .onConnectionEvent(eq(ids.mCallId), eq(TEST_EVENT), bundleArgumentCaptor.capture()); 727 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 728 } 729 730 /** 731 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 732 * 733 * @throws Exception 734 */ 735 @MediumTest 736 @Test 737 public void testSendCallEventNull() throws Exception { 738 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 739 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 740 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 741 742 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 26, null); 743 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 744 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), isNull(Bundle.class), any()); 745 } 746 747 /** 748 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 749 * 750 * @throws Exception 751 */ 752 @MediumTest 753 @Test 754 public void testSendCallEventNonNull() throws Exception { 755 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 756 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 757 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 758 759 Bundle testBundle = new Bundle(); 760 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 761 762 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 763 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 26, 764 testBundle); 765 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 766 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), 767 bundleArgumentCaptor.capture(), any()); 768 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 769 } 770 771 private void blockNumber(String phoneNumber) throws Exception { 772 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 773 @Override 774 public Bundle answer(InvocationOnMock invocation) throws Throwable { 775 Bundle bundle = new Bundle(); 776 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 777 return bundle; 778 } 779 }); 780 } 781 782 private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception { 783 when(getBlockedNumberProvider().call( 784 anyString(), 785 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER), 786 eq(phoneNumber), 787 isNull(Bundle.class))).thenAnswer(answer); 788 } 789 790 private void verifyNoBlockChecks() { 791 verifyZeroInteractions(getBlockedNumberProvider()); 792 } 793 794 private IContentProvider getBlockedNumberProvider() { 795 return mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY); 796 } 797 798 private void disconnectCall(String callId, String connectionId) throws Exception { 799 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 800 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 801 mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL); 802 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState()); 803 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState()); 804 assertEquals(TEST_CREATE_TIME, 805 mInCallServiceFixtureX.getCall(callId).getCreationTimeMillis()); 806 assertEquals(TEST_CREATE_TIME, 807 mInCallServiceFixtureY.getCall(callId).getCreationTimeMillis()); 808 } 809 810 /** 811 * Tests to make sure that the Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is set on a 812 * Call that is based on a Connection with the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY 813 * property set. 814 */ 815 @MediumTest 816 @Test 817 public void testCdmaEnhancedPrivacyVoiceCall() throws Exception { 818 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 819 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 820 821 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 822 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 823 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 824 825 assertTrue(Call.Details.hasProperty( 826 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 827 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 828 } 829 830 /** 831 * Tests to make sure that Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY is dropped 832 * when the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is removed from the Connection. 833 */ 834 @MediumTest 835 @Test 836 public void testDropCdmaEnhancedPrivacyVoiceCall() throws Exception { 837 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 838 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 839 840 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 841 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 842 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 843 mConnectionServiceFixtureA.mLatestConnection.setConnectionProperties(0); 844 845 assertFalse(Call.Details.hasProperty( 846 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 847 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 848 } 849 850 /** 851 * Tests the {@link Call#pullExternalCall()} API. Ensures that an external call which is 852 * pullable can be pulled. 853 * 854 * @throws Exception 855 */ 856 @LargeTest 857 @Test 858 public void testPullExternalCall() throws Exception { 859 // TODO: Revisit this unit test once telecom support for filtering external calls from 860 // InCall services is implemented. 861 mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities = 862 Connection.CAPABILITY_CAN_PULL_CALL; 863 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 864 Connection.PROPERTY_IS_EXTERNAL_CALL; 865 866 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 867 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 868 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 869 870 // Attempt to pull the call and verify the API call makes it through 871 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 872 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 873 .pullExternalCall(eq(ids.mConnectionId), any()); 874 } 875 876 /** 877 * Tests the {@link Call#pullExternalCall()} API. Verifies that if an external call is not 878 * marked as pullable that the connection service does not get an API call to pull the external 879 * call. 880 * 881 * @throws Exception 882 */ 883 @LargeTest 884 @Test 885 public void testPullNonPullableExternalCall() throws Exception { 886 // TODO: Revisit this unit test once telecom support for filtering external calls from 887 // InCall services is implemented. 888 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 889 Connection.PROPERTY_IS_EXTERNAL_CALL; 890 891 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 892 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 893 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 894 895 // Attempt to pull the call and verify the API call makes it through 896 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 897 Thread.sleep(TEST_TIMEOUT); 898 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 899 .pullExternalCall(eq(ids.mConnectionId), any()); 900 } 901 902 /** 903 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 904 * then subsequently selects a PhoneAccount which supports video calling. 905 * @throws Exception 906 */ 907 @LargeTest 908 @Test 909 public void testOutgoingCallSelectPhoneAccountVideo() throws Exception { 910 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 911 null, mConnectionServiceFixtureA, 912 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 913 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 914 .iterator().next(); 915 assert(call.isVideoCallingSupported()); 916 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 917 918 // Change the phone account to one which supports video calling. 919 call.setTargetPhoneAccount(mPhoneAccountA1.getAccountHandle()); 920 assert(call.isVideoCallingSupported()); 921 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 922 } 923 924 /** 925 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 926 * then subsequently selects a PhoneAccount which does not support video calling. 927 * @throws Exception 928 */ 929 @FlakyTest 930 @LargeTest 931 @Test 932 public void testOutgoingCallSelectPhoneAccountNoVideo() throws Exception { 933 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 934 null, mConnectionServiceFixtureA, 935 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 936 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 937 .iterator().next(); 938 assert(call.isVideoCallingSupported()); 939 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 940 941 // Change the phone account to one which does not support video calling. 942 call.setTargetPhoneAccount(mPhoneAccountA2.getAccountHandle()); 943 assert(!call.isVideoCallingSupported()); 944 assertEquals(VideoProfile.STATE_AUDIO_ONLY, call.getVideoState()); 945 } 946 947 /** 948 * Basic test to ensure that a self-managed ConnectionService can place a call. 949 * @throws Exception 950 */ 951 @LargeTest 952 @Test 953 public void testSelfManagedOutgoing() throws Exception { 954 PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle(); 955 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", phoneAccountHandle, 956 mConnectionServiceFixtureA); 957 958 // The InCallService should not know about the call since its self-managed. 959 assertNull(mInCallServiceFixtureX.getCall(ids.mCallId)); 960 } 961 962 /** 963 * Basic test to ensure that a self-managed ConnectionService can add an incoming call. 964 * @throws Exception 965 */ 966 @LargeTest 967 @Test 968 public void testSelfManagedIncoming() throws Exception { 969 PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle(); 970 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", phoneAccountHandle, 971 mConnectionServiceFixtureA); 972 973 // The InCallService should not know about the call since its self-managed. 974 assertNull(mInCallServiceFixtureX.getCall(ids.mCallId)); 975 } 976 977 /** 978 * Basic test to ensure that when there are no calls, we permit outgoing calls by a self managed 979 * CS. 980 * @throws Exception 981 */ 982 @LargeTest 983 @Test 984 public void testIsOutgoingCallPermitted() throws Exception { 985 assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder() 986 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle())); 987 } 988 989 /** 990 * Ensure if there is a holdable call ongoing we'll be able to place another call. 991 * @throws Exception 992 */ 993 @LargeTest 994 @Test 995 public void testIsOutgoingCallPermittedOngoingHoldable() throws Exception { 996 // Start a regular call; the self-managed CS can make a call now since ongoing call can be 997 // held 998 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 999 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 1000 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 1001 1002 assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder() 1003 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle())); 1004 } 1005 1006 /** 1007 * Ensure if there is an unholdable call we can't place another call. 1008 * @throws Exception 1009 */ 1010 @LargeTest 1011 @Test 1012 public void testIsOutgoingCallPermittedOngoingUnHoldable() throws Exception { 1013 // Start a regular call; the self-managed CS can't make a call now because the ongoing call 1014 // can't be held. 1015 mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities = 0; 1016 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 1017 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 1018 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 1019 1020 assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder() 1021 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle())); 1022 } 1023 1024 /** 1025 * Basic to verify audio route gets reset to baseline when emergency call placed while a 1026 * self-managed call is underway. 1027 * @throws Exception 1028 */ 1029 @LargeTest 1030 @Test 1031 @FlakyTest 1032 public void testDisconnectSelfManaged() throws Exception { 1033 // Add a self-managed call. 1034 PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle(); 1035 startAndMakeActiveIncomingCall("650-555-1212", phoneAccountHandle, 1036 mConnectionServiceFixtureA); 1037 Connection connection = mConnectionServiceFixtureA.mLatestConnection; 1038 1039 // Route self-managed call to speaker. 1040 connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER); 1041 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 1042 1043 // Place an emergency call. 1044 startAndMakeDialingEmergencyCall("650-555-1212", mPhoneAccountE0.getAccountHandle(), 1045 mConnectionServiceFixtureA); 1046 1047 // Should have reverted back to earpiece. 1048 assertEquals(CallAudioState.ROUTE_EARPIECE, 1049 mInCallServiceFixtureX.mCallAudioState.getRoute()); 1050 } 1051 1052 /** 1053 * Tests the {@link Call#deflect} API. Verifies that if a call is incoming, 1054 * and deflect API is called, then request is made to the connection service. 1055 * 1056 * @throws Exception 1057 */ 1058 @LargeTest 1059 @Test 1060 public void testDeflectCallWhenIncoming() throws Exception { 1061 Uri deflectAddress = Uri.parse("tel:650-555-1214"); 1062 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 1063 mConnectionServiceFixtureA); 1064 1065 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 1066 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 1067 // Attempt to deflect the call and verify the API call makes it through 1068 mInCallServiceFixtureX.mInCallAdapter.deflectCall(ids.mCallId, deflectAddress); 1069 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 1070 .deflect(eq(ids.mConnectionId), eq(deflectAddress), any()); 1071 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 1072 } 1073 1074 /** 1075 * Tests the {@link Call#deflect} API. Verifies that if a call is outgoing, 1076 * and deflect API is called, then request is not made to the connection service. 1077 * Ideally, deflect option should be displayed only if call is incoming/waiting. 1078 * 1079 * @throws Exception 1080 */ 1081 @LargeTest 1082 @Test 1083 public void testDeflectCallWhenOutgoing() throws Exception { 1084 Uri deflectAddress = Uri.parse("tel:650-555-1214"); 1085 IdPair ids = startOutgoingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 1086 mConnectionServiceFixtureA, Process.myUserHandle()); 1087 // Attempt to deflect the call and verify the API call does not make it through 1088 mInCallServiceFixtureX.mInCallAdapter.deflectCall(ids.mCallId, deflectAddress); 1089 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 1090 .deflect(eq(ids.mConnectionId), eq(deflectAddress), any()); 1091 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 1092 } 1093 1094 /** 1095 * Test to make sure to unmute automatically when making an emergency call and keep unmute 1096 * during the emergency call. 1097 * @throws Exception 1098 */ 1099 @LargeTest 1100 @Test 1101 public void testUnmuteDuringEmergencyCall() throws Exception { 1102 // Make an outgoing call and turn ON mute. 1103 IdPair outgoingCall = startAndMakeActiveOutgoingCall("650-555-1212", 1104 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 1105 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(outgoingCall.mCallId) 1106 .getState()); 1107 mInCallServiceFixtureX.mInCallAdapter.mute(true); 1108 waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() 1109 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); 1110 assertTrue(mTelecomSystem.getCallsManager().getAudioState().isMuted()); 1111 1112 // Make an emergency call. 1113 IdPair emergencyCall = startAndMakeDialingEmergencyCall("650-555-1213", 1114 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 1115 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(emergencyCall.mCallId) 1116 .getState()); 1117 waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() 1118 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); 1119 // Should be unmute automatically. 1120 assertFalse(mTelecomSystem.getCallsManager().getAudioState().isMuted()); 1121 1122 // Toggle mute during an emergency call. 1123 mTelecomSystem.getCallsManager().getCallAudioManager().toggleMute(); 1124 waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager() 1125 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT); 1126 // Should keep unmute. 1127 assertFalse(mTelecomSystem.getCallsManager().getAudioState().isMuted()); 1128 1129 ArgumentCaptor<Boolean> muteValueCaptor = ArgumentCaptor.forClass(Boolean.class); 1130 verify(mAudioService, times(2)).setMicrophoneMute(muteValueCaptor.capture(), 1131 any(String.class), any(Integer.class)); 1132 List<Boolean> muteValues = muteValueCaptor.getAllValues(); 1133 // Check mute status was changed twice with true and false. 1134 assertTrue(muteValues.get(0)); 1135 assertFalse(muteValues.get(1)); 1136 } 1137 } 1138