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 android.graphics.SurfaceTexture;
     20 import android.net.Uri;
     21 import android.telecom.Call;
     22 import android.telecom.Connection;
     23 import android.telecom.Connection.VideoProvider;
     24 import android.telecom.InCallService;
     25 import android.telecom.VideoProfile;
     26 import android.util.Log;
     27 import android.view.Surface;
     28 import android.view.TextureView;
     29 
     30 import static android.telecom.cts.TestUtils.shouldTestTelecom;
     31 
     32 /**
     33  * Suites of tests that use {@link MockVideoProvider} and {@link MockVideoCallCallback} to verify
     34  * the functionality of the video APIs.
     35  *
     36  * Note: You'll notice the use of {@code work}, and
     37  * {@code doWorkAndWaitUntilConditionIsTrueOrTimeout} here.  The problem is the
     38  * {@link MockVideoProvider} is running using a Handler.  To get it to emit mock data that is
     39  * in sync with the setup operations performed on the handler, we'd need access to its handler.
     40  * The handler of the {@link Connection.VideoProvider} is, however, not public.  As a workaround
     41  * we will call local methods on the MockVideoProvider.  This means there is a chance the
     42  * VideoProvider will emit the data we're interested in before the callbacks (on the handler)
     43  * are even set up.  Consequently, the callbacks we're depending on in our test may not get
     44  * called.  To compensate we will call the test methods on the provider repeatedly until we
     45  * hear back via our callback.  Suboptimal, but it works.
     46  */
     47 public class VideoCallTest extends BaseTelecomTestWithMockServices {
     48 
     49     @Override
     50     protected void setUp() throws Exception {
     51         super.setUp();
     52         if (mShouldTestTelecom) {
     53             setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
     54         }
     55     }
     56 
     57     /**
     58      * Tests ability to start a 2-way video call and retrieve its video state.
     59      */
     60     public void testMakeTwoWayVideoCall() {
     61         if (!mShouldTestTelecom) {
     62             return;
     63         }
     64 
     65         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
     66         final MockConnection connection = verifyConnectionForOutgoingCall();
     67 
     68         final MockInCallService inCallService = mInCallCallbacks.getService();
     69         final Call call = inCallService.getLastCall();
     70 
     71         assertCallState(call, Call.STATE_DIALING);
     72         connection.setActive();
     73         assertCallState(call, Call.STATE_ACTIVE);
     74 
     75         assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
     76         assertVideoCallbackRegistered(inCallService, call, true);
     77     }
     78 
     79     /**
     80      * Tests ability to start a 1-way video call and retrieve its video state.
     81      */
     82     public void testMakeOneWayVideoCall() {
     83         if (!mShouldTestTelecom) {
     84             return;
     85         }
     86 
     87         placeAndVerifyCall(VideoProfile.STATE_TX_ENABLED);
     88         verifyConnectionForOutgoingCall();
     89 
     90         final MockInCallService inCallService = mInCallCallbacks.getService();
     91         final Call call = inCallService.getLastCall();
     92 
     93         assertVideoState(call, VideoProfile.STATE_TX_ENABLED);
     94         assertVideoCallbackRegistered(inCallService, call, true);
     95     }
     96 
     97     /**
     98      * Tests ability to upgrade an audio-only call to a video call.
     99      */
    100     public void testUpgradeToVideo() {
    101         if (!mShouldTestTelecom) {
    102             return;
    103         }
    104 
    105         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
    106         verifyConnectionForOutgoingCall();
    107 
    108         final MockInCallService inCallService = mInCallCallbacks.getService();
    109         final Call call = inCallService.getLastCall();
    110         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
    111         assertVideoCallbackRegistered(inCallService, call, true);
    112 
    113         // Send request to upgrade to video.
    114         InCallService.VideoCall videoCall = call.getVideoCall();
    115         videoCall.sendSessionModifyRequest(new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
    116         assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
    117         assertResponseVideoProfileReceived(inCallService.getVideoCallCallback(call),
    118                 VideoProfile.STATE_BIDIRECTIONAL);
    119     }
    120 
    121     /**
    122      * Tests ability to receive a session modification request.
    123      */
    124     public void testReceiveSessionModifyRequest() {
    125         if (!mShouldTestTelecom) {
    126             return;
    127         }
    128 
    129         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
    130         final MockConnection connection = verifyConnectionForOutgoingCall();
    131 
    132         final MockInCallService inCallService = mInCallCallbacks.getService();
    133         final Call call = inCallService.getLastCall();
    134 
    135         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
    136         assertVideoCallbackRegistered(inCallService, call, true);
    137 
    138         // Have the video profile mock reception of a request.
    139         assertRequestVideoProfileReceived(inCallService.getVideoCallCallback(call),
    140                 VideoProfile.STATE_BIDIRECTIONAL,
    141                 new Work() {
    142                     @Override
    143                     public void doWork() {
    144                         connection.sendMockSessionModifyRequest(
    145                                 new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
    146                     }
    147                 });
    148     }
    149 
    150     /**
    151      * Tests ability to send a session modification response.
    152      */
    153     public void testSendSessionModifyResponse() {
    154         if (!mShouldTestTelecom) {
    155             return;
    156         }
    157 
    158         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
    159         final MockConnection connection = verifyConnectionForOutgoingCall();
    160 
    161         final MockInCallService inCallService = mInCallCallbacks.getService();
    162         final Call call = inCallService.getLastCall();
    163         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    164         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
    165         assertVideoCallbackRegistered(inCallService, call, true);
    166 
    167         InCallService.VideoCall videoCall = call.getVideoCall();
    168         videoCall.sendSessionModifyResponse(new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
    169         assertSessionModifyResponse(mockVideoProvider, VideoProfile.STATE_BIDIRECTIONAL);
    170     }
    171 
    172     /**
    173      * Test handling of session modify responses.
    174      */
    175     public void testReceiveSessionModifyResponse() {
    176         if (!mShouldTestTelecom) {
    177             return;
    178         }
    179 
    180         VideoProfile fromVideoProfile = new VideoProfile(VideoProfile.STATE_AUDIO_ONLY);
    181         VideoProfile toVideoProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
    182 
    183         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
    184         final MockConnection connection = verifyConnectionForOutgoingCall();
    185 
    186         final MockInCallService inCallService = mInCallCallbacks.getService();
    187         final Call call = inCallService.getLastCall();
    188         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    189         assertVideoCallbackRegistered(inCallService, call, true);
    190 
    191         final MockVideoCallCallback callback = inCallService.getVideoCallCallback(call);
    192 
    193         mockVideoProvider.sendMockSessionModifyResponse(
    194                 VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS, fromVideoProfile,
    195                 toVideoProfile);
    196         assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS,
    197                 fromVideoProfile, toVideoProfile);
    198 
    199         mockVideoProvider.sendMockSessionModifyResponse(
    200                 VideoProvider.SESSION_MODIFY_REQUEST_FAIL, fromVideoProfile,
    201                 toVideoProfile);
    202         assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_FAIL,
    203                 fromVideoProfile, toVideoProfile);
    204 
    205         mockVideoProvider.sendMockSessionModifyResponse(
    206                 VideoProvider.SESSION_MODIFY_REQUEST_INVALID, fromVideoProfile,
    207                 toVideoProfile);
    208         assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_INVALID,
    209                 fromVideoProfile, toVideoProfile);
    210 
    211         mockVideoProvider.sendMockSessionModifyResponse(
    212                 VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE, fromVideoProfile,
    213                 toVideoProfile);
    214         assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE,
    215                 fromVideoProfile, toVideoProfile);
    216 
    217         mockVideoProvider.sendMockSessionModifyResponse(
    218                 VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT, fromVideoProfile,
    219                 toVideoProfile);
    220         assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT,
    221                 fromVideoProfile, toVideoProfile);
    222     }
    223 
    224     /**
    225      * Tests ability to start a video call, delaying the creation of the provider until after
    226      * the call has been initiated (rather than immediately when the call is created).  This more
    227      * closely mimics the lifespan of a {@code VideoProvider} instance as it is reasonable to
    228      * expect there will be some overhead associated with configuring the camera at the start of
    229      * the call.
    230      */
    231     public void testVideoCallDelayProvider() {
    232         if (!mShouldTestTelecom) {
    233             return;
    234         }
    235 
    236         // Don't create video provider when call is created initially; we will do this later.
    237         try {
    238             connectionService.setCreateVideoProvider(false);
    239             placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    240             final MockConnection connection = verifyConnectionForOutgoingCall();
    241 
    242             final MockInCallService inCallService = mInCallCallbacks.getService();
    243             final Call call = inCallService.getLastCall();
    244 
    245             assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
    246             // After initial connection creation there should not be a video provider or callbacks
    247             // registered.
    248             assertVideoCallbackRegistered(inCallService, call, false);
    249 
    250             // Trigger delayed creation of video provider and registration of callbacks and assert
    251             // that it happened.
    252             connection.createMockVideoProvider();
    253             assertVideoCallbackRegistered(inCallService, call, true);
    254 
    255             // Ensure video providers are created in the future.
    256         } finally {
    257             connectionService.setCreateVideoProvider(true);
    258         }
    259     }
    260 
    261 
    262     /**
    263      * Tests ability to change the current camera.  Ensures that the camera capabilities are sent
    264      * back in response.
    265      */
    266     public void testChangeCamera() {
    267         if (!mShouldTestTelecom) {
    268             return;
    269         }
    270 
    271         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    272         verifyConnectionForOutgoingCall();
    273 
    274         final MockInCallService inCallService = mInCallCallbacks.getService();
    275         final Call call = inCallService.getLastCall();
    276         assertVideoCallbackRegistered(inCallService, call, true);
    277         final InCallService.VideoCall videoCall = call.getVideoCall();
    278 
    279         videoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
    280         assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
    281                 MockVideoProvider.CAMERA_FRONT_DIMENSIONS);
    282 
    283         videoCall.setCamera(MockVideoProvider.CAMERA_BACK);
    284         assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
    285                 MockVideoProvider.CAMERA_BACK_DIMENSIONS);
    286     }
    287 
    288     /**
    289      * Tests ability to request the camera capabilities from the video provider.
    290      */
    291     public void testRequestCameraCapabilities() {
    292         if (!mShouldTestTelecom) {
    293             return;
    294         }
    295 
    296         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    297         verifyConnectionForOutgoingCall();
    298 
    299         final MockInCallService inCallService = mInCallCallbacks.getService();
    300         final Call call = inCallService.getLastCall();
    301         assertVideoCallbackRegistered(inCallService, call, true);
    302         final InCallService.VideoCall videoCall = call.getVideoCall();
    303 
    304         // First, set the camera.
    305         videoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
    306         // Retrieve the camera capabilities that are automatically send when the camera is set --
    307         // ensures the cached value is cleared first.
    308         inCallService.getVideoCallCallback(call).getCameraCapabilities();
    309 
    310         // Now, request capabilities.
    311         videoCall.requestCameraCapabilities();
    312         assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
    313                 MockVideoProvider.CAMERA_FRONT_DIMENSIONS);
    314     }
    315 
    316     /**
    317      * Tests ability to request data usage from the video provider.
    318      */
    319     public void testRequestDataUsage() {
    320         if (!mShouldTestTelecom) {
    321             return;
    322         }
    323 
    324         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    325         verifyConnectionForOutgoingCall();
    326 
    327         final MockInCallService inCallService = mInCallCallbacks.getService();
    328         final Call call = inCallService.getLastCall();
    329         assertVideoCallbackRegistered(inCallService, call, true);
    330         final InCallService.VideoCall videoCall = call.getVideoCall();
    331 
    332         videoCall.requestCallDataUsage();
    333         assertCallDataUsageReceived(inCallService.getVideoCallCallback(call),
    334                 MockVideoProvider.DATA_USAGE);
    335     }
    336 
    337     /**
    338      * Tests ability to receive changes to the video quality from the video provider.
    339      */
    340     public void testReceiveVideoQuality() {
    341         if (!mShouldTestTelecom) {
    342             return;
    343         }
    344 
    345         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    346         final MockConnection connection = verifyConnectionForOutgoingCall();
    347 
    348         final MockInCallService inCallService = mInCallCallbacks.getService();
    349         final Call call = inCallService.getLastCall();
    350         assertVideoCallbackRegistered(inCallService, call, true);
    351 
    352         assertVideoQualityReceived(inCallService.getVideoCallCallback(call),
    353                 VideoProfile.QUALITY_HIGH,
    354                 new Work() {
    355                     @Override
    356                     public void doWork() {
    357                         connection
    358                                 .sendMockVideoQuality(VideoProfile.QUALITY_HIGH);
    359                     }
    360                 });
    361 
    362         assertVideoQualityReceived(inCallService.getVideoCallCallback(call),
    363                 VideoProfile.QUALITY_MEDIUM,
    364                 new Work() {
    365                     @Override
    366                     public void doWork() {
    367                         connection
    368                                 .sendMockVideoQuality(VideoProfile.QUALITY_MEDIUM);
    369                     }
    370                 });
    371     }
    372 
    373     /**
    374      * Tests ability to receive call session events from the video provider.
    375      */
    376     public void testReceiveCallSessionEvent() {
    377         if (!mShouldTestTelecom) {
    378             return;
    379         }
    380 
    381         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    382         final MockConnection connection = verifyConnectionForOutgoingCall();
    383 
    384         final MockInCallService inCallService = mInCallCallbacks.getService();
    385         final Call call = inCallService.getLastCall();
    386         assertVideoCallbackRegistered(inCallService, call, true);
    387 
    388         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    389                 Connection.VideoProvider.SESSION_EVENT_CAMERA_READY,
    390                 new Work() {
    391                     @Override
    392                     public void doWork() {
    393                         connection.sendMockCallSessionEvent(
    394                                 Connection.VideoProvider.SESSION_EVENT_CAMERA_READY);
    395                     }
    396                 });
    397 
    398         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    399                 Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE,
    400                 new Work() {
    401                     @Override
    402                     public void doWork() {
    403                         connection.sendMockCallSessionEvent(
    404                                 Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE);
    405                     }
    406                 });
    407 
    408         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    409                 Connection.VideoProvider.SESSION_EVENT_TX_START,
    410                 new Work() {
    411                     @Override
    412                     public void doWork() {
    413                         connection.sendMockCallSessionEvent(
    414                                 Connection.VideoProvider.SESSION_EVENT_TX_START);
    415                     }
    416                 });
    417 
    418         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    419                 Connection.VideoProvider.SESSION_EVENT_TX_STOP,
    420                 new Work() {
    421                     @Override
    422                     public void doWork() {
    423                         connection.sendMockCallSessionEvent(
    424                                 Connection.VideoProvider.SESSION_EVENT_TX_STOP);
    425                     }
    426                 });
    427 
    428         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    429                 Connection.VideoProvider.SESSION_EVENT_RX_PAUSE,
    430                 new Work() {
    431                     @Override
    432                     public void doWork() {
    433                         connection.sendMockCallSessionEvent(
    434                                 Connection.VideoProvider.SESSION_EVENT_RX_PAUSE);
    435                     }
    436                 });
    437 
    438         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    439                 Connection.VideoProvider.SESSION_EVENT_RX_RESUME,
    440                 new Work() {
    441                     @Override
    442                     public void doWork() {
    443                         connection.sendMockCallSessionEvent(
    444                                 Connection.VideoProvider.SESSION_EVENT_RX_RESUME);
    445                     }
    446                 });
    447 
    448         assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
    449                 VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR,
    450                 new Work() {
    451                     @Override
    452                     public void doWork() {
    453                         connection.sendMockCallSessionEvent(
    454                                 Connection.VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR);
    455                     }
    456                 });
    457     }
    458 
    459     /**
    460      * Tests ability to receive changes to the peer dimensions from the video provider.
    461      */
    462     public void testReceivePeerDimensionChange() {
    463         if (!mShouldTestTelecom) {
    464             return;
    465         }
    466 
    467         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    468         final MockConnection connection = verifyConnectionForOutgoingCall();
    469 
    470         final MockInCallService inCallService = mInCallCallbacks.getService();
    471         final Call call = inCallService.getLastCall();
    472         assertVideoCallbackRegistered(inCallService, call, true);
    473 
    474         assertPeerWidthChanged(inCallService.getVideoCallCallback(call),
    475                 MockVideoProvider.CAMERA_BACK_DIMENSIONS,
    476                 new Work() {
    477                     @Override
    478                     public void doWork() {
    479                         connection.sendMockPeerWidth(MockVideoProvider.CAMERA_BACK_DIMENSIONS);
    480                     }
    481                 });
    482     }
    483 
    484     /**
    485      * Tests ability to set the device orientation via the provider.
    486      */
    487     public void testSetDeviceOrientation() {
    488         if (!mShouldTestTelecom) {
    489             return;
    490         }
    491 
    492         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    493         final MockConnection connection = verifyConnectionForOutgoingCall();
    494 
    495         final MockInCallService inCallService = mInCallCallbacks.getService();
    496         final Call call = inCallService.getLastCall();
    497         assertVideoCallbackRegistered(inCallService, call, true);
    498         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    499         final InCallService.VideoCall videoCall = call.getVideoCall();
    500 
    501         // Set device orientation and ensure provider knows about it.
    502         videoCall.setDeviceOrientation(90);
    503         assertDeviceOrientationChanged(mockVideoProvider, 90);
    504     }
    505 
    506     /**
    507      * Tests ability to set the preview surface via the provider.
    508      */
    509     public void testSetPreviewSurface() {
    510         if (!mShouldTestTelecom) {
    511             return;
    512         }
    513 
    514         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    515         final MockConnection connection = verifyConnectionForOutgoingCall();
    516 
    517         final MockInCallService inCallService = mInCallCallbacks.getService();
    518         final Call call = inCallService.getLastCall();
    519         assertVideoCallbackRegistered(inCallService, call, true);
    520         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    521         final InCallService.VideoCall videoCall = call.getVideoCall();
    522 
    523         Surface surface = new Surface(new SurfaceTexture(1));
    524         // Set a surface
    525         videoCall.setPreviewSurface(surface);
    526         assertPreviewSurfaceChanged(mockVideoProvider, true);
    527 
    528         // Clear the surface
    529         videoCall.setPreviewSurface(null);
    530         assertPreviewSurfaceChanged(mockVideoProvider, false);
    531     }
    532 
    533     /**
    534      * Tests ability to set the display surface via the provider.
    535      */
    536     public void testSetDisplaySurface() {
    537         if (!mShouldTestTelecom) {
    538             return;
    539         }
    540 
    541         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    542         final MockConnection connection = verifyConnectionForOutgoingCall();
    543 
    544         final MockInCallService inCallService = mInCallCallbacks.getService();
    545         final Call call = inCallService.getLastCall();
    546         assertVideoCallbackRegistered(inCallService, call, true);
    547         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    548         final InCallService.VideoCall videoCall = call.getVideoCall();
    549 
    550         // Set a surface
    551         Surface surface = new Surface(new SurfaceTexture(1));
    552         videoCall.setDisplaySurface(surface);
    553         assertDisplaySurfaceChanged(mockVideoProvider, true);
    554 
    555         // Clear the surface
    556         videoCall.setDisplaySurface(null);
    557         assertDisplaySurfaceChanged(mockVideoProvider, false);
    558     }
    559 
    560     /**
    561      * Tests ability to set the camera zoom via the provider.
    562      */
    563     public void testSetZoom() {
    564         if (!mShouldTestTelecom) {
    565             return;
    566         }
    567 
    568         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    569         final MockConnection connection = verifyConnectionForOutgoingCall();
    570 
    571         final MockInCallService inCallService = mInCallCallbacks.getService();
    572         final Call call = inCallService.getLastCall();
    573         assertVideoCallbackRegistered(inCallService, call, true);
    574         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    575         final InCallService.VideoCall videoCall = call.getVideoCall();
    576 
    577         videoCall.setZoom(0.0f);
    578         assertZoomChanged(mockVideoProvider, 0.0f);
    579 
    580         videoCall.setZoom(10.0f);
    581         assertZoomChanged(mockVideoProvider, 10.0f);
    582 
    583         call.disconnect();
    584     }
    585 
    586     public void testSetPauseImage() {
    587         if (!mShouldTestTelecom) {
    588             return;
    589         }
    590 
    591         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
    592         final MockConnection connection = verifyConnectionForOutgoingCall();
    593 
    594         final MockInCallService inCallService = mInCallCallbacks.getService();
    595         final Call call = inCallService.getLastCall();
    596         assertVideoCallbackRegistered(inCallService, call, true);
    597         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
    598         final InCallService.VideoCall videoCall = call.getVideoCall();
    599 
    600         final Uri pauseImageUri = Uri.fromParts("file", "test.png", "");
    601         videoCall.setPauseImage(pauseImageUri);
    602         assertPauseUriChanged(mockVideoProvider, pauseImageUri);
    603     }
    604 
    605     /**
    606      * Asserts that a call video state is as expected.
    607      *
    608      * @param call The call.
    609      * @param videoState The expected video state.
    610      */
    611     private void assertVideoState(final Call call, final int videoState) {
    612         waitUntilConditionIsTrueOrTimeout(
    613                 new Condition() {
    614                     @Override
    615                     public Object expected() {
    616                         return videoState;
    617                     }
    618 
    619                     @Override
    620                     public Object actual() {
    621                         return call.getDetails().getVideoState();
    622                     }
    623                 },
    624                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    625                 "Call should be in videoState " + videoState
    626         );
    627     }
    628 
    629     /**
    630      * Asserts whether the InCallService has registered a video call back (and hence a video call)
    631      * for a call.
    632      *
    633      * @param inCallService The incall service.
    634      * @param call The call.
    635      * @param isRegistered The expected registration state.
    636      */
    637     private void assertVideoCallbackRegistered(final MockInCallService inCallService,
    638             final Call call, final Boolean isRegistered) {
    639         waitUntilConditionIsTrueOrTimeout(
    640                 new Condition() {
    641                     @Override
    642                     public Object expected() {
    643                         return isRegistered;
    644                     }
    645 
    646                     @Override
    647                     public Object actual() {
    648                         return inCallService.isVideoCallbackRegistered(call);
    649                     }
    650                 },
    651                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    652                 "Video callback registration state should be " + isRegistered
    653         );
    654     }
    655 
    656     /**
    657      * Asserts whether the camera capabilities have changed to an expected value.  Compares the
    658      * camera height only (the {@link MockVideoProvider} sets height and width to be the same.
    659      *
    660      * @param videoCallCallback The video call callback.
    661      * @param expectedCameraWidthHeight The expected width and height.
    662      */
    663     private void assertCameraCapabilitiesReceived(final MockVideoCallCallback videoCallCallback,
    664             final int expectedCameraWidthHeight) {
    665         waitUntilConditionIsTrueOrTimeout(
    666                 new Condition() {
    667                     @Override
    668                     public Object expected() {
    669                         return expectedCameraWidthHeight;
    670                     }
    671 
    672                     @Override
    673                     public Object actual() {
    674                         VideoProfile.CameraCapabilities cameraCapabilities =
    675                                 videoCallCallback.getCameraCapabilities();
    676                         return cameraCapabilities == null ? 0 : cameraCapabilities.getHeight();
    677                     }
    678                 },
    679                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    680                 "Camera width and height should be " + expectedCameraWidthHeight
    681         );
    682     }
    683 
    684     /**
    685      * Asserts whether the call data usage has changed to the expected value.
    686      *
    687      * @param videoCallCallback The video call callback.
    688      * @param expectedDataUsage The expected data usage.
    689      */
    690     private void assertCallDataUsageReceived(final MockVideoCallCallback videoCallCallback,
    691             final long expectedDataUsage) {
    692         waitUntilConditionIsTrueOrTimeout(
    693                 new Condition() {
    694                     @Override
    695                     public Object expected() {
    696                         return expectedDataUsage;
    697                     }
    698 
    699                     @Override
    700                     public Object actual() {
    701                         return videoCallCallback.getDataUsage();
    702                     }
    703                 },
    704                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    705                 "Data usage should be " + expectedDataUsage
    706         );
    707     }
    708 
    709     /**
    710      * Asserts whether the video quality has changed to the expected value.
    711      *
    712      * @param videoCallCallback The video call callback.
    713      * @param expectedVideoQuality The expected video quality.
    714      * @param work The work to perform to have the provider emit the video quality.
    715      */
    716     private void assertVideoQualityReceived(final MockVideoCallCallback videoCallCallback,
    717             final int expectedVideoQuality, final Work work) {
    718         doWorkAndWaitUntilConditionIsTrueOrTimeout(
    719                 work,
    720                 new Condition() {
    721                     @Override
    722                     public Object expected() {
    723                         return expectedVideoQuality;
    724                     }
    725 
    726                     @Override
    727                     public Object actual() {
    728                         return videoCallCallback.getVideoQuality();
    729                     }
    730                 },
    731                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    732                 "Video quality should be " + expectedVideoQuality
    733         );
    734     }
    735 
    736     /**
    737      * Asserts whether the call session event has changed to the expected value.
    738      *
    739      * @param videoCallCallback The video call callback.
    740      * @param expectedEvent The expected event.
    741      * @param work The work to be performed to send the call session event from the provider.
    742      */
    743     private void assertCallSessionEventReceived(final MockVideoCallCallback videoCallCallback,
    744             final int expectedEvent, final Work work) {
    745         doWorkAndWaitUntilConditionIsTrueOrTimeout(
    746                 work,
    747                 new Condition() {
    748                     @Override
    749                     public Object expected() {
    750                         return expectedEvent;
    751                     }
    752 
    753                     @Override
    754                     public Object actual() {
    755                         return videoCallCallback.getCallSessionEvent();
    756                     }
    757                 },
    758                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    759                 "Call session event should be " + expectedEvent
    760         );
    761     }
    762 
    763     /**
    764      * Asserts whether the peer width has changed to the expected value.
    765      *
    766      * @param videoCallCallback The video call callback.
    767      * @param expectedWidth The expected width.
    768      * @param work The work to be performed to send the peer width from the provider.
    769      */
    770     private void assertPeerWidthChanged(final MockVideoCallCallback videoCallCallback,
    771             final int expectedWidth, final Work work) {
    772         doWorkAndWaitUntilConditionIsTrueOrTimeout(
    773                 work,
    774                 new Condition() {
    775                     @Override
    776                     public Object expected() {
    777                         return expectedWidth;
    778                     }
    779 
    780                     @Override
    781                     public Object actual() {
    782                         return videoCallCallback.getPeerWidth();
    783                     }
    784                 },
    785                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    786                 "Peer width should be " + expectedWidth
    787         );
    788     }
    789 
    790     /**
    791      * Asserts whether the device orientation has changed to the expected value.
    792      *
    793      * @param mockVideoProvider The mock video provider.
    794      * @param expected The expected device orientation.
    795      */
    796     private void assertDeviceOrientationChanged(final MockVideoProvider mockVideoProvider,
    797             final int expected) {
    798         waitUntilConditionIsTrueOrTimeout(
    799                 new Condition() {
    800                     @Override
    801                     public Object expected() {
    802                         return expected;
    803                     }
    804 
    805                     @Override
    806                     public Object actual() {
    807                         return mockVideoProvider.getDeviceOrientation();
    808                     }
    809                 },
    810                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    811                 "Orientation should be " + expected
    812         );
    813     }
    814 
    815     /**
    816      * Asserts whether the preview surface has been set or not.
    817      *
    818      * @param mockVideoProvider The mock video provider.
    819      * @param expected {@code true} if it is expected the preview surface is not null, {@code false}
    820      *                             if it is expected the preview surface is null.
    821      */
    822     private void assertPreviewSurfaceChanged(final MockVideoProvider mockVideoProvider,
    823             final boolean expected) {
    824         waitUntilConditionIsTrueOrTimeout(
    825                 new Condition() {
    826                     @Override
    827                     public Object expected() {
    828                         return expected;
    829                     }
    830 
    831                     @Override
    832                     public Object actual() {
    833                         return mockVideoProvider.getPreviewSurface() != null;
    834                     }
    835                 },
    836                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    837                 "Preview should be set? " + expected
    838         );
    839     }
    840 
    841     /**
    842      * Asserts whether the display surface has been set or not.
    843      *
    844      * @param mockVideoProvider The mock video provider.
    845      * @param expected {@code true} if it is expected the display surface is not null, {@code false}
    846      *                             if it is expected the display surface is null.
    847      */
    848     private void assertDisplaySurfaceChanged(final MockVideoProvider mockVideoProvider,
    849             final boolean expected) {
    850         waitUntilConditionIsTrueOrTimeout(
    851                 new Condition() {
    852                     @Override
    853                     public Object expected() {
    854                         return expected;
    855                     }
    856 
    857                     @Override
    858                     public Object actual() {
    859                         return mockVideoProvider.getDisplaySurface() != null;
    860                     }
    861                 },
    862                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    863                 "Display should be set? " + expected
    864         );
    865     }
    866 
    867     /**
    868      * Asserts whether the zoom has changed to the expected value.  Note: To make comparisons easier
    869      * the floats are cast to ints, so ensure only whole values are used.
    870      *
    871      * @param mockVideoProvider The mock video provider.
    872      * @param expected The expected zoom.
    873      */
    874     private void assertZoomChanged(final MockVideoProvider mockVideoProvider,
    875             final float expected) {
    876         waitUntilConditionIsTrueOrTimeout(
    877                 new Condition() {
    878                     @Override
    879                     public Object expected() {
    880                         // Cast to int so we're not doing float equality
    881                         return (int)expected;
    882                     }
    883 
    884                     @Override
    885                     public Object actual() {
    886                         // Cast to int so we're not doing float equality
    887                         return (int)mockVideoProvider.getZoom();
    888                     }
    889                 },
    890                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    891                 "Zoom should be " + expected
    892         );
    893     }
    894 
    895     /**
    896      * Asserts whether the pause image URI has changed to the expected value.
    897      *
    898      * @param mockVideoProvider The mock video provider.
    899      * @param expected The expected URI.
    900      */
    901     private void assertPauseUriChanged(final MockVideoProvider mockVideoProvider,
    902             final Uri expected) {
    903         waitUntilConditionIsTrueOrTimeout(
    904                 new Condition() {
    905                     @Override
    906                     public Object expected() {
    907                         return expected;
    908                     }
    909 
    910                     @Override
    911                     public Object actual() {
    912                         return mockVideoProvider.getPauseImageUri();
    913                     }
    914                 },
    915                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    916                 "Pause image URI should be " + expected
    917         );
    918     }
    919 
    920     /**
    921      * Asserts whether a response video profile has been received
    922      *
    923      * @param videoCallCallback The video call callback.
    924      * @param expected The expected video state.
    925      */
    926     private void assertResponseVideoProfileReceived(final MockVideoCallCallback videoCallCallback,
    927             final int expected) {
    928         waitUntilConditionIsTrueOrTimeout(
    929                 new Condition() {
    930                     @Override
    931                     public Object expected() {
    932                         return expected;
    933                     }
    934 
    935                     @Override
    936                     public Object actual() {
    937                         VideoProfile videoProfile = videoCallCallback.getResponseProfile();
    938                         return videoProfile == null ? -1 : videoProfile.getVideoState();
    939                     }
    940                 },
    941                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    942                 "Video state should be " + expected
    943         );
    944     }
    945 
    946     /**
    947      * Asserts whether a session modification request has been received.
    948      *
    949      * @param videoCallCallback The video call callback.
    950      * @param expected The expected video state.
    951      * @param work The work to be performed to cause the session modification request to be emit
    952      *             from the provider.
    953      */
    954     private void assertRequestVideoProfileReceived(final MockVideoCallCallback videoCallCallback,
    955             final int expected, final Work work) {
    956         doWorkAndWaitUntilConditionIsTrueOrTimeout(
    957                 work,
    958                 new Condition() {
    959                     @Override
    960                     public Object expected() {
    961                         return expected;
    962                     }
    963 
    964                     @Override
    965                     public Object actual() {
    966                         VideoProfile videoProfile = videoCallCallback.getRequestProfile();
    967                         return videoProfile == null ? -1 : videoProfile.getVideoState();
    968                     }
    969                 },
    970                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    971                 "Video state should be " + expected
    972         );
    973     }
    974 
    975     /**
    976      * Asserts whether the provider got a session modify response with the expected value.
    977      *
    978      * @param mockVideoProvider The mock video provider.
    979      * @param expected The expected video state of the session modify response.
    980      */
    981     private void assertSessionModifyResponse(final MockVideoProvider mockVideoProvider,
    982             final int expected) {
    983         waitUntilConditionIsTrueOrTimeout(
    984                 new Condition() {
    985                     @Override
    986                     public Object expected() {
    987                         return expected;
    988                     }
    989 
    990                     @Override
    991                     public Object actual() {
    992                         VideoProfile responseProfile = mockVideoProvider.getSessionModifyResponse();
    993                         return responseProfile == null ? -1 : responseProfile.getVideoState();
    994                     }
    995                 },
    996                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
    997                 "Session modify response video state should be " + expected
    998         );
    999     }
   1000 
   1001     /**
   1002      * Asserts whether a session modify response has been received with the expected values.
   1003      *
   1004      * @param videoCallCallback The video call callback.
   1005      * @param expectedResponseStatus The expected status.
   1006      * @param expectedFromProfile The expected from profile.
   1007      * @param expectedToProfile The expected to profile.
   1008      */
   1009     private void assertRequestReceived(final MockVideoCallCallback videoCallCallback,
   1010             final int expectedResponseStatus, final VideoProfile expectedFromProfile,
   1011             final VideoProfile expectedToProfile) {
   1012 
   1013         final String expected = buildRequestString(expectedResponseStatus, expectedFromProfile,
   1014                 expectedToProfile);
   1015 
   1016         waitUntilConditionIsTrueOrTimeout(
   1017                 new Condition() {
   1018                     @Override
   1019                     public Object expected() {
   1020                         return expected;
   1021                     }
   1022 
   1023                     @Override
   1024                     public Object actual() {
   1025                         int responseStatus = videoCallCallback.getResponseStatus();
   1026                         VideoProfile fromProfile = videoCallCallback.getRequestedProfile();
   1027                         VideoProfile toProfile = videoCallCallback.getResponseProfile();
   1028                         return buildRequestString(responseStatus, fromProfile, toProfile);
   1029                     }
   1030                 },
   1031                 TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
   1032                 "Session modify response should match expected."
   1033         );
   1034     }
   1035 
   1036     /**
   1037      * Creates a string representation of the parameters passed to
   1038      * {@link android.telecom.InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
   1039      * VideoProfile, VideoProfile)}.
   1040      *
   1041      * @param status The status.
   1042      * @param fromProfile The from profile.
   1043      * @param toProfile The to profile.
   1044      * @return String representation.
   1045      */
   1046     private String buildRequestString(int status, VideoProfile fromProfile, VideoProfile toProfile) {
   1047         StringBuilder expectedSb = new StringBuilder();
   1048         expectedSb.append("Status: ");
   1049         expectedSb.append(status);
   1050         expectedSb.append(" From: ");
   1051         expectedSb.append(fromProfile);
   1052         expectedSb.append(" To: ");
   1053         expectedSb.append(toProfile);
   1054         return expectedSb.toString();
   1055     }
   1056 }
   1057