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.os.Bundle; 22 import android.os.Handler; 23 import android.os.HandlerThread; 24 import android.telecom.Call; 25 import android.telecom.Connection; 26 import android.telecom.ConnectionRequest; 27 import android.telecom.DisconnectCause; 28 import android.telecom.PhoneAccountHandle; 29 import android.telecom.RemoteConference; 30 import android.telecom.RemoteConnection; 31 import android.telecom.TelecomManager; 32 33 import java.util.ArrayList; 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 Remote Conferences. 39 * We make 2 connections on the {@link CtsConnectionService} & we create 2 connections on the 40 * {@link CtsRemoteConnectionService} via the {@link RemoteConnection} object. We store this 41 * corresponding RemoteConnection object on the connections to plumb the modifications on 42 * the connections in {@link CtsConnectionService} to the connections on 43 * {@link CtsRemoteConnectionService}. Then we create a remote conference on the 44 * {@link CtsRemoteConnectionService} and control it via the {@link RemoteConference} 45 * object. The onConference method on the managerConnectionService will initiate a remote conference 46 * creation on the remoteConnectionService and once that is completed, we create a local conference 47 * on the managerConnectionService. 48 */ 49 public class RemoteConferenceTest extends BaseRemoteTelecomTest { 50 51 public static final int CONF_CAPABILITIES = Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE | 52 Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE | Connection.CAPABILITY_HOLD | 53 Connection.CAPABILITY_MERGE_CONFERENCE | Connection.CAPABILITY_SWAP_CONFERENCE; 54 55 MockConnection mConnection1, mConnection2; 56 MockConnection mRemoteConnection1, mRemoteConnection2; 57 Call mCall1, mCall2; 58 MockConference mConference, mRemoteConference; 59 RemoteConference mRemoteConferenceObject; 60 61 @Override 62 protected void setUp() throws Exception { 63 super.setUp(); 64 if (mShouldTestTelecom) { 65 addRemoteConferenceCall(); 66 verifyRemoteConferenceObject(mRemoteConferenceObject, mRemoteConference, mConference); 67 } 68 } 69 70 public void testRemoteConferenceCreate() { 71 if (!mShouldTestTelecom) { 72 return; 73 } 74 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 75 assertCallState(confCall, Call.STATE_ACTIVE); 76 77 if (mCall1.getParent() != confCall || mCall2.getParent() != confCall) { 78 fail("The 2 participating calls should contain the conference call as its parent"); 79 } 80 if (!(confCall.getChildren().contains(mCall1) && confCall.getChildren().contains(mCall2))) { 81 fail("The conference call should contain the 2 participating calls as its children"); 82 } 83 84 assertConnectionState(mConnection1, Connection.STATE_ACTIVE); 85 assertConnectionState(mConnection2, Connection.STATE_ACTIVE); 86 assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE); 87 assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE); 88 assertConferenceState(mConference, Connection.STATE_ACTIVE); 89 assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE); 90 assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE); 91 } 92 93 public void testRemoteConferenceSplit() { 94 if (!mShouldTestTelecom) { 95 return; 96 } 97 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 98 assertCallState(confCall, Call.STATE_ACTIVE); 99 100 if (!(mCall1.getParent() == confCall) && (confCall.getChildren().contains(mCall1))) { 101 fail("Call 1 not conferenced"); 102 } 103 assertTrue(mConference.getConnections().contains(mConnection1)); 104 assertTrue(mRemoteConference.getConnections().contains(mRemoteConnection1)); 105 106 splitFromConferenceCall(mCall1); 107 108 if ((mCall1.getParent() == confCall) || (confCall.getChildren().contains(mCall1))) { 109 fail("Call 1 should not be still conferenced"); 110 } 111 assertFalse(mConference.getConnections().contains(mConnection1)); 112 assertFalse(mRemoteConference.getConnections().contains(mRemoteConnection1)); 113 } 114 115 public void testRemoteConferenceHoldAndUnhold() { 116 if (!mShouldTestTelecom) { 117 return; 118 } 119 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 120 assertCallState(confCall, Call.STATE_ACTIVE); 121 122 confCall.hold(); 123 assertCallState(confCall, Call.STATE_HOLDING); 124 assertCallState(mCall1, Call.STATE_HOLDING); 125 assertCallState(mCall2, Call.STATE_HOLDING); 126 assertConnectionState(mConnection1, Connection.STATE_HOLDING); 127 assertConnectionState(mConnection2, Connection.STATE_HOLDING); 128 assertConnectionState(mRemoteConnection1, Connection.STATE_HOLDING); 129 assertConnectionState(mRemoteConnection2, Connection.STATE_HOLDING); 130 assertConferenceState(mConference, Connection.STATE_HOLDING); 131 assertConferenceState(mRemoteConference, Connection.STATE_HOLDING); 132 assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_HOLDING); 133 134 confCall.unhold(); 135 assertCallState(confCall, Call.STATE_ACTIVE); 136 assertCallState(mCall1, Call.STATE_ACTIVE); 137 assertCallState(mCall2, Call.STATE_ACTIVE); 138 assertConnectionState(mConnection1, Connection.STATE_ACTIVE); 139 assertConnectionState(mConnection2, Connection.STATE_ACTIVE); 140 assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE); 141 assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE); 142 assertConferenceState(mConference, Connection.STATE_ACTIVE); 143 assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE); 144 assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE); 145 } 146 147 public void testRemoteConferenceMergeAndSwap() { 148 if (!mShouldTestTelecom) { 149 return; 150 } 151 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 152 assertCallState(confCall, Call.STATE_ACTIVE); 153 154 confCall.mergeConference(); 155 assertCallDisplayName(mCall1, TestUtils.MERGE_CALLER_NAME); 156 assertCallDisplayName(mCall2, TestUtils.MERGE_CALLER_NAME); 157 assertConnectionCallDisplayName(mConnection1, 158 TestUtils.MERGE_CALLER_NAME); 159 assertConnectionCallDisplayName(mConnection2, 160 TestUtils.MERGE_CALLER_NAME); 161 assertConnectionCallDisplayName(mRemoteConnection1, 162 TestUtils.MERGE_CALLER_NAME); 163 assertConnectionCallDisplayName(mRemoteConnection2, 164 TestUtils.MERGE_CALLER_NAME); 165 166 confCall.swapConference(); 167 assertCallDisplayName(mCall1, TestUtils.SWAP_CALLER_NAME); 168 assertCallDisplayName(mCall2, TestUtils.SWAP_CALLER_NAME); 169 assertConnectionCallDisplayName(mConnection1, 170 TestUtils.SWAP_CALLER_NAME); 171 assertConnectionCallDisplayName(mConnection2, 172 TestUtils.SWAP_CALLER_NAME); 173 assertConnectionCallDisplayName(mRemoteConnection1, 174 TestUtils.SWAP_CALLER_NAME); 175 assertConnectionCallDisplayName(mRemoteConnection2, 176 TestUtils.SWAP_CALLER_NAME); 177 } 178 179 public void testRemoteConferenceDTMFTone() { 180 if (!mShouldTestTelecom) { 181 return; 182 } 183 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 184 assertCallState(confCall, Call.STATE_ACTIVE); 185 186 assertTrue(mConference.getDtmfString().isEmpty()); 187 assertTrue(mRemoteConference.getDtmfString().isEmpty()); 188 confCall.playDtmfTone('1'); 189 assertDtmfString(mConference, "1"); 190 assertDtmfString(mRemoteConference, "1"); 191 confCall.stopDtmfTone(); 192 assertDtmfString(mConference, "1."); 193 assertDtmfString(mRemoteConference, "1."); 194 confCall.playDtmfTone('3'); 195 assertDtmfString(mConference, "1.3"); 196 assertDtmfString(mRemoteConference, "1.3"); 197 confCall.stopDtmfTone(); 198 assertDtmfString(mConference, "1.3."); 199 assertDtmfString(mRemoteConference, "1.3."); 200 } 201 202 public void testRemoteConferenceCallbacks_StateChange() { 203 if (!mShouldTestTelecom) { 204 return; 205 } 206 Handler handler = setupRemoteConferenceCallbacksTest(); 207 208 final InvokeCounter callbackInvoker = 209 new InvokeCounter("testRemoteConferenceCallbacks_StateChange"); 210 RemoteConference.Callback callback; 211 212 callback = new RemoteConference.Callback() { 213 @Override 214 public void onStateChanged(RemoteConference conference, int oldState, int newState) { 215 super.onStateChanged(conference, oldState, newState); 216 callbackInvoker.invoke(conference, oldState, newState); 217 } 218 }; 219 mRemoteConferenceObject.registerCallback(callback, handler); 220 mRemoteConference.setOnHold(); 221 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 222 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 223 assertEquals(Connection.STATE_ACTIVE, callbackInvoker.getArgs(0)[1]); 224 assertEquals(Connection.STATE_HOLDING, callbackInvoker.getArgs(0)[2]); 225 mRemoteConferenceObject.unregisterCallback(callback); 226 } 227 228 public void testRemoteConferenceCallbacks_Disconnect() { 229 if (!mShouldTestTelecom) { 230 return; 231 } 232 Handler handler = setupRemoteConferenceCallbacksTest(); 233 234 final InvokeCounter callbackInvoker = 235 new InvokeCounter("testRemoteConferenceCallbacks_Disconnect"); 236 RemoteConference.Callback callback; 237 238 callback = new RemoteConference.Callback() { 239 @Override 240 public void onDisconnected(RemoteConference conference, 241 DisconnectCause disconnectCause) { 242 super.onDisconnected(conference, disconnectCause); 243 callbackInvoker.invoke(conference, disconnectCause); 244 } 245 }; 246 mRemoteConferenceObject.registerCallback(callback, handler); 247 DisconnectCause cause = new DisconnectCause(DisconnectCause.LOCAL); 248 mRemoteConference.setDisconnected(cause); 249 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 250 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 251 assertEquals(cause, callbackInvoker.getArgs(0)[1]); 252 mRemoteConferenceObject.unregisterCallback(callback); 253 } 254 255 public void testRemoteConferenceCallbacks_ConnectionAdd() { 256 if (!mShouldTestTelecom) { 257 return; 258 } 259 Handler handler = setupRemoteConferenceCallbacksTest(); 260 261 final InvokeCounter callbackInvoker = 262 new InvokeCounter("testRemoteConferenceCallbacks_ConnectionAdd"); 263 RemoteConference.Callback callback; 264 265 callback = new RemoteConference.Callback() { 266 @Override 267 public void onConnectionAdded(RemoteConference conference, 268 RemoteConnection connection) { 269 super.onConnectionAdded(conference, connection); 270 callbackInvoker.invoke(conference, connection); 271 } 272 }; 273 mRemoteConferenceObject.registerCallback(callback, handler); 274 placeAndVerifyCall(); 275 RemoteConnection newRemoteConnectionObject = 276 verifyConnectionForOutgoingCall(1).getRemoteConnection(); 277 MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(2); 278 mRemoteConference.addConnection(newConnection); 279 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 280 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 281 // No "equals" method in RemoteConnection 282 //assertEquals(newRemoteConnectionObject, callbackInvoker.getArgs(0)[1]); 283 mRemoteConferenceObject.unregisterCallback(callback); 284 } 285 286 public void testRemoteConferenceCallbacks_ConnectionRemove() { 287 if (!mShouldTestTelecom) { 288 return; 289 } 290 Handler handler = setupRemoteConferenceCallbacksTest(); 291 292 final InvokeCounter callbackInvoker = 293 new InvokeCounter("testRemoteConferenceCallbacks_ConnectionRemove"); 294 RemoteConference.Callback callback; 295 296 callback = new RemoteConference.Callback() { 297 @Override 298 public void onConnectionRemoved(RemoteConference conference, 299 RemoteConnection connection) { 300 super.onConnectionRemoved(conference, connection); 301 callbackInvoker.invoke(conference, connection); 302 } 303 }; 304 mRemoteConferenceObject.registerCallback(callback, handler); 305 placeAndVerifyCall(); 306 RemoteConnection newRemoteConnectionObject = 307 verifyConnectionForOutgoingCall(1).getRemoteConnection(); 308 MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(2); 309 mRemoteConference.addConnection(newConnection); 310 mRemoteConference.removeConnection(newConnection); 311 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 312 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 313 //assertEquals(newRemoteConnectionObject, callbackInvoker.getArgs(0)[1]); 314 // No "equals" method in RemoteConnection 315 mRemoteConferenceObject.unregisterCallback(callback); 316 } 317 318 public void testRemoteConferenceCallbacks_ConnectionCapabilities() { 319 if (!mShouldTestTelecom) { 320 return; 321 } 322 Handler handler = setupRemoteConferenceCallbacksTest(); 323 324 final InvokeCounter callbackInvoker = 325 new InvokeCounter("testRemoteConferenceCallbacks_ConnectionCapabilities"); 326 RemoteConference.Callback callback; 327 328 callback = new RemoteConference.Callback() { 329 @Override 330 public void onConnectionCapabilitiesChanged( 331 RemoteConference conference, 332 int connectionCapabilities) { 333 super.onConnectionCapabilitiesChanged(conference, connectionCapabilities); 334 callbackInvoker.invoke(conference, connectionCapabilities); 335 } 336 }; 337 mRemoteConferenceObject.registerCallback(callback, handler); 338 int capabilities = mRemoteConference.getConnectionCapabilities() | Connection.CAPABILITY_MUTE; 339 mRemoteConference.setConnectionCapabilities(capabilities); 340 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 341 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 342 assertEquals(capabilities, callbackInvoker.getArgs(0)[1]); 343 mRemoteConferenceObject.unregisterCallback(callback); 344 } 345 346 public void testRemoteConferenceCallbacks_ConnectionProperties() { 347 if (!mShouldTestTelecom) { 348 return; 349 } 350 Handler handler = setupRemoteConferenceCallbacksTest(); 351 352 final InvokeCounter callbackInvoker = 353 new InvokeCounter("testRemoteConferenceCallbacks_ConnectionProperties"); 354 RemoteConference.Callback callback; 355 356 callback = new RemoteConference.Callback() { 357 @Override 358 public void onConnectionPropertiesChanged( 359 RemoteConference conference, 360 int connectionProperties) { 361 super.onConnectionPropertiesChanged(conference, connectionProperties); 362 callbackInvoker.invoke(conference, connectionProperties); 363 } 364 }; 365 mRemoteConferenceObject.registerCallback(callback, handler); 366 int properties = mRemoteConference.getConnectionCapabilities() 367 | Connection.PROPERTY_IS_EXTERNAL_CALL; 368 mRemoteConference.setConnectionProperties(properties); 369 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 370 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 371 assertEquals(properties, callbackInvoker.getArgs(0)[1]); 372 mRemoteConferenceObject.unregisterCallback(callback); 373 } 374 375 public void testRemoteConferenceCallbacks_ConferenceableConnections() { 376 if (!mShouldTestTelecom) { 377 return; 378 } 379 Handler handler = setupRemoteConferenceCallbacksTest(); 380 381 final InvokeCounter callbackInvoker = 382 new InvokeCounter("testRemoteConferenceCallbacks_ConferenceableConnections"); 383 RemoteConference.Callback callback; 384 385 callback = new RemoteConference.Callback() { 386 @Override 387 public void onConferenceableConnectionsChanged( 388 RemoteConference conference, 389 List<RemoteConnection> conferenceableConnections) { 390 super.onConferenceableConnectionsChanged(conference, conferenceableConnections); 391 callbackInvoker.invoke(conference, conferenceableConnections); 392 } 393 }; 394 mRemoteConferenceObject.registerCallback(callback, handler); 395 placeAndVerifyCall(); 396 RemoteConnection newRemoteConnectionObject = 397 verifyConnectionForOutgoingCall(1).getRemoteConnection(); 398 MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(1); 399 ArrayList<Connection> confList = new ArrayList<>(); 400 confList.add(newConnection); 401 mRemoteConference.setConferenceableConnections(confList); 402 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 403 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 404 // No "equals" method in RemoteConnection 405 //assertTrue(((List<RemoteConnection>)callbackInvoker.getArgs(0)[1]).contains( 406 //newRemoteConnectionObject)); 407 mRemoteConferenceObject.unregisterCallback(callback); 408 } 409 410 public void testRemoteConferenceCallbacks_Destroy() { 411 if (!mShouldTestTelecom) { 412 return; 413 } 414 Handler handler = setupRemoteConferenceCallbacksTest(); 415 416 final InvokeCounter callbackInvoker = 417 new InvokeCounter("testRemoteConferenceCallbacks_Destroy"); 418 RemoteConference.Callback callback; 419 420 callback = new RemoteConference.Callback() { 421 @Override 422 public void onDestroyed(RemoteConference conference) { 423 super.onDestroyed(conference); 424 callbackInvoker.invoke(conference); 425 } 426 }; 427 mRemoteConferenceObject.registerCallback(callback, handler); 428 mRemoteConference.destroy(); 429 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 430 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 431 mRemoteConferenceObject.unregisterCallback(callback); 432 } 433 434 435 public void testRemoteConferenceCallbacks_Extras() { 436 if (!mShouldTestTelecom) { 437 return; 438 } 439 Handler handler = setupRemoteConferenceCallbacksTest(); 440 441 final InvokeCounter callbackInvoker = 442 new InvokeCounter("testRemoteConferenceCallbacks_Extras"); 443 RemoteConference.Callback callback; 444 445 callback = new RemoteConference.Callback() { 446 @Override 447 public void onExtrasChanged(RemoteConference conference, Bundle extras) { 448 super.onExtrasChanged(conference, extras); 449 callbackInvoker.invoke(conference, extras); 450 } 451 }; 452 mRemoteConferenceObject.registerCallback(callback, handler); 453 Bundle extras = new Bundle(); 454 extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test"); 455 mRemoteConference.setExtras(extras); 456 callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS); 457 assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]); 458 assertTrue(((Bundle) callbackInvoker.getArgs(0)[1]).containsKey( 459 TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE)); 460 mRemoteConferenceObject.unregisterCallback(callback); 461 } 462 463 private void verifyRemoteConferenceObject(RemoteConference remoteConferenceObject, 464 MockConference remoteConference, MockConference conference) { 465 assertEquals(remoteConference.getConnectionCapabilities(), 466 remoteConferenceObject.getConnectionCapabilities()); 467 assertTrue(remoteConferenceObject.getConferenceableConnections().isEmpty()); 468 List<RemoteConnection> remoteConnections = new ArrayList<>(); 469 for (Connection c: conference.getConnections()) { 470 remoteConnections.add(((MockConnection)c).getRemoteConnection()); 471 } 472 assertEquals(remoteConnections, remoteConferenceObject.getConnections()); 473 assertEquals(remoteConference.getDisconnectCause(), 474 remoteConferenceObject.getDisconnectCause()); 475 assertTrue(areBundlesEqual(remoteConferenceObject.getExtras(), conference.getExtras())); 476 } 477 478 private void addRemoteConnectionOutgoingCalls() { 479 try { 480 MockConnectionService managerConnectionService = new MockConnectionService() { 481 @Override 482 public Connection onCreateOutgoingConnection( 483 PhoneAccountHandle connectionManagerPhoneAccount, 484 ConnectionRequest request) { 485 MockConnection connection = (MockConnection)super.onCreateOutgoingConnection( 486 connectionManagerPhoneAccount, request); 487 ConnectionRequest remoteRequest = new ConnectionRequest( 488 TEST_REMOTE_PHONE_ACCOUNT_HANDLE, 489 request.getAddress(), 490 request.getExtras()); 491 RemoteConnection remoteConnection = 492 CtsConnectionService.createRemoteOutgoingConnectionToTelecom( 493 TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest); 494 connection.setRemoteConnection(remoteConnection); 495 // Modify the connection object created with local values. 496 int capabilities = connection.getConnectionCapabilities(); 497 connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES); 498 return connection; 499 } 500 @Override 501 public void onConference(Connection connection1, Connection connection2) { 502 /** 503 * Fetch the corresponding remoteConnection objects and instantiate a remote 504 * conference creation on the remoteConnectionService instead of this 505 * managerConnectionService. 506 */ 507 RemoteConnection remoteConnection1 = 508 ((MockConnection)connection1).getRemoteConnection(); 509 RemoteConnection remoteConnection2 = 510 ((MockConnection)connection2).getRemoteConnection(); 511 if (remoteConnection1.getConference() == null && 512 remoteConnection2.getConference() == null) { 513 conferenceRemoteConnections(remoteConnection1, remoteConnection2); 514 } 515 516 if (connection1.getState() == Connection.STATE_HOLDING){ 517 connection1.setActive(); 518 } 519 if(connection2.getState() == Connection.STATE_HOLDING){ 520 connection2.setActive(); 521 } 522 } 523 @Override 524 public void onRemoteConferenceAdded(RemoteConference remoteConference) { 525 /** 526 * Now that the remote conference has been created, 527 * let's create a local conference on this ConnectionService. 528 */ 529 MockConference conference = new MockConference(mConnection1, mConnection2); 530 conference.setRemoteConference(remoteConference); 531 CtsConnectionService.addConferenceToTelecom(conference); 532 conferences.add(conference); 533 lock.release(); 534 } 535 }; 536 /** 537 * We want the conference to be instantiated on the remoteConnectionService registered 538 * with telecom. 539 */ 540 MockConnectionService remoteConnectionService= new MockConnectionService() { 541 @Override 542 public Connection onCreateOutgoingConnection( 543 PhoneAccountHandle connectionManagerPhoneAccount, 544 ConnectionRequest request) { 545 Connection connection = super.onCreateOutgoingConnection( 546 connectionManagerPhoneAccount, 547 request); 548 // Modify the connection object created with local values. 549 int capabilities = connection.getConnectionCapabilities(); 550 connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES); 551 return connection; 552 } 553 @Override 554 public void onConference(Connection connection1, Connection connection2) { 555 // Make sure that these connections are already not conferenced. 556 if (connection1.getConference() == null && 557 connection2.getConference() == null) { 558 MockConference conference = new MockConference( 559 (MockConnection)connection1, (MockConnection)connection2); 560 CtsRemoteConnectionService.addConferenceToTelecom(conference); 561 conferences.add(conference); 562 563 if (connection1.getState() == Connection.STATE_HOLDING){ 564 connection1.setActive(); 565 } 566 if(connection2.getState() == Connection.STATE_HOLDING){ 567 connection2.setActive(); 568 } 569 570 lock.release(); 571 } 572 } 573 }; 574 setupConnectionServices(managerConnectionService, remoteConnectionService, 575 FLAG_REGISTER | FLAG_ENABLE); 576 } catch(Exception e) { 577 fail("Error in setting up the connection services: " + e.toString()); 578 } 579 580 placeAndVerifyCall(); 581 mConnection1 = verifyConnectionForOutgoingCall(0); 582 mRemoteConnection1 = verifyConnectionForOutgoingCallOnRemoteCS(0); 583 mCall1 = mInCallCallbacks.getService().getLastCall(); 584 assertCallState(mCall1, Call.STATE_DIALING); 585 mConnection1.setActive(); 586 mRemoteConnection1.setActive(); 587 assertCallState(mCall1, Call.STATE_ACTIVE); 588 589 placeAndVerifyCall(); 590 mConnection2 = verifyConnectionForOutgoingCall(1); 591 mRemoteConnection2 = verifyConnectionForOutgoingCallOnRemoteCS(1); 592 mCall2 = mInCallCallbacks.getService().getLastCall(); 593 assertCallState(mCall2, Call.STATE_DIALING); 594 mConnection2.setActive(); 595 mRemoteConnection2.setActive(); 596 assertCallState(mCall2, Call.STATE_ACTIVE); 597 598 setAndVerifyConferenceablesForOutgoingConnection(0); 599 setAndVerifyConferenceablesForOutgoingConnection(1); 600 setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(0); 601 setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(1); 602 } 603 604 private void addRemoteConferenceCall() { 605 addRemoteConnectionOutgoingCalls(); 606 /** 607 * We've 2 connections on the local connectionService which have 2 corresponding 608 * connections on the remoteConnectionService controlled via 2 RemoteConnection objects 609 * on the connectionService. We now create a conference on the local two connections 610 * which triggers a creation of conference on the remoteConnectionService via the 611 * RemoteConference object. 612 */ 613 614 addConferenceCall(mCall1, mCall2); 615 mConference = verifyConferenceForOutgoingCall(); 616 mRemoteConference = verifyConferenceForOutgoingCallOnRemoteCS(); 617 mRemoteConferenceObject = mConference.getRemoteConference(); 618 mRemoteConnection1 = (MockConnection)mRemoteConference.getConnections().get(0); 619 mRemoteConnection2 = (MockConnection)mRemoteConference.getConnections().get(1); 620 } 621 622 private Handler setupRemoteConferenceCallbacksTest() { 623 final Call confCall = mInCallCallbacks.getService().getLastConferenceCall(); 624 assertCallState(confCall, Call.STATE_ACTIVE); 625 626 // Create a looper thread for the callbacks. 627 HandlerThread workerThread = new HandlerThread("CallbackThread"); 628 workerThread.start(); 629 Handler handler = new Handler(workerThread.getLooper()); 630 return handler; 631 } 632 } 633