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