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 com.android.server.telecom.tests; 18 19 import org.junit.After; 20 import org.junit.Before; 21 import org.junit.Test; 22 import org.junit.runner.RunWith; 23 import org.junit.runners.JUnit4; 24 import org.mockito.ArgumentCaptor; 25 import org.mockito.Mock; 26 import org.mockito.invocation.InvocationOnMock; 27 import org.mockito.stubbing.Answer; 28 29 import android.app.AppOpsManager; 30 import android.content.Context; 31 import android.graphics.SurfaceTexture; 32 import android.net.Uri; 33 import android.os.Build; 34 import android.os.Handler; 35 import android.os.Looper; 36 import android.os.UserHandle; 37 import android.telecom.Call; 38 import android.telecom.Connection; 39 import android.telecom.Connection.VideoProvider; 40 import android.telecom.DisconnectCause; 41 import android.telecom.InCallService; 42 import android.telecom.InCallService.VideoCall; 43 import android.telecom.VideoCallImpl; 44 import android.telecom.VideoProfile; 45 import android.telecom.VideoProfile.CameraCapabilities; 46 import android.test.suitebuilder.annotation.MediumTest; 47 import android.view.Surface; 48 49 import com.google.common.base.Predicate; 50 51 import java.util.List; 52 import java.util.concurrent.CountDownLatch; 53 import java.util.concurrent.TimeUnit; 54 55 import static org.junit.Assert.assertEquals; 56 import static org.mockito.Matchers.any; 57 import static org.mockito.Matchers.anyInt; 58 import static org.mockito.Matchers.anyLong; 59 import static org.mockito.Matchers.anyString; 60 import static org.mockito.Matchers.eq; 61 import static org.mockito.Mockito.doAnswer; 62 import static org.mockito.Mockito.doNothing; 63 import static org.mockito.Mockito.doReturn; 64 import static org.mockito.Mockito.doThrow; 65 import static org.mockito.Mockito.timeout; 66 import static org.mockito.Mockito.mock; 67 import static org.mockito.Mockito.verify; 68 69 import com.android.server.telecom.CallsManager; 70 71 /** 72 * Performs tests of the {@link VideoProvider} and {@link VideoCall} APIs. Ensures that requests 73 * sent from an InCallService are routed through Telecom to a VideoProvider, and that callbacks are 74 * correctly routed. 75 */ 76 @RunWith(JUnit4.class) 77 public class VideoProviderTest extends TelecomSystemTest { 78 private static final int ORIENTATION_0 = 0; 79 private static final int ORIENTATION_90 = 90; 80 private static final float ZOOM_LEVEL = 3.0f; 81 82 @Mock private VideoCall.Callback mVideoCallCallback; 83 private IdPair mCallIds; 84 private InCallService.VideoCall mVideoCall; 85 private VideoCallImpl mVideoCallImpl; 86 private ConnectionServiceFixture.ConnectionInfo mConnectionInfo; 87 private CountDownLatch mVerificationLock; 88 private AppOpsManager mAppOpsManager; 89 90 private Answer mVerification = new Answer() { 91 @Override 92 public Object answer(InvocationOnMock i) { 93 mVerificationLock.countDown(); 94 return null; 95 } 96 }; 97 98 @Override 99 @Before setUp()100 public void setUp() throws Exception { 101 super.setUp(); 102 mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); 103 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 104 mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities 105 |= Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL; 106 mCallIds = startAndMakeActiveOutgoingCall( 107 "650-555-1212", 108 mPhoneAccountA0.getAccountHandle(), 109 mConnectionServiceFixtureA); 110 111 // Set the video provider on the connection. 112 mConnectionServiceFixtureA.sendSetVideoProvider( 113 mConnectionServiceFixtureA.mLatestConnectionId); 114 115 // Provide a mocked VideoCall.Callback to receive callbacks via. 116 mVideoCallCallback = mock(InCallService.VideoCall.Callback.class); 117 118 mVideoCall = mInCallServiceFixtureX.getCall(mCallIds.mCallId).getVideoCallImpl( 119 mInCallServiceComponentNameX.getPackageName(), Build.VERSION.SDK_INT); 120 mVideoCallImpl = (VideoCallImpl) mVideoCall; 121 mVideoCall.registerCallback(mVideoCallCallback); 122 123 // A little hacky, but we do not want CallsManager spawning InCallTonePlayer threads. 124 CallsManager callsManager = mTelecomSystem.getCallsManager(); 125 callsManager.removeListener(callsManager.getCallAudioManager()); 126 127 mConnectionInfo = mConnectionServiceFixtureA.mConnectionById.get(mCallIds.mConnectionId); 128 mVerificationLock = new CountDownLatch(1); 129 mTelecomSystem.getCallsManager().waitOnHandlers(); 130 131 doNothing().when(mContext).enforcePermission(anyString(), anyInt(), anyInt(), anyString()); 132 doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp(anyInt(), anyInt(), 133 anyString()); 134 135 } 136 137 @Override 138 @After tearDown()139 public void tearDown() throws Exception { 140 super.tearDown(); 141 } 142 143 /** 144 * Tests the {@link VideoCall#setCamera(String)}, {@link VideoProvider#onSetCamera(String)}, 145 * and {@link VideoCall.Callback#onCameraCapabilitiesChanged(CameraCapabilities)} 146 * APIS. 147 */ 148 @MediumTest 149 @Test testCameraChange()150 public void testCameraChange() throws Exception { 151 // Wait until the callback has been received before performing verification. 152 doAnswer(mVerification).when(mVideoCallCallback) 153 .onCameraCapabilitiesChanged(any(CameraCapabilities.class)); 154 155 // Make 2 setCamera requests. 156 mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT); 157 mVideoCall.setCamera(MockVideoProvider.CAMERA_BACK); 158 159 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 160 161 // Capture the video profile reported via the callback. 162 ArgumentCaptor<CameraCapabilities> cameraCapabilitiesCaptor = 163 ArgumentCaptor.forClass(CameraCapabilities.class); 164 165 // Verify that the callback was called twice and capture the callback arguments. 166 verify(mVideoCallCallback, timeout(TEST_TIMEOUT).times(2)) 167 .onCameraCapabilitiesChanged(cameraCapabilitiesCaptor.capture()); 168 169 assertEquals(2, cameraCapabilitiesCaptor.getAllValues().size()); 170 171 List<CameraCapabilities> cameraCapabilities = cameraCapabilitiesCaptor.getAllValues(); 172 // Ensure dimensions are as expected. 173 assertEquals(MockVideoProvider.CAMERA_FRONT_DIMENSIONS, 174 cameraCapabilities.get(0).getHeight()); 175 assertEquals(MockVideoProvider.CAMERA_BACK_DIMENSIONS, 176 cameraCapabilities.get(1).getHeight()); 177 } 178 179 /** 180 * Tests the caller permission check in {@link VideoCall#setCamera(String)} to ensure a camera 181 * change from a non-permitted caller is ignored. 182 */ 183 @MediumTest 184 @Test testCameraChangePermissionFail()185 public void testCameraChangePermissionFail() throws Exception { 186 // Wait until the callback has been received before performing verification. 187 doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt()); 188 189 // ensure permission check fails. 190 doThrow(new SecurityException()).when(mContext) 191 .enforcePermission(anyString(), anyInt(), anyInt(), anyString()); 192 193 // Set the target SDK version to to > N-MR1. 194 mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT); 195 // Make a request to change the camera 196 mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT); 197 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 198 199 // Capture the session event reported via the callback. 200 ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class); 201 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent( 202 sessionEventCaptor.capture()); 203 204 assertEquals(VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR, 205 sessionEventCaptor.getValue().intValue()); 206 } 207 208 /** 209 * Tests the caller app ops check in {@link VideoCall#setCamera(String)} to ensure a camera 210 * change from a non-permitted caller is ignored. 211 */ 212 @MediumTest 213 @Test testCameraChangeAppOpsFail()214 public void testCameraChangeAppOpsFail() throws Exception { 215 // Wait until the callback has been received before performing verification. 216 doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt()); 217 218 // ensure app ops check fails. 219 doReturn(AppOpsManager.MODE_ERRORED).when(mAppOpsManager).noteOp(anyInt(), anyInt(), 220 anyString()); 221 222 // Set the target SDK version to > N-MR1. 223 mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT); 224 // Make a request to change the camera 225 mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT); 226 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 227 228 // Capture the session event reported via the callback. 229 ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class); 230 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent( 231 sessionEventCaptor.capture()); 232 233 assertEquals(VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR, 234 sessionEventCaptor.getValue().intValue()); 235 } 236 237 /** 238 * Tests the caller app ops check in {@link VideoCall#setCamera(String)} to ensure a camera 239 * change from a non-permitted caller is ignored. For < N-MR1, throw a CAMERA_FAILURE instead 240 * of a CAMERA_PERMISSION_ERROR. 241 */ 242 @MediumTest 243 @Test testCameraChangeAppOpsBelowNMR1Fail()244 public void testCameraChangeAppOpsBelowNMR1Fail() throws Exception { 245 // Wait until the callback has been received before performing verification. 246 doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt()); 247 248 // ensure app ops check fails. 249 doReturn(AppOpsManager.MODE_ERRORED).when(mAppOpsManager).noteOp(anyInt(), anyInt(), 250 anyString()); 251 252 // Set the target SDK version to below N-MR1 253 mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.N); 254 255 // Make a request to change the camera 256 mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT); 257 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 258 259 // Capture the session event reported via the callback. 260 ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class); 261 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent( 262 sessionEventCaptor.capture()); 263 264 assertEquals(VideoProvider.SESSION_EVENT_CAMERA_FAILURE, 265 sessionEventCaptor.getValue().intValue()); 266 } 267 268 /** 269 * Tests the caller user handle check in {@link VideoCall#setCamera(String)} to ensure a camera 270 * change from a background user is not permitted. 271 */ 272 @MediumTest 273 @Test testCameraChangeUserFail()274 public void testCameraChangeUserFail() throws Exception { 275 // Wait until the callback has been received before performing verification. 276 doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt()); 277 278 // Set a fake user to be the current foreground user. 279 mTelecomSystem.getCallsManager().onUserSwitch(new UserHandle(1000)); 280 281 // Set the target SDK version to > N-MR1 282 mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT); 283 // Make a request to change the camera 284 mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT); 285 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 286 287 // Capture the session event reported via the callback. 288 ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class); 289 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent( 290 sessionEventCaptor.capture()); 291 292 assertEquals(VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR, 293 sessionEventCaptor.getValue().intValue()); 294 } 295 296 /** 297 * Tests the caller permission check in {@link VideoCall#setCamera(String)} to ensure the 298 * caller can null out the camera, even if they do not have camera permission. 299 */ 300 @MediumTest 301 @Test testCameraChangeNullNoPermission()302 public void testCameraChangeNullNoPermission() throws Exception { 303 // Wait until the callback has been received before performing verification. 304 doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt()); 305 306 // ensure permission check fails. 307 doThrow(new SecurityException()).when(mContext) 308 .enforcePermission(anyString(), anyInt(), anyInt(), anyString()); 309 310 // Make a request to null the camera; we expect the permission check won't happen. 311 mVideoCall.setCamera(null); 312 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 313 314 // Capture the session event reported via the callback. 315 ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class); 316 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent( 317 sessionEventCaptor.capture()); 318 319 // See the MockVideoProvider class; for convenience when the camera is nulled we just send 320 // back a "camera ready" event. 321 assertEquals(VideoProvider.SESSION_EVENT_CAMERA_READY, 322 sessionEventCaptor.getValue().intValue()); 323 } 324 325 /** 326 * Tests the {@link VideoCall#setPreviewSurface(Surface)} and 327 * {@link VideoProvider#onSetPreviewSurface(Surface)} APIs. 328 */ 329 @MediumTest 330 @Test testSetPreviewSurface()331 public void testSetPreviewSurface() throws Exception { 332 final Surface surface = new Surface(new SurfaceTexture(1)); 333 mVideoCall.setPreviewSurface(surface); 334 335 assertTrueWithTimeout(new Predicate<Void>() { 336 @Override 337 public boolean apply(Void v) { 338 return mConnectionInfo.mockVideoProvider.getPreviewSurface() == surface; 339 } 340 }); 341 342 mVideoCall.setPreviewSurface(null); 343 344 assertTrueWithTimeout(new Predicate<Void>() { 345 @Override 346 public boolean apply(Void v) { 347 return mConnectionInfo.mockVideoProvider.getPreviewSurface() == null; 348 } 349 }); 350 } 351 352 /** 353 * Tests the {@link VideoCall#setDisplaySurface(Surface)} and 354 * {@link VideoProvider#onSetDisplaySurface(Surface)} APIs. 355 */ 356 @MediumTest 357 @Test testSetDisplaySurface()358 public void testSetDisplaySurface() throws Exception { 359 final Surface surface = new Surface(new SurfaceTexture(1)); 360 mVideoCall.setDisplaySurface(surface); 361 362 assertTrueWithTimeout(new Predicate<Void>() { 363 @Override 364 public boolean apply(Void v) { 365 return mConnectionInfo.mockVideoProvider.getDisplaySurface() == surface; 366 } 367 }); 368 369 mVideoCall.setDisplaySurface(null); 370 371 assertTrueWithTimeout(new Predicate<Void>() { 372 @Override 373 public boolean apply(Void v) { 374 return mConnectionInfo.mockVideoProvider.getDisplaySurface() == null; 375 } 376 }); 377 } 378 379 /** 380 * Tests the {@link VideoCall#setDeviceOrientation(int)} and 381 * {@link VideoProvider#onSetDeviceOrientation(int)} APIs. 382 */ 383 @MediumTest 384 @Test testSetDeviceOrientation()385 public void testSetDeviceOrientation() throws Exception { 386 mVideoCall.setDeviceOrientation(ORIENTATION_0); 387 388 assertTrueWithTimeout(new Predicate<Void>() { 389 @Override 390 public boolean apply(Void v) { 391 return mConnectionInfo.mockVideoProvider.getDeviceOrientation() == ORIENTATION_0; 392 } 393 }); 394 395 mVideoCall.setDeviceOrientation(ORIENTATION_90); 396 397 assertTrueWithTimeout(new Predicate<Void>() { 398 @Override 399 public boolean apply(Void v) { 400 return mConnectionInfo.mockVideoProvider.getDeviceOrientation() == ORIENTATION_90; 401 } 402 }); 403 } 404 405 /** 406 * Tests the {@link VideoCall#setZoom(float)} and {@link VideoProvider#onSetZoom(float)} APIs. 407 */ 408 @MediumTest 409 @Test testSetZoom()410 public void testSetZoom() throws Exception { 411 mVideoCall.setZoom(ZOOM_LEVEL); 412 413 assertTrueWithTimeout(new Predicate<Void>() { 414 @Override 415 public boolean apply(Void v) { 416 return mConnectionInfo.mockVideoProvider.getZoom() == ZOOM_LEVEL; 417 } 418 }); 419 } 420 421 /** 422 * Tests the {@link VideoCall#sendSessionModifyRequest(VideoProfile)}, 423 * {@link VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)}, 424 * {@link VideoProvider#receiveSessionModifyResponse(int, VideoProfile, VideoProfile)}, and 425 * {@link VideoCall.Callback#onSessionModifyResponseReceived(int, VideoProfile, VideoProfile)} 426 * APIs. 427 * 428 * Emulates a scenario where an InCallService sends a request to upgrade to video, which the 429 * peer accepts as-is. 430 */ 431 @MediumTest 432 @Test testSessionModifyRequest()433 public void testSessionModifyRequest() throws Exception { 434 VideoProfile requestProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL); 435 436 // Set the starting video state on the video call impl; normally this would be set based on 437 // the original android.telecom.Call instance. 438 mVideoCallImpl.setVideoState(VideoProfile.STATE_RX_ENABLED); 439 440 doAnswer(mVerification).when(mVideoCallCallback) 441 .onSessionModifyResponseReceived(anyInt(), any(VideoProfile.class), 442 any(VideoProfile.class)); 443 444 // Send the request. 445 mVideoCall.sendSessionModifyRequest(requestProfile); 446 447 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 448 449 // Capture the video profiles from the callback. 450 ArgumentCaptor<VideoProfile> fromVideoProfileCaptor = 451 ArgumentCaptor.forClass(VideoProfile.class); 452 ArgumentCaptor<VideoProfile> toVideoProfileCaptor = 453 ArgumentCaptor.forClass(VideoProfile.class); 454 455 // Verify we got a response and capture the profiles. 456 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 457 .onSessionModifyResponseReceived(eq(VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS), 458 fromVideoProfileCaptor.capture(), toVideoProfileCaptor.capture()); 459 460 assertEquals(VideoProfile.STATE_RX_ENABLED, 461 fromVideoProfileCaptor.getValue().getVideoState()); 462 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, 463 toVideoProfileCaptor.getValue().getVideoState()); 464 } 465 466 /** 467 * Tests the {@link VideoCall#sendSessionModifyResponse(VideoProfile)}, 468 * and {@link VideoProvider#onSendSessionModifyResponse(VideoProfile)} APIs. 469 */ 470 @MediumTest 471 @Test testSessionModifyResponse()472 public void testSessionModifyResponse() throws Exception { 473 VideoProfile sessionModifyResponse = new VideoProfile(VideoProfile.STATE_TX_ENABLED); 474 475 mVideoCall.sendSessionModifyResponse(sessionModifyResponse); 476 477 assertTrueWithTimeout(new Predicate<Void>() { 478 @Override 479 public boolean apply(Void v) { 480 VideoProfile response = mConnectionInfo.mockVideoProvider 481 .getSessionModifyResponse(); 482 return response != null && response.getVideoState() == VideoProfile.STATE_TX_ENABLED; 483 } 484 }); 485 } 486 487 /** 488 * Tests the {@link VideoCall#requestCameraCapabilities()} ()}, 489 * {@link VideoProvider#onRequestCameraCapabilities()} ()}, and 490 * {@link VideoCall.Callback#onCameraCapabilitiesChanged(CameraCapabilities)} APIs. 491 */ 492 @MediumTest 493 @Test testRequestCameraCapabilities()494 public void testRequestCameraCapabilities() throws Exception { 495 // Wait until the callback has been received before performing verification. 496 doAnswer(mVerification).when(mVideoCallCallback) 497 .onCameraCapabilitiesChanged(any(CameraCapabilities.class)); 498 499 mVideoCall.requestCameraCapabilities(); 500 501 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 502 503 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 504 .onCameraCapabilitiesChanged(any(CameraCapabilities.class)); 505 } 506 507 /** 508 * Tests the {@link VideoCall#setPauseImage(Uri)}, and 509 * {@link VideoProvider#onSetPauseImage(Uri)} APIs. 510 */ 511 @MediumTest 512 @Test testSetPauseImage()513 public void testSetPauseImage() throws Exception { 514 final Uri testUri = Uri.fromParts("file", "test.jpg", null); 515 mVideoCall.setPauseImage(testUri); 516 517 assertTrueWithTimeout(new Predicate<Void>() { 518 @Override 519 public boolean apply(Void v) { 520 Uri pauseImage = mConnectionInfo.mockVideoProvider.getPauseImage(); 521 return pauseImage != null && pauseImage.equals(testUri); 522 } 523 }); 524 } 525 526 /** 527 * Tests the {@link VideoCall#requestCallDataUsage()}, 528 * {@link VideoProvider#onRequestConnectionDataUsage()}, and 529 * {@link VideoCall.Callback#onCallDataUsageChanged(long)} APIs. 530 */ 531 @MediumTest 532 @Test testRequestDataUsage()533 public void testRequestDataUsage() throws Exception { 534 // Wait until the callback has been received before performing verification. 535 doAnswer(mVerification).when(mVideoCallCallback) 536 .onCallDataUsageChanged(anyLong()); 537 538 mVideoCall.requestCallDataUsage(); 539 540 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 541 542 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 543 .onCallDataUsageChanged(eq(MockVideoProvider.DATA_USAGE)); 544 } 545 546 /** 547 * Tests the {@link VideoProvider#receiveSessionModifyRequest(VideoProfile)}, 548 * {@link VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)} APIs. 549 */ 550 @MediumTest 551 @Test testReceiveSessionModifyRequest()552 public void testReceiveSessionModifyRequest() throws Exception { 553 // Wait until the callback has been received before performing verification. 554 doAnswer(mVerification).when(mVideoCallCallback) 555 .onSessionModifyRequestReceived(any(VideoProfile.class)); 556 557 mConnectionInfo.mockVideoProvider.sendMockSessionModifyRequest(); 558 559 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 560 561 ArgumentCaptor<VideoProfile> requestProfileCaptor = 562 ArgumentCaptor.forClass(VideoProfile.class); 563 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 564 .onSessionModifyRequestReceived(requestProfileCaptor.capture()); 565 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, 566 requestProfileCaptor.getValue().getVideoState()); 567 } 568 569 570 /** 571 * Tests the {@link VideoProvider#handleCallSessionEvent(int)}, and 572 * {@link VideoCall.Callback#onCallSessionEvent(int)} APIs. 573 */ 574 @MediumTest 575 @Test testSessionEvent()576 public void testSessionEvent() throws Exception { 577 // Wait until the callback has been received before performing verification. 578 doAnswer(mVerification).when(mVideoCallCallback) 579 .onCallSessionEvent(anyInt()); 580 581 mConnectionInfo.mockVideoProvider.sendMockSessionEvent( 582 VideoProvider.SESSION_EVENT_CAMERA_READY); 583 584 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 585 586 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 587 .onCallSessionEvent(eq(VideoProvider.SESSION_EVENT_CAMERA_READY)); 588 } 589 590 /** 591 * Tests the {@link VideoProvider#changePeerDimensions(int, int)} and 592 * {@link VideoCall.Callback#onPeerDimensionsChanged(int, int)} APIs. 593 */ 594 @MediumTest 595 @Test testPeerDimensionChange()596 public void testPeerDimensionChange() throws Exception { 597 // Wait until the callback has been received before performing verification. 598 doAnswer(mVerification).when(mVideoCallCallback) 599 .onPeerDimensionsChanged(anyInt(), anyInt()); 600 601 mConnectionInfo.mockVideoProvider.sendMockPeerDimensions(MockVideoProvider.PEER_DIMENSIONS, 602 MockVideoProvider.PEER_DIMENSIONS); 603 604 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 605 606 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 607 .onPeerDimensionsChanged(eq(MockVideoProvider.PEER_DIMENSIONS), 608 eq(MockVideoProvider.PEER_DIMENSIONS)); 609 } 610 611 /** 612 * Tests the {@link VideoProvider#changeVideoQuality(int)} and 613 * {@link VideoCall.Callback#onVideoQualityChanged(int)} APIs. 614 */ 615 @MediumTest 616 @Test testVideoQualityChange()617 public void testVideoQualityChange() throws Exception { 618 // Wait until the callback has been received before performing verification. 619 doAnswer(mVerification).when(mVideoCallCallback) 620 .onVideoQualityChanged(anyInt()); 621 622 mConnectionInfo.mockVideoProvider.sendMockVideoQuality(VideoProfile.QUALITY_HIGH); 623 624 mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS); 625 626 verify(mVideoCallCallback, timeout(TEST_TIMEOUT)) 627 .onVideoQualityChanged(eq(VideoProfile.QUALITY_HIGH)); 628 } 629 } 630