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