BasicCallTests.java revision a2b067eacbd9ee7210cb0887a6b26068990d82ff
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 17package com.android.server.telecom.tests; 18 19import static org.mockito.Matchers.any; 20import static org.mockito.Matchers.anyInt; 21import static org.mockito.Matchers.anyString; 22import static org.mockito.Matchers.eq; 23import static org.mockito.Matchers.isNull; 24import static org.mockito.Mockito.never; 25import static org.mockito.Mockito.timeout; 26import static org.mockito.Mockito.verify; 27import static org.mockito.Mockito.verifyZeroInteractions; 28import static org.mockito.Mockito.when; 29 30import android.content.Context; 31import android.content.IContentProvider; 32import android.media.AudioManager; 33import android.net.Uri; 34import android.os.Bundle; 35import android.os.Handler; 36import android.os.Looper; 37import android.os.Process; 38import android.provider.BlockedNumberContract; 39import android.telecom.Call; 40import android.telecom.CallAudioState; 41import android.telecom.Connection; 42import android.telecom.ConnectionRequest; 43import android.telecom.DisconnectCause; 44import android.telecom.Log; 45import android.telecom.ParcelableCall; 46import android.telecom.PhoneAccount; 47import android.telecom.PhoneAccountHandle; 48import android.telecom.TelecomManager; 49import android.telecom.VideoProfile; 50import android.test.suitebuilder.annotation.LargeTest; 51import android.test.suitebuilder.annotation.MediumTest; 52 53import com.android.internal.telecom.IInCallAdapter; 54import com.android.internal.telephony.CallerInfo; 55 56import com.google.common.base.Predicate; 57 58import org.mockito.invocation.InvocationOnMock; 59import org.mockito.stubbing.Answer; 60 61import java.util.concurrent.BrokenBarrierException; 62import java.util.concurrent.CountDownLatch; 63import java.util.concurrent.CyclicBarrier; 64import java.util.concurrent.TimeUnit; 65 66import org.mockito.ArgumentCaptor; 67 68/** 69 * Performs various basic call tests in Telecom. 70 */ 71public class BasicCallTests extends TelecomSystemTest { 72 private static final String TEST_BUNDLE_KEY = "android.telecom.extra.TEST"; 73 private static final String TEST_EVENT = "android.telecom.event.TEST"; 74 75 @LargeTest 76 public void testSingleOutgoingCallLocalDisconnect() throws Exception { 77 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 78 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 79 80 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 81 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 82 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 83 84 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 85 assertEquals(Call.STATE_DISCONNECTED, 86 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 87 assertEquals(Call.STATE_DISCONNECTED, 88 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 89 verifyNoBlockChecks(); 90 } 91 92 @LargeTest 93 public void testSingleOutgoingCallRemoteDisconnect() throws Exception { 94 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 95 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 96 97 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 98 assertEquals(Call.STATE_DISCONNECTED, 99 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 100 assertEquals(Call.STATE_DISCONNECTED, 101 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 102 verifyNoBlockChecks(); 103 } 104 105 /** 106 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 107 * audio-only call. 108 * 109 * @throws Exception 110 */ 111 @LargeTest 112 public void testTelecomManagerAcceptRingingCall() throws Exception { 113 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 114 mConnectionServiceFixtureA); 115 116 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 117 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 118 119 // Use TelecomManager API to answer the ringing call. 120 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 121 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 122 telecomManager.acceptRingingCall(); 123 124 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 125 .answer(eq(ids.mConnectionId), any()); 126 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 127 128 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 129 } 130 131 /** 132 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 133 * video call, which should be answered as video. 134 * 135 * @throws Exception 136 */ 137 @LargeTest 138 public void testTelecomManagerAcceptRingingVideoCall() throws Exception { 139 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 140 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 141 142 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 143 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 144 145 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 146 // answer using whatever video state the ringing call requests. 147 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 148 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 149 telecomManager.acceptRingingCall(); 150 151 // Answer video API should be called 152 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 153 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 154 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 155 156 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 157 } 158 159 /** 160 * Tests the {@link TelecomManager#acceptRingingCall(int)} API. Tests answering a video call 161 * as an audio call. 162 * 163 * @throws Exception 164 */ 165 @LargeTest 166 public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception { 167 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 168 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 169 170 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 171 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 172 173 // Use TelecomManager API to answer the ringing call. 174 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 175 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 176 telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY); 177 178 // The generic answer method on the ConnectionService is used to answer audio-only calls. 179 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 180 .answer(eq(ids.mConnectionId), any()); 181 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 182 183 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 184 } 185 186 /** 187 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 188 * video call, where an attempt is made to answer with an invalid video state. 189 * 190 * @throws Exception 191 */ 192 @LargeTest 193 public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception { 194 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 195 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 196 197 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 198 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 199 200 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 201 // answer using whatever video state the ringing call requests. 202 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 203 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 204 telecomManager.acceptRingingCall(999 /* invalid videostate */); 205 206 // Answer video API should be called 207 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 208 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 209 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 210 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 211 } 212 213 @LargeTest 214 public void testSingleIncomingCallLocalDisconnect() throws Exception { 215 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 216 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 217 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 218 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 219 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 220 221 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 222 assertEquals(Call.STATE_DISCONNECTED, 223 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 224 assertEquals(Call.STATE_DISCONNECTED, 225 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 226 } 227 228 @LargeTest 229 public void testSingleIncomingCallRemoteDisconnect() throws Exception { 230 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 231 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 232 233 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 234 assertEquals(Call.STATE_DISCONNECTED, 235 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 236 assertEquals(Call.STATE_DISCONNECTED, 237 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 238 } 239 240 @LargeTest 241 public void testIncomingEmergencyCallback() throws Exception { 242 // Make an outgoing emergency call 243 String phoneNumber = "650-555-1212"; 244 IdPair ids = startAndMakeDialingEmergencyCall(phoneNumber, 245 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 246 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 247 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 248 249 // Incoming call should be marked as a potential emergency callback 250 Bundle extras = new Bundle(); 251 extras.putParcelable( 252 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 253 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 254 mTelecomSystem.getTelecomServiceImpl().getBinder() 255 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 256 257 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 258 ArgumentCaptor<ConnectionRequest> connectionRequestCaptor 259 = ArgumentCaptor.forClass(ConnectionRequest.class); 260 verify(mConnectionServiceFixtureA.getTestDouble()) 261 .createConnection(any(PhoneAccountHandle.class), anyString(), 262 connectionRequestCaptor.capture(), eq(true), eq(false), any()); 263 264 assert(connectionRequestCaptor.getValue().getExtras().containsKey( 265 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS)); 266 assertTrue(connectionRequestCaptor.getValue().getExtras().getLong( 267 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS, 0) > 0); 268 assert(connectionRequestCaptor.getValue().getExtras().containsKey( 269 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS)); 270 } 271 272 @LargeTest 273 public void testOutgoingCallAndSelectPhoneAccount() throws Exception { 274 // Remove default PhoneAccount so that the Call moves into the correct 275 // SELECT_PHONE_ACCOUNT state. 276 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount( 277 null, Process.myUserHandle()); 278 int startingNumConnections = mConnectionServiceFixtureA.mConnectionById.size(); 279 int startingNumCalls = mInCallServiceFixtureX.mCallById.size(); 280 String callId = startOutgoingPhoneCallWithNoPhoneAccount("650-555-1212", 281 mConnectionServiceFixtureA); 282 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 283 mInCallServiceFixtureX.getCall(callId).getState()); 284 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 285 mInCallServiceFixtureY.getCall(callId).getState()); 286 mInCallServiceFixtureX.mInCallAdapter.phoneAccountSelected(callId, 287 mPhoneAccountA0.getAccountHandle(), false); 288 289 IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(), 290 startingNumConnections, startingNumCalls, mConnectionServiceFixtureA); 291 292 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 293 assertEquals(Call.STATE_DISCONNECTED, 294 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 295 assertEquals(Call.STATE_DISCONNECTED, 296 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 297 } 298 299 @LargeTest 300 public void testIncomingCallFromContactWithSendToVoicemailIsRejected() throws Exception { 301 Bundle extras = new Bundle(); 302 extras.putParcelable( 303 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 304 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 305 mTelecomSystem.getTelecomServiceImpl().getBinder() 306 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 307 308 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 309 verify(mConnectionServiceFixtureA.getTestDouble()) 310 .createConnection(any(PhoneAccountHandle.class), anyString(), 311 any(ConnectionRequest.class), eq(true), eq(false), any()); 312 313 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 314 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 315 for (CallerInfoAsyncQueryFactoryFixture.Request request : 316 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 317 CallerInfo sendToVoicemailCallerInfo = new CallerInfo(); 318 sendToVoicemailCallerInfo.shouldSendToVoicemail = true; 319 request.replyWithCallerInfo(sendToVoicemailCallerInfo); 320 } 321 322 assertTrueWithTimeout(new Predicate<Void>() { 323 @Override 324 public boolean apply(Void aVoid) { 325 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 326 } 327 }); 328 assertTrueWithTimeout(new Predicate<Void>() { 329 @Override 330 public boolean apply(Void aVoid) { 331 return mMissedCallNotifier.missedCallsNotified.size() == 1; 332 } 333 }); 334 335 verify(mInCallServiceFixtureX.getTestDouble(), never()) 336 .setInCallAdapter(any(IInCallAdapter.class)); 337 verify(mInCallServiceFixtureY.getTestDouble(), never()) 338 .setInCallAdapter(any(IInCallAdapter.class)); 339 } 340 341 @LargeTest 342 public void testIncomingCallCallerInfoLookupTimesOutIsAllowed() throws Exception { 343 Bundle extras = new Bundle(); 344 extras.putParcelable( 345 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 346 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 347 mTelecomSystem.getTelecomServiceImpl().getBinder() 348 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 349 350 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 351 verify(mConnectionServiceFixtureA.getTestDouble()) 352 .createConnection(any(PhoneAccountHandle.class), anyString(), 353 any(ConnectionRequest.class), eq(true), eq(false), any()); 354 355 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 356 // Never reply to the caller info lookup. 357 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 358 359 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 360 .setInCallAdapter(any(IInCallAdapter.class)); 361 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 362 .setInCallAdapter(any(IInCallAdapter.class)); 363 364 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 365 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 366 367 assertTrueWithTimeout(new Predicate<Void>() { 368 @Override 369 public boolean apply(Void v) { 370 return mInCallServiceFixtureX.mInCallAdapter != null; 371 } 372 }); 373 374 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 375 .addCall(any(ParcelableCall.class)); 376 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 377 .addCall(any(ParcelableCall.class)); 378 379 disconnectCall(mInCallServiceFixtureX.mLatestCallId, 380 mConnectionServiceFixtureA.mLatestConnectionId); 381 } 382 383 @LargeTest 384 public void testIncomingCallFromBlockedNumberIsRejected() throws Exception { 385 String phoneNumber = "650-555-1212"; 386 blockNumber(phoneNumber); 387 388 Bundle extras = new Bundle(); 389 extras.putParcelable( 390 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 391 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 392 mTelecomSystem.getTelecomServiceImpl().getBinder() 393 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 394 395 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 396 verify(mConnectionServiceFixtureA.getTestDouble()) 397 .createConnection(any(PhoneAccountHandle.class), anyString(), 398 any(ConnectionRequest.class), eq(true), eq(false), any()); 399 400 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 401 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 402 for (CallerInfoAsyncQueryFactoryFixture.Request request : 403 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 404 request.reply(); 405 } 406 407 assertTrueWithTimeout(new Predicate<Void>() { 408 @Override 409 public boolean apply(Void aVoid) { 410 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 411 } 412 }); 413 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 414 415 verify(mInCallServiceFixtureX.getTestDouble(), never()) 416 .setInCallAdapter(any(IInCallAdapter.class)); 417 verify(mInCallServiceFixtureY.getTestDouble(), never()) 418 .setInCallAdapter(any(IInCallAdapter.class)); 419 } 420 421 @LargeTest 422 public void testIncomingCallBlockCheckTimesoutIsAllowed() throws Exception { 423 final CountDownLatch latch = new CountDownLatch(1); 424 String phoneNumber = "650-555-1212"; 425 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 426 @Override 427 public Bundle answer(InvocationOnMock invocation) throws Throwable { 428 latch.await(TEST_TIMEOUT * 2, TimeUnit.MILLISECONDS); 429 Bundle bundle = new Bundle(); 430 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 431 return bundle; 432 } 433 }); 434 435 IdPair ids = startAndMakeActiveIncomingCall( 436 phoneNumber, mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 437 latch.countDown(); 438 439 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 440 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 441 disconnectCall(ids.mCallId, ids.mConnectionId); 442 } 443 444 public void do_testDeadlockOnOutgoingCall() throws Exception { 445 final IdPair ids = startOutgoingPhoneCall("650-555-1212", 446 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA, 447 Process.myUserHandle()); 448 rapidFire( 449 new Runnable() { 450 @Override 451 public void run() { 452 while (mCallerInfoAsyncQueryFactoryFixture.mRequests.size() > 0) { 453 mCallerInfoAsyncQueryFactoryFixture.mRequests.remove(0).reply(); 454 } 455 } 456 }, 457 new Runnable() { 458 @Override 459 public void run() { 460 try { 461 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 462 } catch (Exception e) { 463 Log.e(this, e, ""); 464 } 465 } 466 }); 467 } 468 469 @MediumTest 470 public void testDeadlockOnOutgoingCall() throws Exception { 471 for (int i = 0; i < 100; i++) { 472 BasicCallTests test = new BasicCallTests(); 473 test.setContext(getContext()); 474 test.setTestContext(getTestContext()); 475 test.setName(getName()); 476 test.setUp(); 477 test.do_testDeadlockOnOutgoingCall(); 478 test.tearDown(); 479 } 480 } 481 482 @LargeTest 483 public void testIncomingThenOutgoingCalls() throws Exception { 484 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 485 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 486 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 487 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 488 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 489 490 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 491 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 492 } 493 494 @LargeTest 495 public void testOutgoingThenIncomingCalls() throws Exception { 496 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 497 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 498 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 499 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 500 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 501 verify(mConnectionServiceFixtureA.getTestDouble()) 502 .hold(eq(outgoing.mConnectionId), any()); 503 mConnectionServiceFixtureA.mConnectionById.get(outgoing.mConnectionId).state = 504 Connection.STATE_HOLDING; 505 mConnectionServiceFixtureA.sendSetOnHold(outgoing.mConnectionId); 506 assertEquals(Call.STATE_HOLDING, 507 mInCallServiceFixtureX.getCall(outgoing.mCallId).getState()); 508 assertEquals(Call.STATE_HOLDING, 509 mInCallServiceFixtureY.getCall(outgoing.mCallId).getState()); 510 511 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 512 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 513 } 514 515 @LargeTest 516 public void testAudioManagerOperations() throws Exception { 517 AudioManager audioManager = (AudioManager) mComponentContextFixture.getTestDouble() 518 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE); 519 520 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 521 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 522 523 verify(audioManager, timeout(TEST_TIMEOUT)).requestAudioFocusForCall(anyInt(), anyInt()); 524 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 525 .setMode(AudioManager.MODE_IN_CALL); 526 527 mInCallServiceFixtureX.mInCallAdapter.mute(true); 528 verify(mAudioService, timeout(TEST_TIMEOUT)) 529 .setMicrophoneMute(eq(true), any(String.class), any(Integer.class)); 530 mInCallServiceFixtureX.mInCallAdapter.mute(false); 531 verify(mAudioService, timeout(TEST_TIMEOUT)) 532 .setMicrophoneMute(eq(false), any(String.class), any(Integer.class)); 533 534 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER); 535 verify(audioManager, timeout(TEST_TIMEOUT)) 536 .setSpeakerphoneOn(true); 537 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE); 538 verify(audioManager, timeout(TEST_TIMEOUT)) 539 .setSpeakerphoneOn(false); 540 541 mConnectionServiceFixtureA. 542 sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); 543 544 verify(audioManager, timeout(TEST_TIMEOUT)) 545 .abandonAudioFocusForCall(); 546 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 547 .setMode(AudioManager.MODE_NORMAL); 548 } 549 550 private void rapidFire(Runnable... tasks) { 551 final CyclicBarrier barrier = new CyclicBarrier(tasks.length); 552 final CountDownLatch latch = new CountDownLatch(tasks.length); 553 for (int i = 0; i < tasks.length; i++) { 554 final Runnable task = tasks[i]; 555 new Thread(new Runnable() { 556 @Override 557 public void run() { 558 try { 559 barrier.await(); 560 task.run(); 561 } catch (InterruptedException | BrokenBarrierException e){ 562 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 563 } finally { 564 latch.countDown(); 565 } 566 } 567 }).start(); 568 } 569 try { 570 latch.await(); 571 } catch (InterruptedException e) { 572 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 573 } 574 } 575 576 @MediumTest 577 public void testBasicConferenceCall() throws Exception { 578 makeConferenceCall(); 579 } 580 581 @MediumTest 582 public void testAddCallToConference1() throws Exception { 583 ParcelableCall conferenceCall = makeConferenceCall(); 584 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 585 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 586 // testAddCallToConference{1,2} differ in the order of arguments to InCallAdapter#conference 587 mInCallServiceFixtureX.getInCallAdapter().conference( 588 conferenceCall.getId(), callId3.mCallId); 589 Thread.sleep(200); 590 591 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 592 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 593 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 594 assertEquals(3, updatedConference.getChildCallIds().size()); 595 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 596 } 597 598 @MediumTest 599 public void testAddCallToConference2() throws Exception { 600 ParcelableCall conferenceCall = makeConferenceCall(); 601 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 602 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 603 mInCallServiceFixtureX.getInCallAdapter() 604 .conference(callId3.mCallId, conferenceCall.getId()); 605 Thread.sleep(200); 606 607 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 608 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 609 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 610 assertEquals(3, updatedConference.getChildCallIds().size()); 611 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 612 } 613 614 /** 615 * Tests the {@link Call#pullExternalCall()} API. Verifies that if a call is not an external 616 * call, no pull call request is made to the connection service. 617 * 618 * @throws Exception 619 */ 620 @MediumTest 621 public void testPullNonExternalCall() throws Exception { 622 // TODO: Revisit this unit test once telecom support for filtering external calls from 623 // InCall services is implemented. 624 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 625 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 626 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 627 628 // Attempt to pull the call and verify the API call makes it through 629 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 630 Thread.sleep(TEST_TIMEOUT); 631 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 632 .pullExternalCall(eq(ids.mCallId), any()); 633 } 634 635 /** 636 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 637 * 638 * @throws Exception 639 */ 640 @MediumTest 641 public void testSendConnectionEventNull() throws Exception { 642 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 643 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 644 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 645 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, null); 646 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 647 .onConnectionEvent(ids.mCallId, TEST_EVENT, null); 648 } 649 650 /** 651 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 652 * 653 * @throws Exception 654 */ 655 @MediumTest 656 public void testSendConnectionEventNotNull() throws Exception { 657 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 658 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 659 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 660 661 Bundle testBundle = new Bundle(); 662 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 663 664 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 665 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, testBundle); 666 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 667 .onConnectionEvent(eq(ids.mCallId), eq(TEST_EVENT), bundleArgumentCaptor.capture()); 668 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 669 } 670 671 /** 672 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 673 * 674 * @throws Exception 675 */ 676 @MediumTest 677 public void testSendCallEventNull() throws Exception { 678 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 679 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 680 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 681 682 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, null); 683 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 684 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), isNull(Bundle.class), any()); 685 } 686 687 /** 688 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 689 * 690 * @throws Exception 691 */ 692 @MediumTest 693 public void testSendCallEventNonNull() throws Exception { 694 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 695 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 696 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 697 698 Bundle testBundle = new Bundle(); 699 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 700 701 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 702 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 703 testBundle); 704 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 705 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), 706 bundleArgumentCaptor.capture(), any()); 707 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 708 } 709 710 private void blockNumber(String phoneNumber) throws Exception { 711 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 712 @Override 713 public Bundle answer(InvocationOnMock invocation) throws Throwable { 714 Bundle bundle = new Bundle(); 715 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 716 return bundle; 717 } 718 }); 719 } 720 721 private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception { 722 when(getBlockedNumberProvider().call( 723 anyString(), 724 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER), 725 eq(phoneNumber), 726 isNull(Bundle.class))).thenAnswer(answer); 727 } 728 729 private void verifyNoBlockChecks() { 730 verifyZeroInteractions(getBlockedNumberProvider()); 731 } 732 733 private IContentProvider getBlockedNumberProvider() { 734 return mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY); 735 } 736 737 private void disconnectCall(String callId, String connectionId) throws Exception { 738 mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL); 739 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState()); 740 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState()); 741 } 742 743 /** 744 * Tests to make sure that the Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is set on a 745 * Call that is based on a Connection with the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY 746 * property set. 747 */ 748 @MediumTest 749 public void testCdmaEnhancedPrivacyVoiceCall() throws Exception { 750 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 751 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 752 753 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 754 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 755 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 756 757 assertTrue(Call.Details.hasProperty( 758 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 759 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 760 } 761 762 /** 763 * Tests to make sure that Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY is dropped 764 * when the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is removed from the Connection. 765 */ 766 @MediumTest 767 public void testDropCdmaEnhancedPrivacyVoiceCall() throws Exception { 768 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 769 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 770 771 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 772 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 773 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 774 mConnectionServiceFixtureA.mLatestConnection.setConnectionProperties(0); 775 776 assertFalse(Call.Details.hasProperty( 777 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 778 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 779 } 780 781 /** 782 * Tests the {@link Call#pullExternalCall()} API. Ensures that an external call which is 783 * pullable can be pulled. 784 * 785 * @throws Exception 786 */ 787 @LargeTest 788 public void testPullExternalCall() throws Exception { 789 // TODO: Revisit this unit test once telecom support for filtering external calls from 790 // InCall services is implemented. 791 mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities = 792 Connection.CAPABILITY_CAN_PULL_CALL; 793 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 794 Connection.PROPERTY_IS_EXTERNAL_CALL; 795 796 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 797 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 798 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 799 800 // Attempt to pull the call and verify the API call makes it through 801 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 802 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 803 .pullExternalCall(eq(ids.mConnectionId), any()); 804 } 805 806 /** 807 * Tests the {@link Call#pullExternalCall()} API. Verifies that if an external call is not 808 * marked as pullable that the connection service does not get an API call to pull the external 809 * call. 810 * 811 * @throws Exception 812 */ 813 @LargeTest 814 public void testPullNonPullableExternalCall() throws Exception { 815 // TODO: Revisit this unit test once telecom support for filtering external calls from 816 // InCall services is implemented. 817 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 818 Connection.PROPERTY_IS_EXTERNAL_CALL; 819 820 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 821 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 822 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 823 824 // Attempt to pull the call and verify the API call makes it through 825 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 826 Thread.sleep(TEST_TIMEOUT); 827 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 828 .pullExternalCall(eq(ids.mConnectionId), any()); 829 } 830 831 @LargeTest 832 public void testEmergencyCallFailMoveToSecondSim() throws Exception { 833 IdPair ids = startAndMakeDialingEmergencyCall("650-555-1212", 834 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 835 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 836 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 837 838 // The Emergency Call has failed on the default SIM with an ERROR Disconnect Cause. Retry 839 // with the other SIM PhoneAccount 840 IdPair newIds = triggerEmergencyRedial(mPhoneAccountE1.getAccountHandle(), 841 mConnectionServiceFixtureA, ids); 842 843 // Call should be active on the E1 PhoneAccount 844 mConnectionServiceFixtureA.sendSetActive(newIds.mConnectionId); 845 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(newIds.mCallId).getState()); 846 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(newIds.mCallId).getState()); 847 assertEquals(mInCallServiceFixtureX.getCall(ids.mCallId).getAccountHandle(), 848 mPhoneAccountE1.getAccountHandle()); 849 } 850 851 /** 852 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 853 * then subsequently selects a PhoneAccount which supports video calling. 854 * @throws Exception 855 */ 856 @LargeTest 857 public void testOutgoingCallSelectPhoneAccountVideo() throws Exception { 858 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 859 null, mConnectionServiceFixtureA, 860 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 861 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 862 .iterator().next(); 863 assert(call.isVideoCallingSupported()); 864 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 865 866 // Change the phone account to one which supports video calling. 867 call.setTargetPhoneAccount(mPhoneAccountA1.getAccountHandle()); 868 assert(call.isVideoCallingSupported()); 869 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 870 } 871 872 /** 873 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 874 * then subsequently selects a PhoneAccount which does not support video calling. 875 * @throws Exception 876 */ 877 @LargeTest 878 public void testOutgoingCallSelectPhoneAccountNoVideo() throws Exception { 879 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 880 null, mConnectionServiceFixtureA, 881 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 882 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 883 .iterator().next(); 884 assert(call.isVideoCallingSupported()); 885 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 886 887 // Change the phone account to one which does not support video calling. 888 call.setTargetPhoneAccount(mPhoneAccountA2.getAccountHandle()); 889 assert(!call.isVideoCallingSupported()); 890 assertEquals(VideoProfile.STATE_AUDIO_ONLY, call.getVideoState()); 891 } 892} 893