Home | History | Annotate | Download | only in cts
      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.telecom.Call;
     23 import android.telecom.Conference;
     24 import android.telecom.Connection;
     25 import android.telecom.ConnectionRequest;
     26 import android.telecom.DisconnectCause;
     27 import android.telecom.PhoneAccount;
     28 import android.telecom.PhoneAccountHandle;
     29 import android.telecom.StatusHints;
     30 import android.telecom.TelecomManager;
     31 import android.telecom.VideoProfile;
     32 import android.util.Log;
     33 
     34 import java.util.ArrayList;
     35 import java.util.Arrays;
     36 import java.util.List;
     37 
     38 /**
     39  * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
     40  * verify the functionality of Call Conferencing.
     41  */
     42 public class ConferenceTest extends BaseTelecomTestWithMockServices {
     43 
     44     private static final String TEST_EXTRA_KEY_1 = "android.telecom.test.KEY1";
     45     private static final String TEST_EXTRA_KEY_2 = "android.telecom.test.KEY2";
     46     private static final String TEST_EXTRA_VALUE_1 = "test";
     47     private static final int TEST_EXTRA_VALUE_2 = 42;
     48 
     49     public static final int CONF_CAPABILITIES = Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE |
     50             Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE | Connection.CAPABILITY_HOLD |
     51             Connection.CAPABILITY_MERGE_CONFERENCE | Connection.CAPABILITY_SWAP_CONFERENCE;
     52 
     53     private Call mCall1, mCall2;
     54     private MockConnection mConnection1, mConnection2;
     55     MockInCallService mInCallService;
     56     Conference mConferenceObject;
     57     MockConference mConferenceVerficationObject;
     58 
     59     @Override
     60     protected void setUp() throws Exception {
     61         super.setUp();
     62         if (mShouldTestTelecom) {
     63             addOutgoingCalls();
     64             addConferenceCall(mCall1, mCall2);
     65             mConferenceVerficationObject = verifyConferenceForOutgoingCall();
     66             // Use vanilla conference object so that the CTS coverage tool detects the usage.
     67             mConferenceObject = mConferenceVerficationObject;
     68             verifyConferenceObject(mConferenceObject, mConnection1, mConnection2);
     69         }
     70     }
     71 
     72     public void testConferenceCreate() {
     73         if (!mShouldTestTelecom) {
     74             return;
     75         }
     76         final Call conf = mInCallService.getLastConferenceCall();
     77         assertCallState(conf, Call.STATE_ACTIVE);
     78 
     79         if (mCall1.getParent() != conf || mCall2.getParent() != conf) {
     80             fail("The 2 participating calls should contain the conference call as its parent");
     81         }
     82         if (!(conf.getChildren().contains(mCall1) && conf.getChildren().contains(mCall2))) {
     83             fail("The conference call should contain the 2 participating calls as its children");
     84         }
     85         assertTrue(mConferenceObject.getConnections().contains(mConnection1));
     86 
     87         assertConnectionState(mConferenceObject.getConnections().get(0), Connection.STATE_ACTIVE);
     88         assertConnectionState(mConferenceObject.getConnections().get(1), Connection.STATE_ACTIVE);
     89         assertConferenceState(mConferenceObject, Connection.STATE_ACTIVE);
     90     }
     91 
     92     public void testConferenceSplit() {
     93         if (!mShouldTestTelecom) {
     94             return;
     95         }
     96         final Call conf = mInCallService.getLastConferenceCall();
     97         assertCallState(conf, Call.STATE_ACTIVE);
     98 
     99         if (!(mCall1.getParent() == conf) && (conf.getChildren().contains(mCall1))) {
    100             fail("Call 1 not conferenced");
    101         }
    102         assertTrue(mConferenceObject.getConnections().contains(mConnection1));
    103 
    104         splitFromConferenceCall(mCall1);
    105 
    106         if ((mCall1.getParent() == conf) || (conf.getChildren().contains(mCall1))) {
    107             fail("Call 1 should not be still conferenced");
    108         }
    109         assertFalse(mConferenceObject.getConnections().contains(mConnection1));
    110     }
    111 
    112     public void testConferenceHoldAndUnhold() {
    113         if (!mShouldTestTelecom) {
    114             return;
    115         }
    116         final Call conf = mInCallService.getLastConferenceCall();
    117         assertCallState(conf, Call.STATE_ACTIVE);
    118 
    119         conf.hold();
    120         assertCallState(conf, Call.STATE_HOLDING);
    121         assertCallState(mCall1, Call.STATE_HOLDING);
    122         assertCallState(mCall2, Call.STATE_HOLDING);
    123 
    124         conf.unhold();
    125         assertCallState(conf, Call.STATE_ACTIVE);
    126         assertCallState(mCall1, Call.STATE_ACTIVE);
    127         assertCallState(mCall2, Call.STATE_ACTIVE);
    128     }
    129 
    130     public void testConferenceMergeAndSwap() {
    131         if (!mShouldTestTelecom) {
    132             return;
    133         }
    134         final Call conf = mInCallService.getLastConferenceCall();
    135         assertCallState(conf, Call.STATE_ACTIVE);
    136 
    137         conf.mergeConference();
    138         assertCallDisplayName(mCall1, TestUtils.MERGE_CALLER_NAME);
    139         assertCallDisplayName(mCall2, TestUtils.MERGE_CALLER_NAME);
    140         assertConnectionCallDisplayName(mConferenceObject.getConnections().get(0),
    141                 TestUtils.MERGE_CALLER_NAME);
    142         assertConnectionCallDisplayName(mConferenceObject.getConnections().get(1),
    143                 TestUtils.MERGE_CALLER_NAME);
    144 
    145         conf.swapConference();
    146         assertCallDisplayName(mCall1, TestUtils.SWAP_CALLER_NAME);
    147         assertCallDisplayName(mCall2, TestUtils.SWAP_CALLER_NAME);
    148         assertConnectionCallDisplayName(mConferenceObject.getConnections().get(0),
    149                 TestUtils.SWAP_CALLER_NAME);
    150         assertConnectionCallDisplayName(mConferenceObject.getConnections().get(1),
    151                 TestUtils.SWAP_CALLER_NAME);
    152 
    153     }
    154 
    155     public void testConferenceSetters() {
    156         if (!mShouldTestTelecom) {
    157             return;
    158         }
    159         final Call conf = mInCallService.getLastConferenceCall();
    160         assertCallState(conf, Call.STATE_ACTIVE);
    161 
    162         placeAndVerifyCall();
    163         MockConnection newConnection = verifyConnectionForOutgoingCall(2);
    164         final Call newCall = mInCallService.getLastCall();
    165 
    166         ArrayList<Connection> connectionList = new ArrayList<>();
    167         connectionList.add(newConnection);
    168         ArrayList<Call> callList = new ArrayList<>();
    169         callList.add(newCall);
    170 
    171         assertFalse(conf.getDetails().can(Call.Details.CAPABILITY_MUTE));
    172         int capabilities = mConferenceObject.getConnectionCapabilities() |
    173                 Connection.CAPABILITY_MUTE;
    174         mConferenceObject.setConnectionCapabilities(capabilities);
    175         assertCallCapability(conf, Call.Details.CAPABILITY_MUTE);
    176 
    177         assertFalse(conf.getConferenceableCalls().contains(newCall));
    178         mConferenceObject.setConferenceableConnections(connectionList);
    179         assertCallConferenceableList(conf, callList);
    180 
    181         // Consumed internally in Telecom; no verifiable manner to see the end point of this data
    182         // through public APIs.
    183         mConferenceObject.setConnectionTime(0);
    184         mConferenceObject.setConnectionStartElapsedRealTime(0);
    185 
    186         Bundle extras = new Bundle();
    187         extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
    188         assertFalse(conf.getDetails().getExtras().containsKey(
    189                 TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE));
    190         mConferenceObject.setExtras(extras);
    191         assertCallExtras(conf, TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
    192 
    193         StatusHints hints = new StatusHints("Test", null, null);
    194         assertNull(conf.getDetails().getStatusHints());
    195         mConferenceObject.setStatusHints(hints);
    196         assertCallStatusHints(conf, hints);
    197 
    198         assertFalse(conf.getChildren().contains(newCall));
    199         mConferenceObject.addConnection(newConnection);
    200         assertCallChildrenContains(conf, newCall, true);
    201 
    202         assertTrue(conf.getChildren().contains(newCall));
    203         mConferenceObject.removeConnection(newConnection);
    204         assertCallChildrenContains(conf, newCall, false);
    205 
    206         assertVideoState(conf, VideoProfile.STATE_AUDIO_ONLY);
    207         final MockVideoProvider mockVideoProvider = mConnection1.getMockVideoProvider();
    208         mConferenceObject.setVideoProvider(mConnection1, mockVideoProvider);
    209         mConferenceObject.setVideoState(mConnection1, VideoProfile.STATE_BIDIRECTIONAL);
    210         assertVideoState(conf, VideoProfile.STATE_BIDIRECTIONAL);
    211 
    212         // Dialing state is unsupported for conference calls. so, the state remains active.
    213         mConferenceObject.setDialing();
    214         // just assert call state is not dialing, the state remains as previous one.
    215         assertTrue(conf.getState() != Call.STATE_DIALING);
    216 
    217         mConferenceObject.setOnHold();
    218         assertCallState(conf, Call.STATE_HOLDING);
    219 
    220         mConferenceObject.setActive();
    221         assertCallState(conf, Call.STATE_ACTIVE);
    222 
    223         mConferenceObject.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
    224         assertCallState(conf, Call.STATE_DISCONNECTED);
    225 
    226         // Destroy state is unsupported for conference calls. so, the state remains active.
    227         mConferenceObject.destroy();
    228         assertCallState(conf, Call.STATE_DISCONNECTED);
    229     }
    230 
    231     /**
    232      * Tests end to end propagation of the {@link Conference} properties to the associated
    233      * {@link Call}.
    234      */
    235     public void testConferenceProperties() {
    236         if (!mShouldTestTelecom) {
    237             return;
    238         }
    239         final Call conf = mInCallService.getLastConferenceCall();
    240         assertCallState(conf, Call.STATE_ACTIVE);
    241 
    242         int properties  = mConferenceObject.getConnectionProperties();
    243         properties |= Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY;
    244 
    245         mConferenceObject.setConnectionProperties(properties);
    246 
    247         // Wait for 2nd properties change; the first will be when the conference is marked with
    248         // Call.Details.PROPERTY_CONFERENCE.
    249         assertCallProperties(conf, Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY);
    250         assertTrue(conf.getDetails().hasProperty(Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY));
    251     }
    252 
    253     /**
    254      * Verifies {@link Conference#putExtras(Bundle)} calls are propagated to
    255      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    256      */
    257     public void testConferencePutExtras() {
    258         if (!mShouldTestTelecom) {
    259             return;
    260         }
    261         final Call conf = mInCallService.getLastConferenceCall();
    262         assertCallState(conf, Call.STATE_ACTIVE);
    263 
    264         Bundle extras = new Bundle();
    265         extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
    266         extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
    267         int startInvokeCount = mOnExtrasChangedCounter.getInvokeCount();
    268         mConferenceObject.putExtras(extras);
    269         mOnExtrasChangedCounter.waitForCount(startInvokeCount + 1,
    270                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    271 
    272         Bundle changedExtras = conf.getDetails().getExtras();
    273         assertTrue(changedExtras.containsKey(TEST_EXTRA_KEY_1));
    274         assertTrue(changedExtras.containsKey(TEST_EXTRA_KEY_2));
    275     }
    276 
    277     /**
    278      * Verifies {@link Conference#removeExtras(List)} calls are propagated to
    279      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    280      */
    281     public void testConferenceRemoveExtras() {
    282         if (!mShouldTestTelecom) {
    283             return;
    284         }
    285         final Call conf = mInCallService.getLastConferenceCall();
    286         assertCallState(conf, Call.STATE_ACTIVE);
    287 
    288         setupExtras();
    289 
    290         int startInvokeCount = mOnExtrasChangedCounter.getInvokeCount();
    291         mConferenceObject.removeExtras(Arrays.asList(TEST_EXTRA_KEY_1));
    292         mOnExtrasChangedCounter.waitForCount(startInvokeCount + 1,
    293                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    294         Bundle extras = mConferenceObject.getExtras();
    295 
    296         assertFalse(extras.containsKey(TEST_EXTRA_KEY_1));
    297         assertTrue(extras.containsKey(TEST_EXTRA_KEY_2));
    298     }
    299 
    300     /**
    301      * Verifies {@link Conference#removeExtras(String[])} calls are propagated to
    302      * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
    303      */
    304     public void testConferenceRemoveExtras2() {
    305         if (!mShouldTestTelecom) {
    306             return;
    307         }
    308         final Call conf = mInCallService.getLastConferenceCall();
    309         assertCallState(conf, Call.STATE_ACTIVE);
    310 
    311         setupExtras();
    312 
    313         int startInvokeCount = mOnExtrasChangedCounter.getInvokeCount();
    314         mConferenceObject.removeExtras(TEST_EXTRA_KEY_1, TEST_EXTRA_KEY_2);
    315         mOnExtrasChangedCounter.waitForCount(startInvokeCount + 1,
    316                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    317         Bundle extras = mConferenceObject.getExtras();
    318 
    319         assertFalse(extras.containsKey(TEST_EXTRA_KEY_1));
    320         assertFalse(extras.containsKey(TEST_EXTRA_KEY_2));
    321     }
    322 
    323     private void setupExtras() {
    324         Bundle extras = new Bundle();
    325         extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
    326         extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
    327         int startInvokeCount = mOnExtrasChangedCounter.getInvokeCount();
    328         mConferenceObject.putExtras(extras);
    329         mOnExtrasChangedCounter.waitForCount(startInvokeCount + 1,
    330                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
    331     }
    332 
    333     /**
    334      * Verifies {@link android.telecom.Call#putExtras(Bundle)} changes are propagated to
    335      * {@link Conference#onExtrasChanged(Bundle)}.
    336      */
    337     public void testConferenceOnExtraschanged() {
    338         if (!mShouldTestTelecom) {
    339             return;
    340         }
    341         final Call conf = mInCallService.getLastConferenceCall();
    342         assertCallState(conf, Call.STATE_ACTIVE);
    343 
    344         Bundle extras = new Bundle();
    345         extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
    346         extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
    347         conf.putExtras(extras);
    348         mConferenceVerficationObject.mOnExtrasChanged.waitForCount(1);
    349 
    350         Bundle changedExtras = mConferenceObject.getExtras();
    351         assertTrue(changedExtras.containsKey(TEST_EXTRA_KEY_1));
    352         assertTrue(changedExtras.containsKey(TEST_EXTRA_KEY_2));
    353     }
    354 
    355     public void testConferenceAddAndRemoveConnection() {
    356         if (!mShouldTestTelecom) {
    357             return;
    358         }
    359         final Call conf = mInCallService.getLastConferenceCall();
    360         assertCallState(conf, Call.STATE_ACTIVE);
    361 
    362         placeAndVerifyCall();
    363         MockConnection newConnection = verifyConnectionForOutgoingCall(2);
    364         final Call newCall = mInCallService.getLastCall();
    365 
    366         ArrayList<Connection> connectionList = new ArrayList<>();
    367         connectionList.add(newConnection);
    368         ArrayList<Call> callList = new ArrayList<>();
    369         callList.add(newCall);
    370 
    371         assertFalse(conf.getChildren().contains(newCall));
    372         mConferenceObject.addConnection(newConnection);
    373         assertCallChildrenContains(conf, newCall, true);
    374 
    375         assertTrue(conf.getChildren().contains(newCall));
    376         mConferenceObject.removeConnection(newConnection);
    377         assertCallChildrenContains(conf, newCall, false);
    378     }
    379 
    380     public void testConferenceDTMFTone() {
    381         if (!mShouldTestTelecom) {
    382             return;
    383         }
    384         final Call conf = mInCallService.getLastConferenceCall();
    385         assertCallState(conf, Call.STATE_ACTIVE);
    386 
    387         assertTrue(((MockConference)mConferenceObject).getDtmfString().isEmpty());
    388         conf.playDtmfTone('1');
    389         assertDtmfString((MockConference)mConferenceObject, "1");
    390         conf.stopDtmfTone();
    391         assertDtmfString((MockConference)mConferenceObject, "1.");
    392         conf.playDtmfTone('3');
    393         assertDtmfString((MockConference)mConferenceObject, "1.3");
    394         conf.stopDtmfTone();
    395         assertDtmfString((MockConference)mConferenceObject, "1.3.");
    396     }
    397 
    398     private void verifyConferenceObject(Conference mConferenceObject, MockConnection connection1,
    399             MockConnection connection2) {
    400         assertNull(mConferenceObject.getCallAudioState());
    401         assertTrue(mConferenceObject.getConferenceableConnections().isEmpty());
    402         assertEquals(connection1.getConnectionCapabilities(),
    403                 mConferenceObject.getConnectionCapabilities());
    404         assertEquals(connection1.getState(), mConferenceObject.getState());
    405         assertEquals(connection2.getState(), mConferenceObject.getState());
    406         assertTrue(mConferenceObject.getConnections().contains(connection1));
    407         assertTrue(mConferenceObject.getConnections().contains(connection2));
    408         assertEquals(connection1.getDisconnectCause(), mConferenceObject.getDisconnectCause());
    409         assertTrue(areBundlesEqual(connection1.getExtras(), mConferenceObject.getExtras()));
    410         assertEquals(connection1.getPhoneAccountHandle(), mConferenceObject.getPhoneAccountHandle());
    411         assertEquals(connection1.getStatusHints(), mConferenceObject.getStatusHints());
    412         assertEquals(VideoProfile.STATE_AUDIO_ONLY, mConferenceObject.getVideoState());
    413         assertNull(mConferenceObject.getVideoProvider());
    414     }
    415 
    416     private void addOutgoingCalls() {
    417         try {
    418             PhoneAccount account = setupConnectionService(
    419                     new MockConnectionService() {
    420                         @Override
    421                         public Connection onCreateOutgoingConnection(
    422                                 PhoneAccountHandle connectionManagerPhoneAccount,
    423                                 ConnectionRequest request) {
    424                             Connection connection = super.onCreateOutgoingConnection(
    425                                     connectionManagerPhoneAccount,
    426                                     request);
    427                             // Modify the connection object created with local values.
    428                             int capabilities = connection.getConnectionCapabilities();
    429                             connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
    430                             return connection;
    431                         }
    432                     }, FLAG_REGISTER | FLAG_ENABLE);
    433         } catch(Exception e) {
    434             fail("Error in setting up the connection services");
    435         }
    436 
    437         placeAndVerifyCall();
    438         mConnection1 = verifyConnectionForOutgoingCall(0);
    439         mInCallService = mInCallCallbacks.getService();
    440         mCall1 = mInCallService.getLastCall();
    441         assertCallState(mCall1, Call.STATE_DIALING);
    442         mConnection1.setActive();
    443         assertCallState(mCall1, Call.STATE_ACTIVE);
    444 
    445         placeAndVerifyCall();
    446         mConnection2 = verifyConnectionForOutgoingCall(1);
    447         mCall2 = mInCallService.getLastCall();
    448         assertCallState(mCall2, Call.STATE_DIALING);
    449         mConnection2.setActive();
    450         assertCallState(mCall2, Call.STATE_ACTIVE);
    451 
    452         setAndVerifyConferenceablesForOutgoingConnection(0);
    453         setAndVerifyConferenceablesForOutgoingConnection(1);
    454     }
    455 
    456     private void assertCallCapability(final Call call, final int capability) {
    457         waitUntilConditionIsTrueOrTimeout(
    458                 new Condition() {
    459                     @Override
    460                     public Object expected() {
    461                         return true;
    462                     }
    463 
    464                     @Override
    465                     public Object actual() {
    466                         return call.getDetails().can(capability);
    467                     }
    468                 },
    469                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    470                 "Call should have capability " + capability
    471         );
    472     }
    473 
    474     private void assertCallConnectTime(final Call call, final int connectTime) {
    475         waitUntilConditionIsTrueOrTimeout(
    476                 new Condition() {
    477                     @Override
    478                     public Object expected() {
    479                         return connectTime;
    480                     }
    481 
    482                     @Override
    483                     public Object actual() {
    484                         return call.getDetails().getConnectTimeMillis();
    485                     }
    486                 },
    487                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    488                 "Call should have connect time " + connectTime
    489         );
    490     }
    491 
    492     private void assertCallExtras(final Call call, final String key, final String value) {
    493         waitUntilConditionIsTrueOrTimeout(
    494                 new Condition() {
    495                     @Override
    496                     public Object expected() {
    497                         return value;
    498                     }
    499 
    500                     @Override
    501                     public Object actual() {
    502                         return call.getDetails().getExtras() != null ?
    503                             call.getDetails().getExtras().getString(key) : null;
    504                     }
    505                 },
    506                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    507                 "Call should have extra " + key + "=" + value
    508         );
    509     }
    510 
    511     private void assertCallStatusHints(final Call call, final StatusHints hints) {
    512         waitUntilConditionIsTrueOrTimeout(
    513                 new Condition() {
    514                     @Override
    515                     public Object expected() {
    516                         return hints;
    517                     }
    518 
    519                     @Override
    520                     public Object actual() {
    521                         return call.getDetails().getStatusHints();
    522                     }
    523                 },
    524                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    525                 "Call should have status hints " + hints
    526         );
    527     }
    528 
    529     private void assertCallChildrenContains(final Call call, final Call childrenCall,
    530                                             final boolean expected) {
    531         waitUntilConditionIsTrueOrTimeout(
    532                 new Condition() {
    533                     @Override
    534                     public Object expected() {
    535                         return expected;
    536                     }
    537 
    538                     @Override
    539                     public Object actual() {
    540                         return call.getChildren().contains(childrenCall);
    541                     }
    542                 },
    543                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    544                 expected == true ? "Call should have child call " + childrenCall :
    545                         "Call should not have child call " + childrenCall
    546         );
    547     }
    548 
    549     private void assertVideoState(final Call call, final int videoState) {
    550         waitUntilConditionIsTrueOrTimeout(
    551                 new Condition() {
    552                     @Override
    553                     public Object expected() {
    554                         return videoState;
    555                     }
    556 
    557                     @Override
    558                     public Object actual() {
    559                         return call.getDetails().getVideoState();
    560                     }
    561                 },
    562                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    563                 "Call should be in videoState " + videoState
    564         );
    565     }
    566 }
    567