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 android.telecom.cts; 18 19 import static android.telecom.cts.TestUtils.*; 20 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.provider.BlockedNumberContract; 26 import android.telecom.CallAudioState; 27 import android.telecom.Call; 28 import android.telecom.Connection; 29 import android.telecom.ConnectionService; 30 import android.telecom.InCallService; 31 import android.telecom.TelecomManager; 32 import android.telecom.VideoProfile; 33 34 import java.util.List; 35 36 /** 37 * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to 38 * verify the functionality of the Telecom service. 39 */ 40 public class ExtendedInCallServiceTest extends BaseTelecomTestWithMockServices { 41 42 @Override setUp()43 protected void setUp() throws Exception { 44 super.setUp(); 45 if (mShouldTestTelecom) { 46 setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE); 47 } 48 } 49 testAddNewOutgoingCallAndThenDisconnect()50 public void testAddNewOutgoingCallAndThenDisconnect() { 51 if (!mShouldTestTelecom) { 52 return; 53 } 54 55 placeAndVerifyCall(); 56 verifyConnectionForOutgoingCall(); 57 58 final MockInCallService inCallService = mInCallCallbacks.getService(); 59 inCallService.disconnectLastCall(); 60 61 assertNumCalls(inCallService, 0); 62 } 63 testMuteAndUnmutePhone()64 public void testMuteAndUnmutePhone() { 65 if (!mShouldTestTelecom) { 66 return; 67 } 68 69 placeAndVerifyCall(); 70 final MockConnection connection = verifyConnectionForOutgoingCall(); 71 72 final MockInCallService inCallService = mInCallCallbacks.getService(); 73 74 final Call call = inCallService.getLastCall(); 75 76 assertCallState(call, Call.STATE_DIALING); 77 78 assertMuteState(connection, false); 79 80 // Explicitly call super implementation to enable detection of CTS coverage 81 ((InCallService) inCallService).setMuted(true); 82 83 assertMuteState(connection, true); 84 assertMuteState(inCallService, true); 85 86 inCallService.setMuted(false); 87 assertMuteState(connection, false); 88 assertMuteState(inCallService, false); 89 } 90 testSwitchAudioRoutes()91 public void testSwitchAudioRoutes() { 92 if (!mShouldTestTelecom) { 93 return; 94 } 95 96 placeAndVerifyCall(); 97 final MockConnection connection = verifyConnectionForOutgoingCall(); 98 99 final MockInCallService inCallService = mInCallCallbacks.getService(); 100 101 final Call call = inCallService.getLastCall(); 102 assertCallState(call, Call.STATE_DIALING); 103 104 final int currentInvokeCount = mOnCallAudioStateChangedCounter.getInvokeCount(); 105 106 107 // We need to check what audio routes are available. If speaker and either headset or 108 // earpiece aren't available, then we should skip this test. 109 int availableRoutes = connection.getCallAudioState().getSupportedRouteMask(); 110 if ((availableRoutes & CallAudioState.ROUTE_SPEAKER) == 0) { 111 return; 112 } 113 if ((availableRoutes & CallAudioState.ROUTE_WIRED_OR_EARPIECE) == 0) { 114 return; 115 } 116 // Determine what the second route to go to after SPEAKER should be, depending on what's 117 // supported. 118 int secondRoute = (availableRoutes & CallAudioState.ROUTE_EARPIECE) == 0 ? 119 CallAudioState.ROUTE_WIRED_HEADSET : CallAudioState.ROUTE_EARPIECE; 120 121 // Explicitly call super implementation to enable detection of CTS coverage 122 ((InCallService) inCallService).setAudioRoute(CallAudioState.ROUTE_SPEAKER); 123 mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 1, 124 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 125 assertAudioRoute(connection, CallAudioState.ROUTE_SPEAKER); 126 assertAudioRoute(inCallService, CallAudioState.ROUTE_SPEAKER); 127 128 inCallService.setAudioRoute(secondRoute); 129 mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 2, 130 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 131 assertAudioRoute(connection, secondRoute); 132 assertAudioRoute(inCallService, secondRoute); 133 } 134 135 /** 136 * Tests that DTMF Tones are sent from the {@link InCallService} to the 137 * {@link ConnectionService} in the correct sequence. 138 * 139 * @see {@link Call#playDtmfTone(char)} 140 * @see {@link Call#stopDtmfTone()} 141 */ testPlayAndStopDtmfTones()142 public void testPlayAndStopDtmfTones() { 143 if (!mShouldTestTelecom) { 144 return; 145 } 146 147 placeAndVerifyCall(); 148 final MockConnection connection = verifyConnectionForOutgoingCall(); 149 150 final MockInCallService inCallService = mInCallCallbacks.getService(); 151 152 final Call call = inCallService.getLastCall(); 153 assertCallState(call, Call.STATE_DIALING); 154 155 assertDtmfString(connection, ""); 156 157 call.playDtmfTone('1'); 158 assertDtmfString(connection, "1"); 159 160 call.playDtmfTone('2'); 161 assertDtmfString(connection, "12"); 162 163 call.stopDtmfTone(); 164 assertDtmfString(connection, "12."); 165 166 call.playDtmfTone('3'); 167 call.playDtmfTone('4'); 168 call.playDtmfTone('5'); 169 assertDtmfString(connection, "12.345"); 170 171 call.stopDtmfTone(); 172 assertDtmfString(connection, "12.345."); 173 } 174 testHoldAndUnholdCall()175 public void testHoldAndUnholdCall() { 176 if (!mShouldTestTelecom) { 177 return; 178 } 179 180 placeAndVerifyCall(); 181 final MockConnection connection = verifyConnectionForOutgoingCall(); 182 183 final MockInCallService inCallService = mInCallCallbacks.getService(); 184 185 final Call call = inCallService.getLastCall(); 186 187 assertCallState(call, Call.STATE_DIALING); 188 189 connection.setActive(); 190 191 assertCallState(call, Call.STATE_ACTIVE); 192 193 call.hold(); 194 assertCallState(call, Call.STATE_HOLDING); 195 assertEquals(Connection.STATE_HOLDING, connection.getState()); 196 197 call.unhold(); 198 assertCallState(call, Call.STATE_ACTIVE); 199 assertEquals(Connection.STATE_ACTIVE, connection.getState()); 200 } 201 testAnswerIncomingCallAudioOnly()202 public void testAnswerIncomingCallAudioOnly() { 203 if (!mShouldTestTelecom) { 204 return; 205 } 206 207 addAndVerifyNewIncomingCall(createTestNumber(), null); 208 final MockConnection connection = verifyConnectionForIncomingCall(); 209 210 final MockInCallService inCallService = mInCallCallbacks.getService(); 211 212 final Call call = inCallService.getLastCall(); 213 214 assertCallState(call, Call.STATE_RINGING); 215 assertConnectionState(connection, Connection.STATE_RINGING); 216 217 call.answer(VideoProfile.STATE_AUDIO_ONLY); 218 219 assertCallState(call, Call.STATE_ACTIVE); 220 assertConnectionState(connection, Connection.STATE_ACTIVE); 221 } 222 testIncomingCallFromBlockedNumber_IsRejected()223 public void testIncomingCallFromBlockedNumber_IsRejected() throws Exception { 224 if (!mShouldTestTelecom) { 225 return; 226 } 227 228 Uri blockedUri = null; 229 230 try { 231 Uri testNumberUri = createTestNumber(); 232 blockedUri = blockNumber(testNumberUri); 233 234 final Bundle extras = new Bundle(); 235 extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumberUri); 236 mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras); 237 238 final MockConnection connection = verifyConnectionForIncomingCall(); 239 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 240 assertNull(mInCallCallbacks.getService()); 241 } finally { 242 if (blockedUri != null) { 243 mContext.getContentResolver().delete(blockedUri, null, null); 244 } 245 } 246 } 247 blockNumber(Uri phoneNumberUri)248 private Uri blockNumber(Uri phoneNumberUri) { 249 ContentValues cv = new ContentValues(); 250 cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, 251 phoneNumberUri.getSchemeSpecificPart()); 252 return mContext.getContentResolver().insert( 253 BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv); 254 } 255 testAnswerIncomingCallAsVideo_SendsCorrectVideoState()256 public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() { 257 if (!mShouldTestTelecom) { 258 return; 259 } 260 261 addAndVerifyNewIncomingCall(createTestNumber(), null); 262 final MockConnection connection = verifyConnectionForIncomingCall(); 263 264 final MockInCallService inCallService = mInCallCallbacks.getService(); 265 266 final Call call = inCallService.getLastCall(); 267 268 assertCallState(call, Call.STATE_RINGING); 269 assertConnectionState(connection, Connection.STATE_RINGING); 270 271 call.answer(VideoProfile.STATE_BIDIRECTIONAL); 272 273 assertCallState(call, Call.STATE_ACTIVE); 274 assertConnectionState(connection, Connection.STATE_ACTIVE); 275 assertEquals("Connection did not receive VideoState for answered call", 276 VideoProfile.STATE_BIDIRECTIONAL, connection.videoState); 277 } 278 testRejectIncomingCall()279 public void testRejectIncomingCall() { 280 if (!mShouldTestTelecom) { 281 return; 282 } 283 284 addAndVerifyNewIncomingCall(createTestNumber(), null); 285 final MockConnection connection = verifyConnectionForIncomingCall(); 286 287 final MockInCallService inCallService = mInCallCallbacks.getService(); 288 289 final Call call = inCallService.getLastCall(); 290 291 assertCallState(call, Call.STATE_RINGING); 292 assertConnectionState(connection, Connection.STATE_RINGING); 293 294 call.reject(false, null); 295 296 assertCallState(call, Call.STATE_DISCONNECTED); 297 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 298 } 299 testRejectIncomingCallWithMessage()300 public void testRejectIncomingCallWithMessage() { 301 if (!mShouldTestTelecom) { 302 return; 303 } 304 String disconnectReason = "Test reason for disconnect"; 305 306 addAndVerifyNewIncomingCall(createTestNumber(), null); 307 final MockConnection connection = verifyConnectionForIncomingCall(); 308 309 final MockInCallService inCallService = mInCallCallbacks.getService(); 310 311 final Call call = inCallService.getLastCall(); 312 313 assertCallState(call, Call.STATE_RINGING); 314 assertConnectionState(connection, Connection.STATE_RINGING); 315 316 call.reject(true, disconnectReason); 317 318 assertCallState(call, Call.STATE_DISCONNECTED); 319 assertConnectionState(connection, Connection.STATE_DISCONNECTED); 320 assertDisconnectReason(connection, disconnectReason); 321 } 322 testCanAddCall_CannotAddForExistingDialingCall()323 public void testCanAddCall_CannotAddForExistingDialingCall() { 324 if (!mShouldTestTelecom) { 325 return; 326 } 327 328 placeAndVerifyCall(); 329 verifyConnectionForOutgoingCall(); 330 331 final MockInCallService inCallService = mInCallCallbacks.getService(); 332 333 final Call call = inCallService.getLastCall(); 334 assertCallState(call, Call.STATE_DIALING); 335 336 assertCanAddCall(inCallService, false, 337 "Should not be able to add call with existing dialing call"); 338 } 339 testCanAddCall_CanAddForExistingActiveCall()340 public void testCanAddCall_CanAddForExistingActiveCall() { 341 if (!mShouldTestTelecom) { 342 return; 343 } 344 345 placeAndVerifyCall(); 346 final MockConnection connection = verifyConnectionForOutgoingCall(); 347 348 final MockInCallService inCallService = mInCallCallbacks.getService(); 349 350 final Call call = inCallService.getLastCall(); 351 assertCallState(call, Call.STATE_DIALING); 352 353 connection.setActive(); 354 355 assertCallState(call, Call.STATE_ACTIVE); 356 357 assertCanAddCall(inCallService, true, 358 "Should be able to add call with only one active call"); 359 } 360 testCanAddCall_CannotAddIfTooManyCalls()361 public void testCanAddCall_CannotAddIfTooManyCalls() { 362 if (!mShouldTestTelecom) { 363 return; 364 } 365 366 placeAndVerifyCall(); 367 final MockConnection connection1 = verifyConnectionForOutgoingCall(0); 368 final MockInCallService inCallService = mInCallCallbacks.getService(); 369 final Call call1 = inCallService.getLastCall(); 370 assertCallState(call1, Call.STATE_DIALING); 371 372 connection1.setActive(); 373 374 assertCallState(call1, Call.STATE_ACTIVE); 375 376 placeAndVerifyCall(); 377 final MockConnection connection2 = verifyConnectionForOutgoingCall(1); 378 379 final Call call2 = inCallService.getLastCall(); 380 assertCallState(call2, Call.STATE_DIALING); 381 connection2.setActive(); 382 assertCallState(call2, Call.STATE_ACTIVE); 383 384 assertEquals("InCallService should have 2 calls", 2, inCallService.getCallCount()); 385 386 assertCanAddCall(inCallService, false, 387 "Should not be able to add call with two calls already present"); 388 389 call1.hold(); 390 assertCallState(call1, Call.STATE_HOLDING); 391 392 assertCanAddCall(inCallService, false, 393 "Should not be able to add call with two calls already present"); 394 } 395 testOnBringToForeground()396 public void testOnBringToForeground() { 397 if (!mShouldTestTelecom) { 398 return; 399 } 400 401 placeAndVerifyCall(); 402 verifyConnectionForOutgoingCall(); 403 404 final MockInCallService inCallService = mInCallCallbacks.getService(); 405 406 final Call call = inCallService.getLastCall(); 407 408 assertCallState(call, Call.STATE_DIALING); 409 410 assertEquals(0, mOnBringToForegroundCounter.getInvokeCount()); 411 412 final TelecomManager tm = 413 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 414 415 tm.showInCallScreen(false); 416 417 mOnBringToForegroundCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 418 419 assertFalse((Boolean) mOnBringToForegroundCounter.getArgs(0)[0]); 420 421 tm.showInCallScreen(true); 422 423 mOnBringToForegroundCounter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 424 425 assertTrue((Boolean) mOnBringToForegroundCounter.getArgs(1)[0]); 426 } 427 testSilenceRinger()428 public void testSilenceRinger() { 429 if (!mShouldTestTelecom) { 430 return; 431 } 432 433 addAndVerifyNewIncomingCall(createTestNumber(), null); 434 final MockConnection connection = verifyConnectionForIncomingCall(); 435 final MockInCallService inCallService = mInCallCallbacks.getService(); 436 437 final TelecomManager telecomManager = 438 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 439 telecomManager.silenceRinger(); 440 mOnSilenceRingerCounter.waitForCount(1); 441 } 442 testOnPostDialWaitAndContinue()443 public void testOnPostDialWaitAndContinue() { 444 if (!mShouldTestTelecom) { 445 return; 446 } 447 448 placeAndVerifyCall(); 449 final MockConnection connection = verifyConnectionForOutgoingCall(); 450 final MockInCallService inCallService = mInCallCallbacks.getService(); 451 final Call call = inCallService.getLastCall(); 452 assertCallState(call, Call.STATE_DIALING); 453 454 connection.setActive(); 455 assertCallState(call, Call.STATE_ACTIVE); 456 457 final String postDialString = "12345"; 458 ((Connection) connection).setPostDialWait(postDialString); 459 mOnPostDialWaitCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 460 461 assertEquals(postDialString, mOnPostDialWaitCounter.getArgs(0)[1]); 462 assertEquals(postDialString, call.getRemainingPostDialSequence()); 463 464 final InvokeCounter counter = connection.getInvokeCounter(MockConnection.ON_POST_DIAL_WAIT); 465 466 call.postDialContinue(true); 467 counter.waitForCount(1); 468 assertTrue((Boolean) counter.getArgs(0)[0]); 469 470 call.postDialContinue(false); 471 counter.waitForCount(2); 472 assertFalse((Boolean) counter.getArgs(1)[0]); 473 } 474 testOnCannedTextResponsesLoaded()475 public void testOnCannedTextResponsesLoaded() { 476 if (!mShouldTestTelecom) { 477 return; 478 } 479 480 addAndVerifyNewIncomingCall(createTestNumber(), null); 481 verifyConnectionForIncomingCall(); 482 final MockInCallService inCallService = mInCallCallbacks.getService(); 483 484 final Call call = inCallService.getLastCall(); 485 486 assertCallState(call, Call.STATE_RINGING); 487 488 // We can't do much to enforce the number and type of responses that are preloaded on 489 // device, so the best we can do is to make sure that the call back is called and 490 // that the returned list is non-empty. 491 492 // This test should also verify that the callback is called as well, but unfortunately it 493 // is never called right now (b/22952515). 494 // mOnCannedTextResponsesLoadedCounter.waitForCount(1); 495 496 assertGetCannedTextResponsesNotEmpty(call); 497 } 498 testGetCalls()499 public void testGetCalls() { 500 if (!mShouldTestTelecom) { 501 return; 502 } 503 504 placeAndVerifyCall(); 505 final MockConnection connection1 = verifyConnectionForOutgoingCall(0); 506 final MockInCallService inCallService = mInCallCallbacks.getService(); 507 final Call call1 = inCallService.getLastCall(); 508 assertCallState(call1, Call.STATE_DIALING); 509 510 connection1.setActive(); 511 512 assertCallState(call1, Call.STATE_ACTIVE); 513 514 List<Call> calls = inCallService.getCalls(); 515 assertEquals("InCallService.getCalls() should return list with 1 call.", 1, calls.size()); 516 assertEquals(call1, calls.get(0)); 517 518 addAndVerifyNewIncomingCall(createTestNumber(), null); 519 verifyConnectionForIncomingCall(); 520 521 final Call call2 = inCallService.getLastCall(); 522 calls = inCallService.getCalls(); 523 assertEquals("InCallService.getCalls() should return list with 2 calls.", 2, calls.size()); 524 assertEquals(call1, calls.get(0)); 525 assertEquals(call2, calls.get(1)); 526 } 527 assertGetCannedTextResponsesNotEmpty(final Call call)528 private void assertGetCannedTextResponsesNotEmpty(final Call call) { 529 waitUntilConditionIsTrueOrTimeout( 530 new Condition() { 531 @Override 532 public Object expected() { 533 return true; 534 } 535 536 @Override 537 public Object actual() { 538 return call.getCannedTextResponses() != null 539 && !call.getCannedTextResponses().isEmpty(); 540 } 541 542 }, 543 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, 544 "Call.getCannedTextResponses should not be empty"); 545 } 546 assertCanAddCall(final InCallService inCallService, final boolean canAddCall, String message)547 private void assertCanAddCall(final InCallService inCallService, final boolean canAddCall, 548 String message) { 549 waitUntilConditionIsTrueOrTimeout( 550 new Condition() { 551 @Override 552 public Object expected() { 553 return canAddCall; 554 } 555 556 @Override 557 public Object actual() { 558 return inCallService.canAddCall(); 559 } 560 }, 561 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, 562 message 563 ); 564 } 565 } 566