• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2022 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.telephony.imsmedia;
18 
19 import static org.junit.Assert.fail;
20 import static org.mockito.Mockito.eq;
21 import static org.mockito.Mockito.times;
22 import static org.mockito.Mockito.verify;
23 
24 import android.graphics.ImageFormat;
25 import android.media.ImageReader;
26 import android.os.Looper;
27 import android.os.Parcel;
28 import android.os.ParcelFileDescriptor;
29 import android.os.RemoteException;
30 import android.telephony.ims.RtpHeaderExtension;
31 import android.telephony.imsmedia.IImsVideoSessionCallback;
32 import android.telephony.imsmedia.ImsMediaSession;
33 import android.telephony.imsmedia.MediaQualityThreshold;
34 import android.telephony.imsmedia.VideoConfig;
35 import android.testing.AndroidTestingRunner;
36 import android.testing.TestableLooper;
37 import android.view.Surface;
38 
39 import com.android.telephony.imsmedia.Utils.OpenSessionParams;
40 
41 import org.junit.After;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 
48 import java.net.DatagramSocket;
49 import java.net.SocketException;
50 import java.util.ArrayList;
51 
52 @RunWith(AndroidTestingRunner.class)
53 @TestableLooper.RunWithLooper
54 public class VideoSessionTest extends ImsMediaTest {
55     private static final int SESSION_ID = 1;
56     private static final int UNUSED = -1;
57     private static final int SUCCESS = ImsMediaSession.RESULT_SUCCESS;
58     private static final int NO_RESOURCES = ImsMediaSession.RESULT_NO_RESOURCES;
59     private static final int RTP = ImsMediaSession.PACKET_TYPE_RTP;
60     private static final int RTCP = ImsMediaSession.PACKET_TYPE_RTCP;
61     private static final int RESOLUTION_WIDTH = 640;
62     private static final int RESOLUTION_HEIGHT = 480;
63     private static final long VIDEO_DATA = 1024;
64     private static final int PACKET_LOSS = 15;
65     private static final Surface PREVIEW_SURFACE = ImageReader.newInstance(
66             RESOLUTION_WIDTH, RESOLUTION_HEIGHT, ImageFormat.JPEG, 1).getSurface();
67     private static final Surface DISPLAY_SURFACE = ImageReader.newInstance(
68             RESOLUTION_WIDTH, RESOLUTION_HEIGHT, ImageFormat.JPEG, 1).getSurface();
69     private VideoSession mVideoSession;
70     private VideoSession.VideoSessionHandler mHandler;
71     @Mock
72     private VideoService mVideoService;
73     private VideoListener mVideoListener;
74     @Mock
75     private VideoLocalSession mVideoLocalSession;
76     @Mock
77     private IImsVideoSessionCallback mCallback;
78     private TestableLooper mLooper;
79 
80     @Before
setUp()81     public void setUp() {
82         MockitoAnnotations.initMocks(this);
83         mVideoSession = new VideoSession(SESSION_ID, mCallback,
84                 mVideoService, mVideoLocalSession, Looper.myLooper());
85         mVideoListener = mVideoSession.getVideoListener();
86         mHandler = mVideoSession.getVideoSessionHandler();
87         mTestClass = VideoSessionTest.this;
88         super.setUp();
89     }
90 
91     @After
tearDown()92     public void tearDown() throws Exception {
93         super.tearDown();
94     }
95 
createParcel(int message, int result, VideoConfig config)96     private Parcel createParcel(int message, int result, VideoConfig config) {
97         Parcel parcel = Parcel.obtain();
98         parcel.writeInt(message);
99         parcel.writeInt(result);
100         if (config != null) {
101             config.writeToParcel(parcel, 0);
102         }
103         parcel.setDataPosition(0);
104         return parcel;
105     }
106 
107     @Test
testOpenSession()108     public void testOpenSession() {
109         DatagramSocket rtpSocket = null;
110         DatagramSocket rtcpSocket = null;
111 
112         try {
113             rtpSocket = new DatagramSocket();
114             rtcpSocket = new DatagramSocket();
115         } catch (SocketException e) {
116             fail("SocketException:" + e);
117         }
118 
119         OpenSessionParams params = new OpenSessionParams(
120                 ParcelFileDescriptor.fromDatagramSocket(rtpSocket),
121                 ParcelFileDescriptor.fromDatagramSocket(rtcpSocket),
122                 null, null);
123 
124         mVideoSession.openSession(params);
125         processAllMessages();
126         verify(mVideoService, times(1)).openSession(eq(SESSION_ID), eq(params));
127     }
128 
129     @Test
testCloseSession()130     public void testCloseSession() {
131         mVideoSession.closeSession();
132         processAllMessages();
133         verify(mVideoService, times(1)).closeSession(eq(SESSION_ID));
134     }
135 
136     @Test
testModifySession()137     public void testModifySession() {
138         // Modify Session Request
139         VideoConfig config = VideoConfigTest.createVideoConfig();
140         mVideoSession.modifySession(config);
141         processAllMessages();
142         verify(mVideoLocalSession, times(1)).modifySession(eq(config));
143 
144         // Modify Session Response - Success
145         mVideoListener.onMessage(
146                 createParcel(VideoSession.EVENT_MODIFY_SESSION_RESPONSE, SUCCESS, config));
147         processAllMessages();
148         try {
149             verify(mCallback, times(1)).onModifySessionResponse(eq(config), eq(SUCCESS));
150         } catch (RemoteException e) {
151             fail("Failed to notify modify session response: " + e);
152         }
153 
154         // Modify Session Response - Failure (NO_RESOURCES)
155         mVideoListener.onMessage(
156                 createParcel(VideoSession.EVENT_MODIFY_SESSION_RESPONSE, NO_RESOURCES, config));
157         processAllMessages();
158         try {
159             verify(mCallback, times(1)).onModifySessionResponse(eq(config), eq(NO_RESOURCES));
160         } catch (RemoteException e) {
161             fail("Failed to notify modify session response: " + e);
162         }
163     }
164 
165     @Test
testSurfaces()166     public void testSurfaces() {
167         Utils.sendMessage(mHandler, VideoSession.CMD_SET_PREVIEW_SURFACE, PREVIEW_SURFACE);
168         processAllMessages();
169         verify(mVideoLocalSession, times(1)).setPreviewSurface(eq(PREVIEW_SURFACE));
170 
171         Utils.sendMessage(mHandler, VideoSession.CMD_SET_DISPLAY_SURFACE, DISPLAY_SURFACE);
172         processAllMessages();
173         verify(mVideoLocalSession, times(1)).setDisplaySurface(eq(DISPLAY_SURFACE));
174     }
175 
176     @Test
testSetMediaQualityThreshold()177     public void testSetMediaQualityThreshold() {
178         // Set Media Quality Threshold
179         MediaQualityThreshold threshold = MediaQualityThresholdTest.createMediaQualityThreshold();
180         mVideoSession.setMediaQualityThreshold(threshold);
181         processAllMessages();
182         verify(mVideoLocalSession, times(1)).setMediaQualityThreshold(eq(threshold));
183     }
184 
185     @Test
testRequestVideoDataUsage()186     public void testRequestVideoDataUsage() {
187         mVideoSession.requestVideoDataUsage();
188         processAllMessages();
189         verify(mVideoLocalSession, times(1)).requestVideoDataUsage();
190     }
191 
192     @Test
testMediaInactivityInd()193     public void testMediaInactivityInd() {
194         // Receive Inactivity - RTP
195         Parcel parcel = Parcel.obtain();
196         parcel.writeInt(VideoSession.EVENT_MEDIA_INACTIVITY_IND);
197         parcel.writeInt(RTP);
198         parcel.setDataPosition(0);
199         mVideoListener.onMessage(parcel);
200         processAllMessages();
201         try {
202             verify(mCallback, times(1)).notifyMediaInactivity(eq(RTP));
203         } catch (RemoteException e) {
204             fail("Failed to notify media inactivity: " + e);
205         }
206 
207         // Receive Inactivity - RTCP
208         Parcel parcel2 = Parcel.obtain();
209         parcel2.writeInt(VideoSession.EVENT_MEDIA_INACTIVITY_IND);
210         parcel2.writeInt(RTCP);
211         parcel2.setDataPosition(0);
212         mVideoListener.onMessage(parcel2);
213         processAllMessages();
214         try {
215             verify(mCallback, times(1)).notifyMediaInactivity(eq(RTCP));
216         } catch (RemoteException e) {
217             fail("Failed to notify media inactivity: " + e);
218         }
219     }
220 
221     @Test
testPeerDimensionChanged()222     public void testPeerDimensionChanged() {
223         // received video frame resolution changed
224         Parcel parcel = Parcel.obtain();
225         parcel.writeInt(VideoSession.EVENT_PEER_DIMENSION_CHANGED);
226         parcel.writeInt(RESOLUTION_WIDTH);
227         parcel.writeInt(RESOLUTION_HEIGHT);
228         parcel.setDataPosition(0);
229         mVideoListener.onMessage(parcel);
230         processAllMessages();
231         try {
232             verify(mCallback, times(1)).onPeerDimensionChanged(
233                     eq(RESOLUTION_WIDTH), eq(RESOLUTION_HEIGHT));
234         } catch (RemoteException e) {
235             fail("Failed to notify peer dimension changed: " + e);
236         }
237     }
238 
239     @Test
testNotifyVideoDataUsage()240     public void testNotifyVideoDataUsage() {
241         Parcel parcel = Parcel.obtain();
242         parcel.writeInt(VideoSession.EVENT_VIDEO_DATA_USAGE_IND);
243         parcel.writeLong(VIDEO_DATA);
244         parcel.setDataPosition(0);
245         mVideoListener.onMessage(parcel);
246         processAllMessages();
247         try {
248             verify(mCallback, times(1)).notifyVideoDataUsage(eq(VIDEO_DATA));
249         } catch (RemoteException e) {
250             fail("Failed to notify video data usage: " + e);
251         }
252     }
253 
254     @Test
testFirstMediaPacketReceivedInd()255     public void testFirstMediaPacketReceivedInd() {
256         // Receive First MediaPacket Received Indication
257         VideoConfig config = VideoConfigTest.createVideoConfig();
258         Utils.sendMessage(mHandler, VideoSession.EVENT_FIRST_MEDIA_PACKET_IND, config);
259         processAllMessages();
260         try {
261             verify(mCallback, times(1)).onFirstMediaPacketReceived(eq(config));
262         } catch (RemoteException e) {
263             fail("Failed to notify first media packet received: " + e);
264         }
265     }
266 
267     @Test
testHeaderExtension()268     public void testHeaderExtension() {
269         // Send RtpHeaderExtension
270         ArrayList extensions = new ArrayList<RtpHeaderExtension>();
271         mVideoSession.sendHeaderExtension(extensions);
272         processAllMessages();
273         verify(mVideoLocalSession, times(1)).sendHeaderExtension(eq(extensions));
274 
275         // Receive RtpHeaderExtension
276         Utils.sendMessage(mHandler, VideoSession.EVENT_RTP_HEADER_EXTENSION_IND, extensions);
277         processAllMessages();
278         try {
279             verify(mCallback, times(1)).onHeaderExtensionReceived(eq(extensions));
280         } catch (RemoteException e) {
281             fail("Failed to notify header extension received: " + e);
282         }
283     }
284 
285     @Test
testPacketLossInd()286     public void testPacketLossInd() {
287         // Receive Packet Loss
288         Utils.sendMessage(mHandler, VideoSession.EVENT_NOTIFY_BITRATE_IND, PACKET_LOSS, UNUSED);
289         processAllMessages();
290         try {
291             verify(mCallback, times(1)).notifyBitrate(eq(PACKET_LOSS));
292         } catch (RemoteException e) {
293             fail("Failed to notify notifyBitrate: " + e);
294         }
295     }
296 
297     @Test
testOpenSessionSuccess()298     public void testOpenSessionSuccess() {
299         mVideoSession.onOpenSessionSuccess(mVideoLocalSession);
300         processAllMessages();
301         try {
302             verify(mCallback, times(1)).onOpenSessionSuccess(mVideoSession);
303         } catch (RemoteException e) {
304             fail("Failed to notify onOpenSessionSuccess: " + e);
305         }
306     }
307 
308     @Test
testOpenSessionFailure()309     public void testOpenSessionFailure() {
310         mVideoSession.onOpenSessionFailure(ImsMediaSession.RESULT_INVALID_PARAM);
311         processAllMessages();
312         try {
313             verify(mCallback, times(1)).onOpenSessionFailure(ImsMediaSession.RESULT_INVALID_PARAM);
314         } catch (RemoteException e) {
315             fail("Failed to notify onOpenSessionFailure: " + e);
316         }
317     }
318 
319     @Test
testSessionClosed()320     public void testSessionClosed() {
321         mVideoSession.onSessionClosed();
322         processAllMessages();
323         try {
324             verify(mCallback, times(1)).onSessionClosed();
325         } catch (RemoteException e) {
326             fail("Failed to notify onSessionClosed: " + e);
327         }
328     }
329 }
330