TelecomSystemTest.java revision b60f00673149da9a96d9369f4e1c4458e9a9cf53
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.anyBoolean; 21import static org.mockito.Matchers.anyInt; 22import static org.mockito.Matchers.anyString; 23import static org.mockito.Matchers.eq; 24import static org.mockito.Mockito.atLeastOnce; 25import static org.mockito.Mockito.mock; 26import static org.mockito.Mockito.reset; 27import static org.mockito.Mockito.timeout; 28import static org.mockito.Mockito.verify; 29import static org.mockito.Mockito.when; 30 31import android.content.BroadcastReceiver; 32import android.content.ComponentName; 33import android.content.Context; 34import android.content.Intent; 35import android.media.AudioManager; 36import android.net.Uri; 37import android.os.Bundle; 38import android.os.Handler; 39import android.os.UserHandle; 40import android.telecom.Call; 41import android.telecom.CallAudioState; 42import android.telecom.ConnectionRequest; 43import android.telecom.DisconnectCause; 44import android.telecom.ParcelableCall; 45import android.telecom.PhoneAccount; 46import android.telecom.PhoneAccountHandle; 47import android.telecom.TelecomManager; 48import android.telephony.TelephonyManager; 49 50import com.android.internal.telecom.IInCallAdapter; 51import com.android.server.telecom.CallsManager; 52import com.android.server.telecom.HeadsetMediaButton; 53import com.android.server.telecom.HeadsetMediaButtonFactory; 54import com.android.server.telecom.InCallWakeLockController; 55import com.android.server.telecom.InCallWakeLockControllerFactory; 56import com.android.server.telecom.Log; 57import com.android.server.telecom.MissedCallNotifier; 58import com.android.server.telecom.ProximitySensorManager; 59import com.android.server.telecom.ProximitySensorManagerFactory; 60import com.android.server.telecom.TelecomSystem; 61 62import org.mockito.ArgumentCaptor; 63import org.mockito.Mock; 64import org.mockito.internal.verification.VerificationModeFactory; 65 66import java.util.concurrent.BrokenBarrierException; 67import java.util.concurrent.CountDownLatch; 68import java.util.concurrent.CyclicBarrier; 69 70public class TelecomSystemTest extends TelecomTestCase { 71 72 static final int TEST_TIMEOUT = 1000; // milliseconds 73 74 @Mock MissedCallNotifier mMissedCallNotifier; 75 @Mock HeadsetMediaButton mHeadsetMediaButton; 76 @Mock ProximitySensorManager mProximitySensorManager; 77 @Mock InCallWakeLockController mInCallWakeLockController; 78 79 final ComponentName mInCallServiceComponentNameX = 80 new ComponentName( 81 "incall-service-package-X", 82 "incall-service-class-X"); 83 final ComponentName mInCallServiceComponentNameY = 84 new ComponentName( 85 "incall-service-package-Y", 86 "incall-service-class-Y"); 87 88 InCallServiceFixture mInCallServiceFixtureX; 89 InCallServiceFixture mInCallServiceFixtureY; 90 91 final ComponentName mConnectionServiceComponentNameA = 92 new ComponentName( 93 "connection-service-package-A", 94 "connection-service-class-A"); 95 final ComponentName mConnectionServiceComponentNameB = 96 new ComponentName( 97 "connection-service-package-B", 98 "connection-service-class-B"); 99 100 final PhoneAccount mPhoneAccountA0 = 101 PhoneAccount.builder( 102 new PhoneAccountHandle( 103 mConnectionServiceComponentNameA, 104 "id A 0"), 105 "Phone account service A ID 0") 106 .addSupportedUriScheme("tel") 107 .setCapabilities( 108 PhoneAccount.CAPABILITY_CALL_PROVIDER | 109 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 110 .build(); 111 final PhoneAccount mPhoneAccountA1 = 112 PhoneAccount.builder( 113 new PhoneAccountHandle( 114 mConnectionServiceComponentNameA, 115 "id A 1"), 116 "Phone account service A ID 1") 117 .addSupportedUriScheme("tel") 118 .setCapabilities( 119 PhoneAccount.CAPABILITY_CALL_PROVIDER | 120 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 121 .build(); 122 final PhoneAccount mPhoneAccountB0 = 123 PhoneAccount.builder( 124 new PhoneAccountHandle( 125 mConnectionServiceComponentNameB, 126 "id B 0"), 127 "Phone account service B ID 0") 128 .addSupportedUriScheme("tel") 129 .setCapabilities( 130 PhoneAccount.CAPABILITY_CALL_PROVIDER | 131 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 132 .build(); 133 134 ConnectionServiceFixture mConnectionServiceFixtureA; 135 ConnectionServiceFixture mConnectionServiceFixtureB; 136 137 CallerInfoAsyncQueryFactoryFixture mCallerInfoAsyncQueryFactoryFixture; 138 139 TelecomSystem mTelecomSystem; 140 141 class IdPair { 142 final String mConnectionId; 143 final String mCallId; 144 145 public IdPair(String connectionId, String callId) { 146 this.mConnectionId = connectionId; 147 this.mCallId = callId; 148 } 149 } 150 151 @Override 152 public void setUp() throws Exception { 153 super.setUp(); 154 155 // First set up information about the In-Call services in the mock Context, since 156 // Telecom will search for these as soon as it is instantiated 157 setupInCallServices(); 158 159 // Next, create the TelecomSystem, our system under test 160 setupTelecomSystem(); 161 162 // Finally, register the ConnectionServices with the PhoneAccountRegistrar of the 163 // now-running TelecomSystem 164 setupConnectionServices(); 165 } 166 167 @Override 168 public void tearDown() throws Exception { 169 mTelecomSystem = null; 170 super.tearDown(); 171 } 172 173 private void setupTelecomSystem() throws Exception { 174 HeadsetMediaButtonFactory headsetMediaButtonFactory = 175 mock(HeadsetMediaButtonFactory.class); 176 ProximitySensorManagerFactory proximitySensorManagerFactory = 177 mock(ProximitySensorManagerFactory.class); 178 InCallWakeLockControllerFactory inCallWakeLockControllerFactory = 179 mock(InCallWakeLockControllerFactory.class); 180 181 mCallerInfoAsyncQueryFactoryFixture = new CallerInfoAsyncQueryFactoryFixture(); 182 183 when(headsetMediaButtonFactory.create( 184 any(Context.class), 185 any(CallsManager.class), 186 any(TelecomSystem.SyncRoot.class))) 187 .thenReturn(mHeadsetMediaButton); 188 when(proximitySensorManagerFactory.create( 189 any(Context.class), 190 any(CallsManager.class))) 191 .thenReturn(mProximitySensorManager); 192 when(inCallWakeLockControllerFactory.create( 193 any(Context.class), 194 any(CallsManager.class))) 195 .thenReturn(mInCallWakeLockController); 196 197 mTelecomSystem = new TelecomSystem( 198 mComponentContextFixture.getTestDouble(), 199 mMissedCallNotifier, 200 mCallerInfoAsyncQueryFactoryFixture.getTestDouble(), 201 headsetMediaButtonFactory, 202 proximitySensorManagerFactory, 203 inCallWakeLockControllerFactory); 204 205 verify(headsetMediaButtonFactory).create( 206 eq(mComponentContextFixture.getTestDouble().getApplicationContext()), 207 any(CallsManager.class), 208 any(TelecomSystem.SyncRoot.class)); 209 verify(proximitySensorManagerFactory).create( 210 eq(mComponentContextFixture.getTestDouble().getApplicationContext()), 211 any(CallsManager.class)); 212 verify(inCallWakeLockControllerFactory).create( 213 eq(mComponentContextFixture.getTestDouble().getApplicationContext()), 214 any(CallsManager.class)); 215 } 216 217 private void setupConnectionServices() throws Exception { 218 mConnectionServiceFixtureA = new ConnectionServiceFixture(); 219 mConnectionServiceFixtureB = new ConnectionServiceFixture(); 220 221 mComponentContextFixture.addConnectionService( 222 mConnectionServiceComponentNameA, 223 mConnectionServiceFixtureA.getTestDouble()); 224 mComponentContextFixture.addConnectionService( 225 mConnectionServiceComponentNameB, 226 mConnectionServiceFixtureB.getTestDouble()); 227 228 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA0); 229 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA1); 230 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountB0); 231 232 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount( 233 mPhoneAccountA0.getAccountHandle()); 234 } 235 236 private void setupInCallServices() throws Exception { 237 mComponentContextFixture.putResource( 238 com.android.server.telecom.R.string.ui_default_package, 239 mInCallServiceComponentNameX.getPackageName()); 240 mComponentContextFixture.putResource( 241 com.android.server.telecom.R.string.incall_default_class, 242 mInCallServiceComponentNameX.getClassName()); 243 244 mInCallServiceFixtureX = new InCallServiceFixture(); 245 mInCallServiceFixtureY = new InCallServiceFixture(); 246 247 mComponentContextFixture.addInCallService( 248 mInCallServiceComponentNameX, 249 mInCallServiceFixtureX.getTestDouble()); 250 mComponentContextFixture.addInCallService( 251 mInCallServiceComponentNameY, 252 mInCallServiceFixtureY.getTestDouble()); 253 } 254 255 private IdPair startOutgoingPhoneCall( 256 String number, 257 PhoneAccountHandle phoneAccountHandle, 258 ConnectionServiceFixture connectionServiceFixture) throws Exception { 259 reset( 260 connectionServiceFixture.getTestDouble(), 261 mInCallServiceFixtureX.getTestDouble(), 262 mInCallServiceFixtureY.getTestDouble()); 263 264 assertEquals( 265 mInCallServiceFixtureX.mCallById.size(), 266 mInCallServiceFixtureY.mCallById.size()); 267 assertEquals( 268 (mInCallServiceFixtureX.mInCallAdapter != null), 269 (mInCallServiceFixtureY.mInCallAdapter != null)); 270 271 int startingNumConnections = connectionServiceFixture.mConnectionById.size(); 272 int startingNumCalls = mInCallServiceFixtureX.mCallById.size(); 273 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null; 274 275 Intent actionCallIntent = new Intent(); 276 actionCallIntent.setData(Uri.parse("tel:" + number)); 277 actionCallIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); 278 actionCallIntent.setAction(Intent.ACTION_CALL); 279 if (phoneAccountHandle != null) { 280 actionCallIntent.putExtra( 281 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 282 phoneAccountHandle); 283 } 284 285 mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent); 286 287 if (!hasInCallAdapter) { 288 verify(mInCallServiceFixtureX.getTestDouble()) 289 .setInCallAdapter( 290 any(IInCallAdapter.class)); 291 verify(mInCallServiceFixtureY.getTestDouble()) 292 .setInCallAdapter( 293 any(IInCallAdapter.class)); 294 } 295 296 ArgumentCaptor<Intent> newOutgoingCallIntent = 297 ArgumentCaptor.forClass(Intent.class); 298 ArgumentCaptor<BroadcastReceiver> newOutgoingCallReceiver = 299 ArgumentCaptor.forClass(BroadcastReceiver.class); 300 301 verify(mComponentContextFixture.getTestDouble().getApplicationContext()) 302 .sendOrderedBroadcastAsUser( 303 newOutgoingCallIntent.capture(), 304 any(UserHandle.class), 305 anyString(), 306 anyInt(), 307 newOutgoingCallReceiver.capture(), 308 any(Handler.class), 309 anyInt(), 310 anyString(), 311 any(Bundle.class)); 312 313 assertNotNull(mInCallServiceFixtureX.mInCallAdapter); 314 assertNotNull(mInCallServiceFixtureY.mInCallAdapter); 315 316 // Pass on the new outgoing call Intent 317 // Set a dummy PendingResult so the BroadcastReceiver agrees to accept onReceive() 318 newOutgoingCallReceiver.getValue().setPendingResult( 319 new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0)); 320 newOutgoingCallReceiver.getValue().setResultData( 321 newOutgoingCallIntent.getValue().getStringExtra(Intent.EXTRA_PHONE_NUMBER)); 322 newOutgoingCallReceiver.getValue().onReceive( 323 mComponentContextFixture.getTestDouble(), 324 newOutgoingCallIntent.getValue()); 325 326 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size()); 327 328 verify(connectionServiceFixture.getTestDouble()).createConnection( 329 eq(phoneAccountHandle), 330 anyString(), 331 any(ConnectionRequest.class), 332 anyBoolean(), 333 anyBoolean()); 334 335 connectionServiceFixture.sendHandleCreateConnectionComplete( 336 connectionServiceFixture.mLatestConnectionId); 337 338 assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size()); 339 assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size()); 340 341 assertEquals( 342 mInCallServiceFixtureX.mLatestCallId, 343 mInCallServiceFixtureY.mLatestCallId); 344 345 return new IdPair( 346 connectionServiceFixture.mLatestConnectionId, 347 mInCallServiceFixtureX.mLatestCallId); 348 } 349 350 private IdPair startIncomingPhoneCall( 351 String number, 352 PhoneAccountHandle phoneAccountHandle, 353 ConnectionServiceFixture connectionServiceFixture) throws Exception { 354 reset( 355 connectionServiceFixture.getTestDouble(), 356 mInCallServiceFixtureX.getTestDouble(), 357 mInCallServiceFixtureY.getTestDouble()); 358 359 assertEquals( 360 mInCallServiceFixtureX.mCallById.size(), 361 mInCallServiceFixtureY.mCallById.size()); 362 assertEquals( 363 (mInCallServiceFixtureX.mInCallAdapter != null), 364 (mInCallServiceFixtureY.mInCallAdapter != null)); 365 366 int startingNumConnections = connectionServiceFixture.mConnectionById.size(); 367 int startingNumCalls = mInCallServiceFixtureX.mCallById.size(); 368 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null; 369 370 Bundle extras = new Bundle(); 371 extras.putParcelable( 372 TelephonyManager.EXTRA_INCOMING_NUMBER, 373 Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null)); 374 mTelecomSystem.getTelecomServiceImpl().getBinder() 375 .addNewIncomingCall(phoneAccountHandle, extras); 376 377 verify(connectionServiceFixture.getTestDouble()).createConnection( 378 any(PhoneAccountHandle.class), 379 anyString(), 380 any(ConnectionRequest.class), 381 eq(true), 382 eq(false)); 383 384 connectionServiceFixture.sendHandleCreateConnectionComplete( 385 connectionServiceFixture.mLatestConnectionId); 386 connectionServiceFixture.sendSetRinging( 387 connectionServiceFixture.mLatestConnectionId); 388 389 // For the case of incoming calls, Telecom connecting the InCall services and adding the 390 // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call 391 // is added, future interactions as triggered by the ConnectionService, through the various 392 // test fixtures, will be synchronous. 393 394 if (!hasInCallAdapter) { 395 verify( 396 mInCallServiceFixtureX.getTestDouble(), 397 timeout(TEST_TIMEOUT)) 398 .setInCallAdapter( 399 any(IInCallAdapter.class)); 400 verify( 401 mInCallServiceFixtureY.getTestDouble(), 402 timeout(TEST_TIMEOUT)) 403 .setInCallAdapter( 404 any(IInCallAdapter.class)); 405 } 406 407 // Give the InCallService time to respond 408 pause(); 409 410 assertNotNull(mInCallServiceFixtureX.mInCallAdapter); 411 assertNotNull(mInCallServiceFixtureY.mInCallAdapter); 412 413 verify( 414 mInCallServiceFixtureX.getTestDouble(), 415 timeout(TEST_TIMEOUT)) 416 .addCall( 417 any(ParcelableCall.class)); 418 verify( 419 mInCallServiceFixtureY.getTestDouble(), 420 timeout(TEST_TIMEOUT)) 421 .addCall( 422 any(ParcelableCall.class)); 423 424 // Give the InCallService time to respond 425 pause(); 426 427 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size()); 428 assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size()); 429 assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size()); 430 431 assertEquals( 432 mInCallServiceFixtureX.mLatestCallId, 433 mInCallServiceFixtureY.mLatestCallId); 434 435 return new IdPair( 436 connectionServiceFixture.mLatestConnectionId, 437 mInCallServiceFixtureX.mLatestCallId); 438 } 439 440 private void rapidFire(Runnable... tasks) { 441 final CyclicBarrier barrier = new CyclicBarrier(tasks.length); 442 final CountDownLatch latch = new CountDownLatch(tasks.length); 443 for (int i = 0; i < tasks.length; i++) { 444 final Runnable task = tasks[i]; 445 new Thread(new Runnable() { 446 @Override 447 public void run() { 448 try { 449 barrier.await(); 450 task.run(); 451 } catch (InterruptedException | BrokenBarrierException e){ 452 Log.e(TelecomSystemTest.this, e, "Unexpectedly interrupted"); 453 } finally { 454 latch.countDown(); 455 } 456 } 457 }).start(); 458 } 459 try { 460 latch.await(); 461 } catch (InterruptedException e) { 462 Log.e(TelecomSystemTest.this, e, "Unexpectedly interrupted"); 463 } 464 } 465 466 // A simple outgoing call, verifying that the appropriate connection service is contacted, 467 // the proper lifecycle is followed, and both In-Call Services are updated correctly. 468 private IdPair startAndMakeActiveOutgoingCall( 469 String number, 470 PhoneAccountHandle phoneAccountHandle, 471 ConnectionServiceFixture connectionServiceFixture) throws Exception { 472 IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture); 473 474 connectionServiceFixture.sendSetDialing(ids.mConnectionId); 475 476 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 477 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 478 479 connectionServiceFixture.sendSetActive(ids.mConnectionId); 480 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 481 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 482 483 return ids; 484 } 485 486 public void testSingleOutgoingCallLocalDisconnect() throws Exception { 487 IdPair ids = startAndMakeActiveOutgoingCall( 488 "650-555-1212", 489 mPhoneAccountA0.getAccountHandle(), 490 mConnectionServiceFixtureA); 491 492 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 493 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 494 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 495 496 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 497 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 498 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 499 } 500 501 public void testSingleOutgoingCallRemoteDisconnect() throws Exception { 502 IdPair ids = startAndMakeActiveOutgoingCall( 503 "650-555-1212", 504 mPhoneAccountA0.getAccountHandle(), 505 mConnectionServiceFixtureA); 506 507 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 508 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 509 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 510 } 511 512 // A simple incoming call, similar in scope to the previous test 513 private IdPair startAndMakeActiveIncomingCall( 514 String number, 515 PhoneAccountHandle phoneAccountHandle, 516 ConnectionServiceFixture connectionServiceFixture) throws Exception { 517 IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture); 518 519 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 520 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 521 522 connectionServiceFixture.sendSetActive(ids.mConnectionId); 523 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 524 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 525 526 return ids; 527 } 528 529 public void testSingleIncomingCallLocalDisconnect() throws Exception { 530 IdPair ids = startAndMakeActiveIncomingCall( 531 "650-555-1212", 532 mPhoneAccountA0.getAccountHandle(), 533 mConnectionServiceFixtureA); 534 535 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 536 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 537 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 538 539 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 540 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 541 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 542 } 543 544 public void testSingleIncomingCallRemoteDisconnect() throws Exception { 545 IdPair ids = startAndMakeActiveIncomingCall( 546 "650-555-1212", 547 mPhoneAccountA0.getAccountHandle(), 548 mConnectionServiceFixtureA); 549 550 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 551 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 552 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 553 } 554 555 public void do_testDeadlockOnOutgoingCall() throws Exception { 556 final IdPair ids = startOutgoingPhoneCall( 557 "650-555-1212", 558 mPhoneAccountA0.getAccountHandle(), 559 mConnectionServiceFixtureA); 560 rapidFire( 561 new Runnable() { 562 @Override 563 public void run() { 564 while (mCallerInfoAsyncQueryFactoryFixture.mRequests.size() > 0) { 565 mCallerInfoAsyncQueryFactoryFixture.mRequests.remove(0).reply(); 566 } 567 } 568 }, 569 new Runnable() { 570 @Override 571 public void run() { 572 try { 573 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 574 } catch (Exception e) { 575 Log.e(this, e, ""); 576 } 577 } 578 }); 579 } 580 581 public void testDeadlockOnOutgoingCall() throws Exception { 582 for (int i = 0; i < 100; i++) { 583 TelecomSystemTest test = new TelecomSystemTest(); 584 test.setContext(getContext()); 585 test.setTestContext(getTestContext()); 586 test.setName(getName()); 587 test.setUp(); 588 test.do_testDeadlockOnOutgoingCall(); 589 test.tearDown(); 590 } 591 } 592 593 public void testIncomingThenOutgoingCalls() throws Exception { 594 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 595 IdPair incoming = startAndMakeActiveIncomingCall( 596 "650-555-2323", 597 mPhoneAccountA0.getAccountHandle(), 598 mConnectionServiceFixtureA); 599 IdPair outgoing = startAndMakeActiveOutgoingCall( 600 "650-555-1212", 601 mPhoneAccountA0.getAccountHandle(), 602 mConnectionServiceFixtureA); 603 } 604 605 public void testOutgoingThenIncomingCalls() throws Exception { 606 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 607 IdPair outgoing = startAndMakeActiveOutgoingCall( 608 "650-555-1212", 609 mPhoneAccountA0.getAccountHandle(), 610 mConnectionServiceFixtureA); 611 IdPair incoming = startAndMakeActiveIncomingCall( 612 "650-555-2323", 613 mPhoneAccountA0.getAccountHandle(), 614 mConnectionServiceFixtureA); 615 } 616 617 public void testAudioManagerOperations() throws Exception { 618 AudioManager audioManager = (AudioManager) mComponentContextFixture.getTestDouble() 619 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE); 620 621 IdPair outgoing = startAndMakeActiveOutgoingCall( 622 "650-555-1212", 623 mPhoneAccountA0.getAccountHandle(), 624 mConnectionServiceFixtureA); 625 626 verify(audioManager, timeout(TEST_TIMEOUT)) 627 .requestAudioFocusForCall(anyInt(), anyInt()); 628 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 629 .setMode(AudioManager.MODE_IN_CALL); 630 631 mInCallServiceFixtureX.mInCallAdapter.mute(true); 632 verify(audioManager, timeout(TEST_TIMEOUT)) 633 .setMicrophoneMute(true); 634 mInCallServiceFixtureX.mInCallAdapter.mute(false); 635 verify(audioManager, timeout(TEST_TIMEOUT)) 636 .setMicrophoneMute(false); 637 638 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER); 639 verify(audioManager, timeout(TEST_TIMEOUT)) 640 .setSpeakerphoneOn(true); 641 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE); 642 verify(audioManager, timeout(TEST_TIMEOUT)) 643 .setSpeakerphoneOn(false); 644 645 mConnectionServiceFixtureA. 646 sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); 647 648 verify(audioManager, timeout(TEST_TIMEOUT)) 649 .abandonAudioFocusForCall(); 650 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 651 .setMode(AudioManager.MODE_NORMAL); 652 } 653 654 protected static void pause() { 655 try { 656 Thread.sleep(TEST_TIMEOUT); 657 } catch (InterruptedException e) { 658 fail(e.toString()); 659 } 660 } 661} 662