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
setUp()62     protected void setUp() throws Exception {
63         super.setUp();
64         if (mShouldTestTelecom) {
65             addRemoteConferenceCall();
66             verifyRemoteConferenceObject(mRemoteConferenceObject, mRemoteConference, mConference);
67         }
68     }
69 
testRemoteConferenceCreate()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 
testRemoteConferenceSplit()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 
testRemoteConferenceHoldAndUnhold()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 
testRemoteConferenceMergeAndSwap()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 
testRemoteConferenceDTMFTone()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 
testRemoteConferenceCallbacks_StateChange()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 
testRemoteConferenceCallbacks_Disconnect()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 
testRemoteConferenceCallbacks_ConnectionAdd()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 
testRemoteConferenceCallbacks_ConnectionRemove()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 
testRemoteConferenceCallbacks_ConnectionCapabilities()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 
testRemoteConferenceCallbacks_ConferenceableConnections()346     public void testRemoteConferenceCallbacks_ConferenceableConnections() {
347         if (!mShouldTestTelecom) {
348             return;
349         }
350         Handler handler = setupRemoteConferenceCallbacksTest();
351 
352         final InvokeCounter callbackInvoker =
353                 new InvokeCounter("testRemoteConferenceCallbacks_ConferenceableConnections");
354         RemoteConference.Callback callback;
355 
356         callback = new RemoteConference.Callback() {
357             @Override
358             public void onConferenceableConnectionsChanged(
359                     RemoteConference conference,
360                     List<RemoteConnection> conferenceableConnections) {
361                 super.onConferenceableConnectionsChanged(conference, conferenceableConnections);
362                 callbackInvoker.invoke(conference, conferenceableConnections);
363             }
364         };
365         mRemoteConferenceObject.registerCallback(callback, handler);
366         placeAndVerifyCall();
367         RemoteConnection newRemoteConnectionObject =
368             verifyConnectionForOutgoingCall(1).getRemoteConnection();
369         MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(1);
370         ArrayList<Connection> confList = new ArrayList<>();
371         confList.add(newConnection);
372         mRemoteConference.setConferenceableConnections(confList);
373         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
374         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
375         // No "equals" method in RemoteConnection
376         //assertTrue(((List<RemoteConnection>)callbackInvoker.getArgs(0)[1]).contains(
377                 //newRemoteConnectionObject));
378         mRemoteConferenceObject.unregisterCallback(callback);
379     }
380 
testRemoteConferenceCallbacks_Destroy()381     public void testRemoteConferenceCallbacks_Destroy() {
382         if (!mShouldTestTelecom) {
383             return;
384         }
385         Handler handler = setupRemoteConferenceCallbacksTest();
386 
387         final InvokeCounter callbackInvoker =
388                 new InvokeCounter("testRemoteConferenceCallbacks_Destroy");
389         RemoteConference.Callback callback;
390 
391         callback = new RemoteConference.Callback() {
392             @Override
393             public void onDestroyed(RemoteConference conference) {
394                 super.onDestroyed(conference);
395                 callbackInvoker.invoke(conference);
396             }
397         };
398         mRemoteConferenceObject.registerCallback(callback, handler);
399         mRemoteConference.destroy();
400         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
401         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
402         mRemoteConferenceObject.unregisterCallback(callback);
403     }
404 
testRemoteConferenceCallbacks_Extras()405     public void testRemoteConferenceCallbacks_Extras() {
406         if (!mShouldTestTelecom) {
407             return;
408         }
409         Handler handler = setupRemoteConferenceCallbacksTest();
410 
411         final InvokeCounter callbackInvoker =
412                 new InvokeCounter("testRemoteConferenceCallbacks_Extras");
413         RemoteConference.Callback callback;
414 
415         callback = new RemoteConference.Callback() {
416             @Override
417             public void onExtrasChanged(RemoteConference conference, Bundle extras) {
418                 super.onExtrasChanged(conference, extras);
419                 callbackInvoker.invoke(conference, extras);
420             }
421         };
422         mRemoteConferenceObject.registerCallback(callback, handler);
423         Bundle extras = new Bundle();
424         extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
425         mRemoteConference.setExtras(extras);
426         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
427         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
428         assertEquals(extras, callbackInvoker.getArgs(0)[1]);
429         mRemoteConferenceObject.unregisterCallback(callback);
430     }
431 
verifyRemoteConferenceObject(RemoteConference remoteConferenceObject, MockConference remoteConference, MockConference conference)432     private void verifyRemoteConferenceObject(RemoteConference remoteConferenceObject,
433             MockConference remoteConference, MockConference conference) {
434         assertEquals(remoteConference.getConnectionCapabilities(),
435                 remoteConferenceObject.getConnectionCapabilities());
436         assertTrue(remoteConferenceObject.getConferenceableConnections().isEmpty());
437         List<RemoteConnection> remoteConnections = new ArrayList<>();
438         for (Connection c: conference.getConnections()) {
439             remoteConnections.add(((MockConnection)c).getRemoteConnection());
440         }
441         assertEquals(remoteConnections, remoteConferenceObject.getConnections());
442         assertEquals(remoteConference.getDisconnectCause(), remoteConferenceObject.getDisconnectCause());
443         assertEquals(remoteConference.getExtras(), remoteConferenceObject.getExtras());
444     }
445 
addRemoteConnectionOutgoingCalls()446     private void addRemoteConnectionOutgoingCalls() {
447         try {
448             MockConnectionService managerConnectionService = new MockConnectionService() {
449                 @Override
450                 public Connection onCreateOutgoingConnection(
451                         PhoneAccountHandle connectionManagerPhoneAccount,
452                         ConnectionRequest request) {
453                     MockConnection connection = (MockConnection)super.onCreateOutgoingConnection(
454                             connectionManagerPhoneAccount, request);
455                     ConnectionRequest remoteRequest = new ConnectionRequest(
456                             TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
457                             request.getAddress(),
458                             request.getExtras());
459                     RemoteConnection remoteConnection =
460                             CtsConnectionService.createRemoteOutgoingConnectionToTelecom(
461                                     TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest);
462                     connection.setRemoteConnection(remoteConnection);
463                     // Modify the connection object created with local values.
464                     int capabilities = connection.getConnectionCapabilities();
465                     connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
466                     return connection;
467                 }
468                 @Override
469                 public void onConference(Connection connection1, Connection connection2) {
470                     /**
471                      * Fetch the corresponding remoteConnection objects and instantiate a remote
472                      * conference creation on the remoteConnectionService instead of this
473                      * managerConnectionService.
474                      */
475                     RemoteConnection remoteConnection1 =
476                             ((MockConnection)connection1).getRemoteConnection();
477                     RemoteConnection remoteConnection2 =
478                             ((MockConnection)connection2).getRemoteConnection();
479                     if (remoteConnection1.getConference() == null &&
480                             remoteConnection2.getConference() == null) {
481                         conferenceRemoteConnections(remoteConnection1, remoteConnection2);
482                     }
483                 }
484                 @Override
485                 public void onRemoteConferenceAdded(RemoteConference remoteConference) {
486                     /**
487                      * Now that the remote conference has been created,
488                      * let's create a local conference on this ConnectionService.
489                      */
490                     MockConference conference = new MockConference(mConnection1, mConnection2);
491                     conference.setRemoteConference(remoteConference);
492                     CtsConnectionService.addConferenceToTelecom(conference);
493                     conferences.add(conference);
494                     lock.release();
495                 }
496             };
497             /**
498              * We want the conference to be instantiated on the remoteConnectionService registered
499              * with telecom.
500              */
501             MockConnectionService remoteConnectionService= new MockConnectionService() {
502                 @Override
503                 public Connection onCreateOutgoingConnection(
504                         PhoneAccountHandle connectionManagerPhoneAccount,
505                         ConnectionRequest request) {
506                     Connection connection = super.onCreateOutgoingConnection(
507                             connectionManagerPhoneAccount,
508                             request);
509                     // Modify the connection object created with local values.
510                     int capabilities = connection.getConnectionCapabilities();
511                     connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
512                     return connection;
513                 }
514                 @Override
515                 public void onConference(Connection connection1, Connection connection2) {
516                     // Make sure that these connections are already not conferenced.
517                     if (connection1.getConference() == null &&
518                             connection2.getConference() == null) {
519                         MockConference conference = new MockConference(
520                                 (MockConnection)connection1, (MockConnection)connection2);
521                         CtsRemoteConnectionService.addConferenceToTelecom(conference);
522                         conferences.add(conference);
523                         lock.release();
524                     }
525                 }
526             };
527             setupConnectionServices(managerConnectionService, remoteConnectionService,
528                     FLAG_REGISTER | FLAG_ENABLE);
529         } catch(Exception e) {
530             fail("Error in setting up the connection services");
531         }
532 
533         placeAndVerifyCall();
534         mConnection1 = verifyConnectionForOutgoingCall(0);
535         mRemoteConnection1 = verifyConnectionForOutgoingCallOnRemoteCS(0);
536         mCall1 = mInCallCallbacks.getService().getLastCall();
537         assertCallState(mCall1, Call.STATE_DIALING);
538         mConnection1.setActive();
539         mRemoteConnection1.setActive();
540         assertCallState(mCall1, Call.STATE_ACTIVE);
541 
542         placeAndVerifyCall();
543         mConnection2 = verifyConnectionForOutgoingCall(1);
544         mRemoteConnection2 = verifyConnectionForOutgoingCallOnRemoteCS(1);
545         mCall2 = mInCallCallbacks.getService().getLastCall();
546         assertCallState(mCall2, Call.STATE_DIALING);
547         mConnection2.setActive();
548         mRemoteConnection2.setActive();
549         assertCallState(mCall2, Call.STATE_ACTIVE);
550 
551         setAndVerifyConferenceablesForOutgoingConnection(0);
552         setAndVerifyConferenceablesForOutgoingConnection(1);
553         setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(0);
554         setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(1);
555     }
556 
addRemoteConferenceCall()557     private void addRemoteConferenceCall() {
558         addRemoteConnectionOutgoingCalls();
559         /**
560          * We've 2 connections on the local connectionService which have 2 corresponding
561          * connections on the remoteConnectionService controlled via 2 RemoteConnection objects
562          * on the connectionService. We now create a conference on the local two connections
563          * which triggers a creation of conference on the remoteConnectionService via the
564          * RemoteConference object.
565          */
566 
567         addConferenceCall(mCall1, mCall2);
568         mConference = verifyConferenceForOutgoingCall();
569         mRemoteConference = verifyConferenceForOutgoingCallOnRemoteCS();
570         mRemoteConferenceObject = mConference.getRemoteConference();
571         mRemoteConnection1 = (MockConnection)mRemoteConference.getConnections().get(0);
572         mRemoteConnection2 = (MockConnection)mRemoteConference.getConnections().get(1);
573     }
574 
setupRemoteConferenceCallbacksTest()575     private Handler setupRemoteConferenceCallbacksTest() {
576         final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
577         assertCallState(confCall, Call.STATE_ACTIVE);
578 
579         // Create a looper thread for the callbacks.
580         HandlerThread workerThread = new HandlerThread("CallbackThread");
581         workerThread.start();
582         Handler handler = new Handler(workerThread.getLooper());
583         return handler;
584     }
585 }
586