Bug 1848242 - Mark basic.any.html subtest as intermittent. a=test-only
[gecko.git] / third_party / libwebrtc / pc / peer_connection_interface_unittest.cc
blob3023be1493b048703705c45ca3b3ef402a26ab62
1 /*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
11 #include "api/peer_connection_interface.h"
13 #include <limits.h>
14 #include <stdint.h>
16 #include <string>
17 #include <utility>
18 #include <vector>
20 #include "absl/strings/str_replace.h"
21 #include "absl/types/optional.h"
22 #include "api/audio/audio_mixer.h"
23 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
24 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
25 #include "api/call/call_factory_interface.h"
26 #include "api/create_peerconnection_factory.h"
27 #include "api/data_channel_interface.h"
28 #include "api/jsep.h"
29 #include "api/media_stream_interface.h"
30 #include "api/media_types.h"
31 #include "api/rtc_error.h"
32 #include "api/rtc_event_log/rtc_event_log.h"
33 #include "api/rtc_event_log/rtc_event_log_factory.h"
34 #include "api/rtc_event_log_output.h"
35 #include "api/rtp_receiver_interface.h"
36 #include "api/rtp_sender_interface.h"
37 #include "api/rtp_transceiver_direction.h"
38 #include "api/scoped_refptr.h"
39 #include "api/task_queue/default_task_queue_factory.h"
40 #include "api/transport/field_trial_based_config.h"
41 #include "api/video_codecs/video_decoder_factory_template.h"
42 #include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
43 #include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
44 #include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
45 #include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
46 #include "api/video_codecs/video_encoder_factory_template.h"
47 #include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
48 #include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
49 #include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
50 #include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
51 #include "media/base/codec.h"
52 #include "media/base/media_config.h"
53 #include "media/base/media_engine.h"
54 #include "media/base/stream_params.h"
55 #include "media/engine/webrtc_media_engine.h"
56 #include "media/engine/webrtc_media_engine_defaults.h"
57 #include "media/sctp/sctp_transport_internal.h"
58 #include "modules/audio_device/include/audio_device.h"
59 #include "modules/audio_processing/include/audio_processing.h"
60 #include "p2p/base/fake_port_allocator.h"
61 #include "p2p/base/p2p_constants.h"
62 #include "p2p/base/port.h"
63 #include "p2p/base/port_allocator.h"
64 #include "p2p/base/transport_description.h"
65 #include "p2p/base/transport_info.h"
66 #include "pc/audio_track.h"
67 #include "pc/media_session.h"
68 #include "pc/media_stream.h"
69 #include "pc/peer_connection.h"
70 #include "pc/peer_connection_factory.h"
71 #include "pc/rtp_sender.h"
72 #include "pc/rtp_sender_proxy.h"
73 #include "pc/session_description.h"
74 #include "pc/stream_collection.h"
75 #include "pc/test/fake_audio_capture_module.h"
76 #include "pc/test/fake_rtc_certificate_generator.h"
77 #include "pc/test/fake_video_track_source.h"
78 #include "pc/test/mock_peer_connection_observers.h"
79 #include "pc/test/test_sdp_strings.h"
80 #include "pc/video_track.h"
81 #include "rtc_base/checks.h"
82 #include "rtc_base/gunit.h"
83 #include "rtc_base/rtc_certificate_generator.h"
84 #include "rtc_base/socket_address.h"
85 #include "rtc_base/thread.h"
86 #include "rtc_base/virtual_socket_server.h"
87 #include "test/gmock.h"
88 #include "test/gtest.h"
89 #include "test/scoped_key_value_config.h"
91 #ifdef WEBRTC_ANDROID
92 #include "pc/test/android_test_initializer.h"
93 #endif
95 namespace webrtc {
96 namespace {
98 static const char kStreamId1[] = "local_stream_1";
99 static const char kStreamId2[] = "local_stream_2";
100 static const char kStreamId3[] = "local_stream_3";
101 static const int kDefaultStunPort = 3478;
102 static const char kStunAddressOnly[] = "stun:address";
103 static const char kStunInvalidPort[] = "stun:address:-1";
104 static const char kStunAddressPortAndMore1[] = "stun:address:port:more";
105 static const char kStunAddressPortAndMore2[] = "stun:address:port more";
106 static const char kTurnIceServerUri[] = "turn:turn.example.org";
107 static const char kTurnUsername[] = "user";
108 static const char kTurnPassword[] = "password";
109 static const char kTurnHostname[] = "turn.example.org";
110 static const uint32_t kTimeout = 10000U;
112 static const char kStreams[][8] = {"stream1", "stream2"};
113 static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
114 static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
116 static const char kRecvonly[] = "recvonly";
117 static const char kSendrecv[] = "sendrecv";
118 constexpr uint64_t kTiebreakerDefault = 44444;
120 // Reference SDP with a MediaStream with label "stream1" and audio track with
121 // id "audio_1" and a video track with id "video_1;
122 static const char kSdpStringWithStream1PlanB[] =
123 "v=0\r\n"
124 "o=- 0 0 IN IP4 127.0.0.1\r\n"
125 "s=-\r\n"
126 "t=0 0\r\n"
127 "m=audio 1 RTP/AVPF 111\r\n"
128 "a=ice-ufrag:e5785931\r\n"
129 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
130 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
131 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
132 "a=mid:audio\r\n"
133 "a=sendrecv\r\n"
134 "a=rtcp-mux\r\n"
135 "a=rtpmap:111 OPUS/48000/2\r\n"
136 "a=ssrc:1 cname:stream1\r\n"
137 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
138 "m=video 1 RTP/AVPF 120\r\n"
139 "a=ice-ufrag:e5785931\r\n"
140 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
141 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
142 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
143 "a=mid:video\r\n"
144 "a=sendrecv\r\n"
145 "a=rtcp-mux\r\n"
146 "a=rtpmap:120 VP8/90000\r\n"
147 "a=ssrc:2 cname:stream1\r\n"
148 "a=ssrc:2 msid:stream1 videotrack0\r\n";
149 // Same string as above but with the MID changed to the Unified Plan default and
150 // a=msid added. This is needed so that this SDP can be used as an answer for a
151 // Unified Plan offer.
152 static const char kSdpStringWithStream1UnifiedPlan[] =
153 "v=0\r\n"
154 "o=- 0 0 IN IP4 127.0.0.1\r\n"
155 "s=-\r\n"
156 "t=0 0\r\n"
157 "m=audio 1 RTP/AVPF 111\r\n"
158 "a=ice-ufrag:e5785931\r\n"
159 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
160 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
161 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
162 "a=mid:0\r\n"
163 "a=sendrecv\r\n"
164 "a=rtcp-mux\r\n"
165 "a=rtpmap:111 OPUS/48000/2\r\n"
166 "a=msid:stream1 audiotrack0\r\n"
167 "a=ssrc:1 cname:stream1\r\n"
168 "m=video 1 RTP/AVPF 120\r\n"
169 "a=ice-ufrag:e5785931\r\n"
170 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
171 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
172 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
173 "a=mid:1\r\n"
174 "a=sendrecv\r\n"
175 "a=rtcp-mux\r\n"
176 "a=rtpmap:120 VP8/90000\r\n"
177 "a=msid:stream1 videotrack0\r\n"
178 "a=ssrc:2 cname:stream1\r\n";
180 // Reference SDP with a MediaStream with label "stream1" and audio track with
181 // id "audio_1";
182 static const char kSdpStringWithStream1AudioTrackOnly[] =
183 "v=0\r\n"
184 "o=- 0 0 IN IP4 127.0.0.1\r\n"
185 "s=-\r\n"
186 "t=0 0\r\n"
187 "m=audio 1 RTP/AVPF 111\r\n"
188 "a=ice-ufrag:e5785931\r\n"
189 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
190 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
191 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
192 "a=mid:audio\r\n"
193 "a=sendrecv\r\n"
194 "a=rtpmap:111 OPUS/48000/2\r\n"
195 "a=ssrc:1 cname:stream1\r\n"
196 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
197 "a=rtcp-mux\r\n";
199 // Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
200 // MediaStreams have one audio track and one video track.
201 // This uses MSID.
202 static const char kSdpStringWithStream1And2PlanB[] =
203 "v=0\r\n"
204 "o=- 0 0 IN IP4 127.0.0.1\r\n"
205 "s=-\r\n"
206 "t=0 0\r\n"
207 "a=msid-semantic: WMS stream1 stream2\r\n"
208 "m=audio 1 RTP/AVPF 111\r\n"
209 "a=ice-ufrag:e5785931\r\n"
210 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
211 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
212 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
213 "a=mid:audio\r\n"
214 "a=sendrecv\r\n"
215 "a=rtcp-mux\r\n"
216 "a=rtpmap:111 OPUS/48000/2\r\n"
217 "a=ssrc:1 cname:stream1\r\n"
218 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
219 "a=ssrc:3 cname:stream2\r\n"
220 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
221 "m=video 1 RTP/AVPF 120\r\n"
222 "a=ice-ufrag:e5785931\r\n"
223 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
224 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
225 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
226 "a=mid:video\r\n"
227 "a=sendrecv\r\n"
228 "a=rtcp-mux\r\n"
229 "a=rtpmap:120 VP8/0\r\n"
230 "a=ssrc:2 cname:stream1\r\n"
231 "a=ssrc:2 msid:stream1 videotrack0\r\n"
232 "a=ssrc:4 cname:stream2\r\n"
233 "a=ssrc:4 msid:stream2 videotrack1\r\n";
234 static const char kSdpStringWithStream1And2UnifiedPlan[] =
235 "v=0\r\n"
236 "o=- 0 0 IN IP4 127.0.0.1\r\n"
237 "s=-\r\n"
238 "t=0 0\r\n"
239 "a=msid-semantic: WMS stream1 stream2\r\n"
240 "m=audio 1 RTP/AVPF 111\r\n"
241 "a=ice-ufrag:e5785931\r\n"
242 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
243 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
244 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
245 "a=mid:0\r\n"
246 "a=sendrecv\r\n"
247 "a=rtcp-mux\r\n"
248 "a=rtpmap:111 OPUS/48000/2\r\n"
249 "a=ssrc:1 cname:stream1\r\n"
250 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
251 "m=video 1 RTP/AVPF 120\r\n"
252 "a=ice-ufrag:e5785931\r\n"
253 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
254 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
255 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
256 "a=mid:1\r\n"
257 "a=sendrecv\r\n"
258 "a=rtcp-mux\r\n"
259 "a=rtpmap:120 VP8/0\r\n"
260 "a=ssrc:2 cname:stream1\r\n"
261 "a=ssrc:2 msid:stream1 videotrack0\r\n"
262 "m=audio 1 RTP/AVPF 111\r\n"
263 "a=ice-ufrag:e5785931\r\n"
264 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
265 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
266 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
267 "a=mid:2\r\n"
268 "a=sendrecv\r\n"
269 "a=rtcp-mux\r\n"
270 "a=rtpmap:111 OPUS/48000/2\r\n"
271 "a=ssrc:3 cname:stream2\r\n"
272 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
273 "m=video 1 RTP/AVPF 120\r\n"
274 "a=ice-ufrag:e5785931\r\n"
275 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
276 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
277 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
278 "a=mid:3\r\n"
279 "a=sendrecv\r\n"
280 "a=rtcp-mux\r\n"
281 "a=rtpmap:120 VP8/0\r\n"
282 "a=ssrc:4 cname:stream2\r\n"
283 "a=ssrc:4 msid:stream2 videotrack1\r\n";
285 // Reference SDP without MediaStreams. Msid is not supported.
286 static const char kSdpStringWithoutStreams[] =
287 "v=0\r\n"
288 "o=- 0 0 IN IP4 127.0.0.1\r\n"
289 "s=-\r\n"
290 "t=0 0\r\n"
291 "m=audio 1 RTP/AVPF 111\r\n"
292 "a=ice-ufrag:e5785931\r\n"
293 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
294 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
295 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
296 "a=mid:audio\r\n"
297 "a=sendrecv\r\n"
298 "a=rtcp-mux\r\n"
299 "a=rtpmap:111 OPUS/48000/2\r\n"
300 "m=video 1 RTP/AVPF 120\r\n"
301 "a=ice-ufrag:e5785931\r\n"
302 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
303 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
304 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
305 "a=mid:video\r\n"
306 "a=sendrecv\r\n"
307 "a=rtcp-mux\r\n"
308 "a=rtpmap:120 VP8/90000\r\n";
310 // Reference SDP without MediaStreams. Msid is supported.
311 static const char kSdpStringWithMsidWithoutStreams[] =
312 "v=0\r\n"
313 "o=- 0 0 IN IP4 127.0.0.1\r\n"
314 "s=-\r\n"
315 "t=0 0\r\n"
316 "a=msid-semantic: WMS\r\n"
317 "m=audio 1 RTP/AVPF 111\r\n"
318 "a=ice-ufrag:e5785931\r\n"
319 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
320 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
321 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
322 "a=mid:audio\r\n"
323 "a=sendrecv\r\n"
324 "a=rtcp-mux\r\n"
325 "a=rtpmap:111 OPUS/48000/2\r\n"
326 "m=video 1 RTP/AVPF 120\r\n"
327 "a=ice-ufrag:e5785931\r\n"
328 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
329 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
330 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
331 "a=mid:video\r\n"
332 "a=sendrecv\r\n"
333 "a=rtcp-mux\r\n"
334 "a=rtpmap:120 VP8/90000\r\n";
336 // Reference SDP without MediaStreams and audio only.
337 static const char kSdpStringWithoutStreamsAudioOnly[] =
338 "v=0\r\n"
339 "o=- 0 0 IN IP4 127.0.0.1\r\n"
340 "s=-\r\n"
341 "t=0 0\r\n"
342 "m=audio 1 RTP/AVPF 111\r\n"
343 "a=ice-ufrag:e5785931\r\n"
344 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
345 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
346 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
347 "a=mid:audio\r\n"
348 "a=sendrecv\r\n"
349 "a=rtcp-mux\r\n"
350 "a=rtpmap:111 OPUS/48000/2\r\n";
352 // Reference SENDONLY SDP without MediaStreams. Msid is not supported.
353 static const char kSdpStringSendOnlyWithoutStreams[] =
354 "v=0\r\n"
355 "o=- 0 0 IN IP4 127.0.0.1\r\n"
356 "s=-\r\n"
357 "t=0 0\r\n"
358 "m=audio 1 RTP/AVPF 111\r\n"
359 "a=ice-ufrag:e5785931\r\n"
360 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
361 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
362 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
363 "a=mid:audio\r\n"
364 "a=sendrecv\r\n"
365 "a=sendonly\r\n"
366 "a=rtcp-mux\r\n"
367 "a=rtpmap:111 OPUS/48000/2\r\n"
368 "m=video 1 RTP/AVPF 120\r\n"
369 "a=ice-ufrag:e5785931\r\n"
370 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
371 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
372 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
373 "a=mid:video\r\n"
374 "a=sendrecv\r\n"
375 "a=sendonly\r\n"
376 "a=rtcp-mux\r\n"
377 "a=rtpmap:120 VP8/90000\r\n";
379 static const char kSdpStringInit[] =
380 "v=0\r\n"
381 "o=- 0 0 IN IP4 127.0.0.1\r\n"
382 "s=-\r\n"
383 "t=0 0\r\n"
384 "a=msid-semantic: WMS\r\n";
386 static const char kSdpStringAudio[] =
387 "m=audio 1 RTP/AVPF 111\r\n"
388 "a=ice-ufrag:e5785931\r\n"
389 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
390 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
391 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
392 "a=mid:audio\r\n"
393 "a=sendrecv\r\n"
394 "a=rtcp-mux\r\n"
395 "a=rtpmap:111 OPUS/48000/2\r\n";
397 static const char kSdpStringVideo[] =
398 "m=video 1 RTP/AVPF 120\r\n"
399 "a=ice-ufrag:e5785931\r\n"
400 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
401 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
402 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
403 "a=mid:video\r\n"
404 "a=sendrecv\r\n"
405 "a=rtcp-mux\r\n"
406 "a=rtpmap:120 VP8/90000\r\n";
408 static const char kSdpStringMs1Audio0[] =
409 "a=ssrc:1 cname:stream1\r\n"
410 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
412 static const char kSdpStringMs1Video0[] =
413 "a=ssrc:2 cname:stream1\r\n"
414 "a=ssrc:2 msid:stream1 videotrack0\r\n";
416 static const char kSdpStringMs1Audio1[] =
417 "a=ssrc:3 cname:stream1\r\n"
418 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
420 static const char kSdpStringMs1Video1[] =
421 "a=ssrc:4 cname:stream1\r\n"
422 "a=ssrc:4 msid:stream1 videotrack1\r\n";
424 static const char kDtlsSdesFallbackSdp[] =
425 "v=0\r\n"
426 "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n"
427 "s=-\r\n"
428 "c=IN IP4 0.0.0.0\r\n"
429 "t=0 0\r\n"
430 "a=group:BUNDLE audio\r\n"
431 "a=msid-semantic: WMS\r\n"
432 "m=audio 1 RTP/SAVPF 0\r\n"
433 "a=sendrecv\r\n"
434 "a=rtcp-mux\r\n"
435 "a=mid:audio\r\n"
436 "a=ssrc:1 cname:stream1\r\n"
437 "a=ice-ufrag:e5785931\r\n"
438 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
439 "a=rtpmap:0 pcmu/8000\r\n"
440 "a=fingerprint:sha-1 "
441 "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
442 "a=setup:actpass\r\n"
443 "a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
444 "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
445 "dummy_session_params\r\n";
447 class RtcEventLogOutputNull final : public RtcEventLogOutput {
448 public:
449 bool IsActive() const override { return true; }
450 bool Write(const absl::string_view /*output*/) override { return true; }
453 using ::cricket::StreamParams;
454 using ::testing::Eq;
455 using ::testing::Exactly;
456 using ::testing::SizeIs;
457 using ::testing::Values;
459 using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
460 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
462 // Gets the first ssrc of given content type from the ContentInfo.
463 bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
464 if (!content_info || !ssrc) {
465 return false;
467 const cricket::MediaContentDescription* media_desc =
468 content_info->media_description();
469 if (!media_desc || media_desc->streams().empty()) {
470 return false;
472 *ssrc = media_desc->streams().begin()->first_ssrc();
473 return true;
476 // Get the ufrags out of an SDP blob. Useful for testing ICE restart
477 // behavior.
478 std::vector<std::string> GetUfrags(
479 const webrtc::SessionDescriptionInterface* desc) {
480 std::vector<std::string> ufrags;
481 for (const cricket::TransportInfo& info :
482 desc->description()->transport_infos()) {
483 ufrags.push_back(info.description.ice_ufrag);
485 return ufrags;
488 void SetSsrcToZero(std::string* sdp) {
489 const char kSdpSsrcAtribute[] = "a=ssrc:";
490 const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
491 size_t ssrc_pos = 0;
492 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
493 std::string::npos) {
494 size_t end_ssrc = sdp->find(" ", ssrc_pos);
495 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
496 ssrc_pos = end_ssrc;
500 // Check if `streams` contains the specified track.
501 bool ContainsTrack(const std::vector<cricket::StreamParams>& streams,
502 const std::string& stream_id,
503 const std::string& track_id) {
504 for (const cricket::StreamParams& params : streams) {
505 if (params.first_stream_id() == stream_id && params.id == track_id) {
506 return true;
509 return false;
512 // Check if `senders` contains the specified sender, by id.
513 bool ContainsSender(
514 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
515 const std::string& id) {
516 for (const auto& sender : senders) {
517 if (sender->id() == id) {
518 return true;
521 return false;
524 // Check if `senders` contains the specified sender, by id and stream id.
525 bool ContainsSender(
526 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
527 const std::string& id,
528 const std::string& stream_id) {
529 for (const auto& sender : senders) {
530 if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
531 return true;
534 return false;
537 // Create a collection of streams.
538 // CreateStreamCollection(1) creates a collection that
539 // correspond to kSdpStringWithStream1.
540 // CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
541 rtc::scoped_refptr<StreamCollection> CreateStreamCollection(
542 int number_of_streams,
543 int tracks_per_stream) {
544 rtc::scoped_refptr<StreamCollection> local_collection(
545 StreamCollection::Create());
547 for (int i = 0; i < number_of_streams; ++i) {
548 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
549 webrtc::MediaStream::Create(kStreams[i]));
551 for (int j = 0; j < tracks_per_stream; ++j) {
552 // Add a local audio track.
553 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
554 webrtc::AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j],
555 nullptr));
556 stream->AddTrack(audio_track);
558 // Add a local video track.
559 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
560 webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
561 webrtc::FakeVideoTrackSource::Create(),
562 rtc::Thread::Current()));
563 stream->AddTrack(video_track);
566 local_collection->AddStream(stream);
568 return local_collection;
571 // Check equality of StreamCollections.
572 bool CompareStreamCollections(StreamCollectionInterface* s1,
573 StreamCollectionInterface* s2) {
574 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
575 return false;
578 for (size_t i = 0; i != s1->count(); ++i) {
579 if (s1->at(i)->id() != s2->at(i)->id()) {
580 return false;
582 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
583 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
584 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
585 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
587 if (audio_tracks1.size() != audio_tracks2.size()) {
588 return false;
590 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
591 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
592 return false;
595 if (video_tracks1.size() != video_tracks2.size()) {
596 return false;
598 for (size_t j = 0; j != video_tracks1.size(); ++j) {
599 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
600 return false;
604 return true;
607 // Helper class to test Observer.
608 class MockTrackObserver : public ObserverInterface {
609 public:
610 explicit MockTrackObserver(NotifierInterface* notifier)
611 : notifier_(notifier) {
612 notifier_->RegisterObserver(this);
615 ~MockTrackObserver() { Unregister(); }
617 void Unregister() {
618 if (notifier_) {
619 notifier_->UnregisterObserver(this);
620 notifier_ = nullptr;
624 MOCK_METHOD(void, OnChanged, (), (override));
626 private:
627 NotifierInterface* notifier_;
630 // The PeerConnectionMediaConfig tests below verify that configuration and
631 // constraints are propagated into the PeerConnection's MediaConfig. These
632 // settings are intended for MediaChannel constructors, but that is not
633 // exercised by these unittest.
634 class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
635 public:
636 static rtc::scoped_refptr<PeerConnectionFactoryForTest>
637 CreatePeerConnectionFactoryForTest() {
638 PeerConnectionFactoryDependencies dependencies;
639 dependencies.worker_thread = rtc::Thread::Current();
640 dependencies.network_thread = rtc::Thread::Current();
641 dependencies.signaling_thread = rtc::Thread::Current();
642 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
643 dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
644 cricket::MediaEngineDependencies media_deps;
645 media_deps.task_queue_factory = dependencies.task_queue_factory.get();
646 // Use fake audio device module since we're only testing the interface
647 // level, and using a real one could make tests flaky when run in parallel.
648 media_deps.adm = FakeAudioCaptureModule::Create();
649 SetMediaEngineDefaults(&media_deps);
650 media_deps.trials = dependencies.trials.get();
651 dependencies.media_engine =
652 cricket::CreateMediaEngine(std::move(media_deps));
653 dependencies.call_factory = webrtc::CreateCallFactory();
654 dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
655 dependencies.task_queue_factory.get());
657 return rtc::make_ref_counted<PeerConnectionFactoryForTest>(
658 std::move(dependencies));
661 using PeerConnectionFactory::PeerConnectionFactory;
663 private:
664 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
667 // TODO(steveanton): Convert to use the new PeerConnectionWrapper.
668 class PeerConnectionInterfaceBaseTest : public ::testing::Test {
669 protected:
670 explicit PeerConnectionInterfaceBaseTest(SdpSemantics sdp_semantics)
671 : vss_(new rtc::VirtualSocketServer()),
672 main_(vss_.get()),
673 sdp_semantics_(sdp_semantics) {
674 #ifdef WEBRTC_ANDROID
675 webrtc::InitializeAndroidObjects();
676 #endif
679 void SetUp() override {
680 // Use fake audio capture module since we're only testing the interface
681 // level, and using a real one could make tests flaky when run in parallel.
682 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
683 pc_factory_ = webrtc::CreatePeerConnectionFactory(
684 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
685 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
686 fake_audio_capture_module_),
687 webrtc::CreateBuiltinAudioEncoderFactory(),
688 webrtc::CreateBuiltinAudioDecoderFactory(),
689 std::make_unique<webrtc::VideoEncoderFactoryTemplate<
690 webrtc::LibvpxVp8EncoderTemplateAdapter,
691 webrtc::LibvpxVp9EncoderTemplateAdapter,
692 webrtc::OpenH264EncoderTemplateAdapter,
693 webrtc::LibaomAv1EncoderTemplateAdapter>>(),
694 std::make_unique<webrtc::VideoDecoderFactoryTemplate<
695 webrtc::LibvpxVp8DecoderTemplateAdapter,
696 webrtc::LibvpxVp9DecoderTemplateAdapter,
697 webrtc::OpenH264DecoderTemplateAdapter,
698 webrtc::Dav1dDecoderTemplateAdapter>>(),
699 nullptr /* audio_mixer */, nullptr /* audio_processing */);
700 ASSERT_TRUE(pc_factory_);
703 void TearDown() override {
704 if (pc_)
705 pc_->Close();
708 void CreatePeerConnection() {
709 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration());
712 // DTLS does not work in a loopback call, so is disabled for many
713 // tests in this file.
714 void CreatePeerConnectionWithoutDtls() {
715 RTCConfiguration config;
716 PeerConnectionFactoryInterface::Options options;
717 options.disable_encryption = true;
718 pc_factory_->SetOptions(options);
719 CreatePeerConnection(config);
720 options.disable_encryption = false;
721 pc_factory_->SetOptions(options);
724 void CreatePeerConnectionWithIceTransportsType(
725 PeerConnectionInterface::IceTransportsType type) {
726 PeerConnectionInterface::RTCConfiguration config;
727 config.type = type;
728 return CreatePeerConnection(config);
731 void CreatePeerConnectionWithIceServer(const std::string& uri,
732 const std::string& username,
733 const std::string& password) {
734 PeerConnectionInterface::RTCConfiguration config;
735 PeerConnectionInterface::IceServer server;
736 server.uri = uri;
737 server.username = username;
738 server.password = password;
739 config.servers.push_back(server);
740 CreatePeerConnection(config);
743 void CreatePeerConnection(const RTCConfiguration& config) {
744 if (pc_) {
745 pc_->Close();
746 pc_ = nullptr;
748 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
749 new cricket::FakePortAllocator(
750 rtc::Thread::Current(),
751 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()),
752 &field_trials_));
753 port_allocator_ = port_allocator.get();
754 port_allocator_->SetIceTiebreaker(kTiebreakerDefault);
756 // Create certificate generator unless DTLS constraint is explicitly set to
757 // false.
758 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
760 // These won't be used if encryption is turned off, but that's harmless.
761 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
762 cert_generator.reset(fake_certificate_generator_);
764 RTCConfiguration modified_config = config;
765 modified_config.sdp_semantics = sdp_semantics_;
766 PeerConnectionDependencies pc_dependencies(&observer_);
767 pc_dependencies.cert_generator = std::move(cert_generator);
768 pc_dependencies.allocator = std::move(port_allocator);
769 auto result = pc_factory_->CreatePeerConnectionOrError(
770 modified_config, std::move(pc_dependencies));
771 ASSERT_TRUE(result.ok());
772 pc_ = result.MoveValue();
773 observer_.SetPeerConnectionInterface(pc_.get());
774 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
777 void CreatePeerConnectionExpectFail(const std::string& uri) {
778 PeerConnectionInterface::RTCConfiguration config;
779 PeerConnectionInterface::IceServer server;
780 server.uri = uri;
781 config.servers.push_back(server);
782 config.sdp_semantics = sdp_semantics_;
783 PeerConnectionDependencies pc_dependencies(&observer_);
784 auto result = pc_factory_->CreatePeerConnectionOrError(
785 config, std::move(pc_dependencies));
786 EXPECT_FALSE(result.ok());
789 void CreatePeerConnectionExpectFail(
790 PeerConnectionInterface::RTCConfiguration config) {
791 PeerConnectionInterface::IceServer server;
792 server.uri = kTurnIceServerUri;
793 server.password = kTurnPassword;
794 config.servers.push_back(server);
795 config.sdp_semantics = sdp_semantics_;
796 PeerConnectionDependencies pc_dependencies(&observer_);
797 auto result = pc_factory_->CreatePeerConnectionOrError(
798 config, std::move(pc_dependencies));
799 EXPECT_FALSE(result.ok());
802 void CreatePeerConnectionWithDifferentConfigurations() {
803 CreatePeerConnectionWithIceServer(kStunAddressOnly, "", "");
804 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
805 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
806 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
807 EXPECT_EQ(kDefaultStunPort,
808 port_allocator_->stun_servers().begin()->port());
810 CreatePeerConnectionExpectFail(kStunInvalidPort);
811 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
812 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
814 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnUsername,
815 kTurnPassword);
816 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
817 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
818 EXPECT_EQ(kTurnUsername,
819 port_allocator_->turn_servers()[0].credentials.username);
820 EXPECT_EQ(kTurnPassword,
821 port_allocator_->turn_servers()[0].credentials.password);
822 EXPECT_EQ(kTurnHostname,
823 port_allocator_->turn_servers()[0].ports[0].address.hostname());
826 void ReleasePeerConnection() {
827 pc_ = nullptr;
828 observer_.SetPeerConnectionInterface(nullptr);
831 rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
832 const std::string& label) {
833 return pc_factory_->CreateVideoTrack(FakeVideoTrackSource::Create(), label);
836 void AddVideoTrack(const std::string& track_label,
837 const std::vector<std::string>& stream_ids = {}) {
838 auto sender_or_error =
839 pc_->AddTrack(CreateVideoTrack(track_label), stream_ids);
840 ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
843 void AddVideoStream(const std::string& label) {
844 rtc::scoped_refptr<MediaStreamInterface> stream(
845 pc_factory_->CreateLocalMediaStream(label));
846 stream->AddTrack(CreateVideoTrack(label + "v0"));
847 ASSERT_TRUE(pc_->AddStream(stream.get()));
850 rtc::scoped_refptr<AudioTrackInterface> CreateAudioTrack(
851 const std::string& label) {
852 return pc_factory_->CreateAudioTrack(label, nullptr);
855 void AddAudioTrack(const std::string& track_label,
856 const std::vector<std::string>& stream_ids = {}) {
857 auto sender_or_error =
858 pc_->AddTrack(CreateAudioTrack(track_label), stream_ids);
859 ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
862 void AddAudioStream(const std::string& label) {
863 rtc::scoped_refptr<MediaStreamInterface> stream(
864 pc_factory_->CreateLocalMediaStream(label));
865 stream->AddTrack(CreateAudioTrack(label + "a0"));
866 ASSERT_TRUE(pc_->AddStream(stream.get()));
869 void AddAudioVideoStream(const std::string& stream_id,
870 const std::string& audio_track_label,
871 const std::string& video_track_label) {
872 // Create a local stream.
873 rtc::scoped_refptr<MediaStreamInterface> stream(
874 pc_factory_->CreateLocalMediaStream(stream_id));
875 stream->AddTrack(CreateAudioTrack(audio_track_label));
876 stream->AddTrack(CreateVideoTrack(video_track_label));
877 ASSERT_TRUE(pc_->AddStream(stream.get()));
880 rtc::scoped_refptr<RtpReceiverInterface> GetFirstReceiverOfType(
881 cricket::MediaType media_type) {
882 for (auto receiver : pc_->GetReceivers()) {
883 if (receiver->media_type() == media_type) {
884 return receiver;
887 return nullptr;
890 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
891 const RTCOfferAnswerOptions* options,
892 bool offer) {
893 auto observer =
894 rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
895 if (offer) {
896 pc_->CreateOffer(observer.get(),
897 options ? *options : RTCOfferAnswerOptions());
898 } else {
899 pc_->CreateAnswer(observer.get(),
900 options ? *options : RTCOfferAnswerOptions());
902 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
903 *desc = observer->MoveDescription();
904 return observer->result();
907 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
908 const RTCOfferAnswerOptions* options) {
909 return DoCreateOfferAnswer(desc, options, true);
912 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
913 const RTCOfferAnswerOptions* options) {
914 return DoCreateOfferAnswer(desc, options, false);
917 bool DoSetSessionDescription(
918 std::unique_ptr<SessionDescriptionInterface> desc,
919 bool local) {
920 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
921 if (local) {
922 pc_->SetLocalDescription(observer.get(), desc.release());
923 } else {
924 pc_->SetRemoteDescription(observer.get(), desc.release());
926 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
927 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
929 return observer->result();
932 bool DoSetLocalDescription(
933 std::unique_ptr<SessionDescriptionInterface> desc) {
934 return DoSetSessionDescription(std::move(desc), true);
937 bool DoSetRemoteDescription(
938 std::unique_ptr<SessionDescriptionInterface> desc) {
939 return DoSetSessionDescription(std::move(desc), false);
942 // Calls PeerConnection::GetStats and check the return value.
943 // It does not verify the values in the StatReports since a RTCP packet might
944 // be required.
945 bool DoGetStats(MediaStreamTrackInterface* track) {
946 auto observer = rtc::make_ref_counted<MockStatsObserver>();
947 if (!pc_->GetStats(observer.get(), track,
948 PeerConnectionInterface::kStatsOutputLevelStandard))
949 return false;
950 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
951 return observer->called();
954 // Call the standards-compliant GetStats function.
955 bool DoGetRTCStats() {
956 auto callback =
957 rtc::make_ref_counted<webrtc::MockRTCStatsCollectorCallback>();
958 pc_->GetStats(callback.get());
959 EXPECT_TRUE_WAIT(callback->called(), kTimeout);
960 return callback->called();
963 void InitiateCall() {
964 CreatePeerConnectionWithoutDtls();
965 // Create a local stream with audio&video tracks.
966 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
967 AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
968 } else {
969 // Unified Plan does not support AddStream, so just add an audio and video
970 // track.
971 AddAudioTrack(kAudioTracks[0], {kStreamId1});
972 AddVideoTrack(kVideoTracks[0], {kStreamId1});
974 CreateOfferReceiveAnswer();
977 // Verify that RTP Header extensions has been negotiated for audio and video.
978 void VerifyRemoteRtpHeaderExtensions() {
979 const cricket::MediaContentDescription* desc =
980 cricket::GetFirstAudioContentDescription(
981 pc_->remote_description()->description());
982 ASSERT_TRUE(desc != nullptr);
983 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
985 desc = cricket::GetFirstVideoContentDescription(
986 pc_->remote_description()->description());
987 ASSERT_TRUE(desc != nullptr);
988 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
991 void CreateOfferAsRemoteDescription() {
992 std::unique_ptr<SessionDescriptionInterface> offer;
993 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
994 std::string sdp;
995 EXPECT_TRUE(offer->ToString(&sdp));
996 std::unique_ptr<SessionDescriptionInterface> remote_offer(
997 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
998 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
999 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
1002 void CreateAndSetRemoteOffer(const std::string& sdp) {
1003 std::unique_ptr<SessionDescriptionInterface> remote_offer(
1004 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
1005 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
1006 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
1009 void CreateAnswerAsLocalDescription() {
1010 std::unique_ptr<SessionDescriptionInterface> answer;
1011 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
1013 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1014 // audio codec change, even if the parameter has nothing to do with
1015 // receiving. Not all parameters are serialized to SDP.
1016 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1017 // the SessionDescription, it is necessary to do that here to in order to
1018 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1019 // https://code.google.com/p/webrtc/issues/detail?id=1356
1020 std::string sdp;
1021 EXPECT_TRUE(answer->ToString(&sdp));
1022 std::unique_ptr<SessionDescriptionInterface> new_answer(
1023 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
1024 EXPECT_TRUE(DoSetLocalDescription(std::move(new_answer)));
1025 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1028 void CreatePrAnswerAsLocalDescription() {
1029 std::unique_ptr<SessionDescriptionInterface> answer;
1030 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
1032 std::string sdp;
1033 EXPECT_TRUE(answer->ToString(&sdp));
1034 std::unique_ptr<SessionDescriptionInterface> pr_answer(
1035 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
1036 EXPECT_TRUE(DoSetLocalDescription(std::move(pr_answer)));
1037 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
1040 void CreateOfferReceiveAnswer() {
1041 CreateOfferAsLocalDescription();
1042 std::string sdp;
1043 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1044 CreateAnswerAsRemoteDescription(sdp);
1047 void CreateOfferAsLocalDescription() {
1048 std::unique_ptr<SessionDescriptionInterface> offer;
1049 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1050 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1051 // audio codec change, even if the parameter has nothing to do with
1052 // receiving. Not all parameters are serialized to SDP.
1053 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1054 // the SessionDescription, it is necessary to do that here to in order to
1055 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1056 // https://code.google.com/p/webrtc/issues/detail?id=1356
1057 std::string sdp;
1058 EXPECT_TRUE(offer->ToString(&sdp));
1059 std::unique_ptr<SessionDescriptionInterface> new_offer(
1060 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
1062 EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
1063 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
1064 // Wait for the ice_complete message, so that SDP will have candidates.
1065 EXPECT_TRUE_WAIT(observer_.ice_gathering_complete_, kTimeout);
1068 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
1069 std::unique_ptr<SessionDescriptionInterface> answer(
1070 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
1071 ASSERT_TRUE(answer);
1072 EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
1073 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1076 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
1077 std::unique_ptr<SessionDescriptionInterface> pr_answer(
1078 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
1079 ASSERT_TRUE(pr_answer);
1080 EXPECT_TRUE(DoSetRemoteDescription(std::move(pr_answer)));
1081 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
1082 std::unique_ptr<SessionDescriptionInterface> answer(
1083 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
1084 ASSERT_TRUE(answer);
1085 EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
1086 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1089 // Waits until a remote stream with the given id is signaled. This helper
1090 // function will verify both OnAddTrack and OnAddStream (Plan B only) are
1091 // called with the given stream id and expected number of tracks.
1092 void WaitAndVerifyOnAddStream(const std::string& stream_id,
1093 int expected_num_tracks) {
1094 // Verify that both OnAddStream and OnAddTrack are called.
1095 EXPECT_EQ_WAIT(stream_id, observer_.GetLastAddedStreamId(), kTimeout);
1096 EXPECT_EQ_WAIT(expected_num_tracks,
1097 observer_.CountAddTrackEventsForStream(stream_id), kTimeout);
1100 // Creates an offer and applies it as a local session description.
1101 // Creates an answer with the same SDP an the offer but removes all lines
1102 // that start with a:ssrc"
1103 void CreateOfferReceiveAnswerWithoutSsrc() {
1104 CreateOfferAsLocalDescription();
1105 std::string sdp;
1106 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1107 SetSsrcToZero(&sdp);
1108 CreateAnswerAsRemoteDescription(sdp);
1111 // This function creates a MediaStream with label kStreams[0] and
1112 // `number_of_audio_tracks` and `number_of_video_tracks` tracks and the
1113 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
1114 // is returned and the MediaStream is stored in
1115 // `reference_collection_`
1116 std::unique_ptr<SessionDescriptionInterface>
1117 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1118 size_t number_of_video_tracks) {
1119 EXPECT_LE(number_of_audio_tracks, 2u);
1120 EXPECT_LE(number_of_video_tracks, 2u);
1122 reference_collection_ = StreamCollection::Create();
1123 std::string sdp_ms1 = std::string(kSdpStringInit);
1125 std::string mediastream_id = kStreams[0];
1127 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
1128 webrtc::MediaStream::Create(mediastream_id));
1129 reference_collection_->AddStream(stream);
1131 if (number_of_audio_tracks > 0) {
1132 sdp_ms1 += std::string(kSdpStringAudio);
1133 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1134 AddAudioTrack(kAudioTracks[0], stream.get());
1136 if (number_of_audio_tracks > 1) {
1137 sdp_ms1 += kSdpStringMs1Audio1;
1138 AddAudioTrack(kAudioTracks[1], stream.get());
1141 if (number_of_video_tracks > 0) {
1142 sdp_ms1 += std::string(kSdpStringVideo);
1143 sdp_ms1 += std::string(kSdpStringMs1Video0);
1144 AddVideoTrack(kVideoTracks[0], stream.get());
1146 if (number_of_video_tracks > 1) {
1147 sdp_ms1 += kSdpStringMs1Video1;
1148 AddVideoTrack(kVideoTracks[1], stream.get());
1151 return std::unique_ptr<SessionDescriptionInterface>(
1152 webrtc::CreateSessionDescription(SdpType::kOffer, sdp_ms1));
1155 void AddAudioTrack(const std::string& track_id,
1156 MediaStreamInterface* stream) {
1157 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1158 webrtc::AudioTrack::Create(track_id, nullptr));
1159 ASSERT_TRUE(stream->AddTrack(audio_track));
1162 void AddVideoTrack(const std::string& track_id,
1163 MediaStreamInterface* stream) {
1164 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
1165 webrtc::VideoTrack::Create(track_id,
1166 webrtc::FakeVideoTrackSource::Create(),
1167 rtc::Thread::Current()));
1168 ASSERT_TRUE(stream->AddTrack(video_track));
1171 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioTrack() {
1172 CreatePeerConnectionWithoutDtls();
1173 AddAudioTrack(kAudioTracks[0]);
1174 std::unique_ptr<SessionDescriptionInterface> offer;
1175 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1176 return offer;
1179 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
1180 CreatePeerConnectionWithoutDtls();
1181 AddAudioStream(kStreamId1);
1182 std::unique_ptr<SessionDescriptionInterface> offer;
1183 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1184 return offer;
1187 std::unique_ptr<SessionDescriptionInterface> CreateAnswerWithOneAudioTrack() {
1188 EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioTrack()));
1189 std::unique_ptr<SessionDescriptionInterface> answer;
1190 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1191 return answer;
1194 std::unique_ptr<SessionDescriptionInterface>
1195 CreateAnswerWithOneAudioStream() {
1196 EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioStream()));
1197 std::unique_ptr<SessionDescriptionInterface> answer;
1198 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1199 return answer;
1202 const std::string& GetFirstAudioStreamCname(
1203 const SessionDescriptionInterface* desc) {
1204 const cricket::AudioContentDescription* audio_desc =
1205 cricket::GetFirstAudioContentDescription(desc->description());
1206 return audio_desc->streams()[0].cname;
1209 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOptions(
1210 const RTCOfferAnswerOptions& offer_answer_options) {
1211 RTC_DCHECK(pc_);
1212 auto observer =
1213 rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
1214 pc_->CreateOffer(observer.get(), offer_answer_options);
1215 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
1216 return observer->MoveDescription();
1219 void CreateOfferWithOptionsAsRemoteDescription(
1220 std::unique_ptr<SessionDescriptionInterface>* desc,
1221 const RTCOfferAnswerOptions& offer_answer_options) {
1222 *desc = CreateOfferWithOptions(offer_answer_options);
1223 ASSERT_TRUE(desc != nullptr);
1224 std::string sdp;
1225 EXPECT_TRUE((*desc)->ToString(&sdp));
1226 std::unique_ptr<SessionDescriptionInterface> remote_offer(
1227 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
1228 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
1229 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
1232 void CreateOfferWithOptionsAsLocalDescription(
1233 std::unique_ptr<SessionDescriptionInterface>* desc,
1234 const RTCOfferAnswerOptions& offer_answer_options) {
1235 *desc = CreateOfferWithOptions(offer_answer_options);
1236 ASSERT_TRUE(desc != nullptr);
1237 std::string sdp;
1238 EXPECT_TRUE((*desc)->ToString(&sdp));
1239 std::unique_ptr<SessionDescriptionInterface> new_offer(
1240 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
1242 EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
1243 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
1246 bool HasCNCodecs(const cricket::ContentInfo* content) {
1247 RTC_DCHECK(content);
1248 RTC_DCHECK(content->media_description());
1249 for (const cricket::AudioCodec& codec :
1250 content->media_description()->as_audio()->codecs()) {
1251 if (codec.name == "CN") {
1252 return true;
1255 return false;
1258 const char* GetSdpStringWithStream1() const {
1259 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
1260 return kSdpStringWithStream1PlanB;
1261 } else {
1262 return kSdpStringWithStream1UnifiedPlan;
1266 const char* GetSdpStringWithStream1And2() const {
1267 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
1268 return kSdpStringWithStream1And2PlanB;
1269 } else {
1270 return kSdpStringWithStream1And2UnifiedPlan;
1274 rtc::SocketServer* socket_server() const { return vss_.get(); }
1276 webrtc::test::ScopedKeyValueConfig field_trials_;
1277 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1278 rtc::AutoSocketServerThread main_;
1279 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
1280 cricket::FakePortAllocator* port_allocator_ = nullptr;
1281 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
1282 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1283 rtc::scoped_refptr<PeerConnectionInterface> pc_;
1284 MockPeerConnectionObserver observer_;
1285 rtc::scoped_refptr<StreamCollection> reference_collection_;
1286 const SdpSemantics sdp_semantics_;
1289 class PeerConnectionInterfaceTest
1290 : public PeerConnectionInterfaceBaseTest,
1291 public ::testing::WithParamInterface<SdpSemantics> {
1292 protected:
1293 PeerConnectionInterfaceTest() : PeerConnectionInterfaceBaseTest(GetParam()) {}
1296 class PeerConnectionInterfaceTestPlanB
1297 : public PeerConnectionInterfaceBaseTest {
1298 protected:
1299 PeerConnectionInterfaceTestPlanB()
1300 : PeerConnectionInterfaceBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
1303 // Generate different CNAMEs when PeerConnections are created.
1304 // The CNAMEs are expected to be generated randomly. It is possible
1305 // that the test fails, though the possibility is very low.
1306 TEST_P(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
1307 std::unique_ptr<SessionDescriptionInterface> offer1 =
1308 CreateOfferWithOneAudioTrack();
1309 std::unique_ptr<SessionDescriptionInterface> offer2 =
1310 CreateOfferWithOneAudioTrack();
1311 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1312 GetFirstAudioStreamCname(offer2.get()));
1315 TEST_P(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
1316 std::unique_ptr<SessionDescriptionInterface> answer1 =
1317 CreateAnswerWithOneAudioTrack();
1318 std::unique_ptr<SessionDescriptionInterface> answer2 =
1319 CreateAnswerWithOneAudioTrack();
1320 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1321 GetFirstAudioStreamCname(answer2.get()));
1324 TEST_P(PeerConnectionInterfaceTest,
1325 CreatePeerConnectionWithDifferentConfigurations) {
1326 CreatePeerConnectionWithDifferentConfigurations();
1329 TEST_P(PeerConnectionInterfaceTest,
1330 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1331 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1332 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1333 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1334 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1335 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1336 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1337 port_allocator_->candidate_filter());
1338 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1339 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1342 // Test that when a PeerConnection is created with a nonzero candidate pool
1343 // size, the pooled PortAllocatorSession is created with all the attributes
1344 // in the RTCConfiguration.
1345 TEST_P(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
1346 PeerConnectionInterface::RTCConfiguration config;
1347 config.sdp_semantics = sdp_semantics_;
1348 PeerConnectionInterface::IceServer server;
1349 server.uri = kStunAddressOnly;
1350 config.servers.push_back(server);
1351 config.type = PeerConnectionInterface::kRelay;
1352 config.tcp_candidate_policy =
1353 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
1354 config.candidate_network_policy =
1355 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
1356 config.ice_candidate_pool_size = 1;
1357 CreatePeerConnection(config);
1359 const cricket::FakePortAllocatorSession* session =
1360 static_cast<const cricket::FakePortAllocatorSession*>(
1361 port_allocator_->GetPooledSession());
1362 ASSERT_NE(nullptr, session);
1363 EXPECT_EQ(1UL, session->stun_servers().size());
1364 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
1365 EXPECT_LT(0U,
1366 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
1369 // Test that network-related RTCConfiguration members are applied to the
1370 // PortAllocator when CreatePeerConnection is called. Specifically:
1371 // - disable_ipv6_on_wifi
1372 // - max_ipv6_networks
1373 // - tcp_candidate_policy
1374 // - candidate_network_policy
1375 // - prune_turn_ports
1377 // Note that the candidate filter (RTCConfiguration::type) is already tested
1378 // above.
1379 TEST_P(PeerConnectionInterfaceTest,
1380 CreatePeerConnectionAppliesNetworkConfigToPortAllocator) {
1381 // Create fake port allocator.
1382 std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory(
1383 new rtc::BasicPacketSocketFactory(socket_server()));
1384 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1385 new cricket::FakePortAllocator(
1386 rtc::Thread::Current(), packet_socket_factory.get(), &field_trials_));
1387 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1389 // Create RTCConfiguration with some network-related fields relevant to
1390 // PortAllocator populated.
1391 PeerConnectionInterface::RTCConfiguration config;
1392 config.sdp_semantics = sdp_semantics_;
1393 config.disable_ipv6_on_wifi = true;
1394 config.max_ipv6_networks = 10;
1395 config.tcp_candidate_policy =
1396 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
1397 config.candidate_network_policy =
1398 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
1399 config.prune_turn_ports = true;
1401 // Create the PC factory and PC with the above config.
1402 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1403 webrtc::CreatePeerConnectionFactory(
1404 rtc::Thread::Current(), rtc::Thread::Current(),
1405 rtc::Thread::Current(), fake_audio_capture_module_,
1406 webrtc::CreateBuiltinAudioEncoderFactory(),
1407 webrtc::CreateBuiltinAudioDecoderFactory(),
1408 std::make_unique<webrtc::VideoEncoderFactoryTemplate<
1409 webrtc::LibvpxVp8EncoderTemplateAdapter,
1410 webrtc::LibvpxVp9EncoderTemplateAdapter,
1411 webrtc::OpenH264EncoderTemplateAdapter,
1412 webrtc::LibaomAv1EncoderTemplateAdapter>>(),
1413 std::make_unique<webrtc::VideoDecoderFactoryTemplate<
1414 webrtc::LibvpxVp8DecoderTemplateAdapter,
1415 webrtc::LibvpxVp9DecoderTemplateAdapter,
1416 webrtc::OpenH264DecoderTemplateAdapter,
1417 webrtc::Dav1dDecoderTemplateAdapter>>(),
1418 nullptr /* audio_mixer */, nullptr /* audio_processing */));
1419 PeerConnectionDependencies pc_dependencies(&observer_);
1420 pc_dependencies.allocator = std::move(port_allocator);
1421 auto result = pc_factory_->CreatePeerConnectionOrError(
1422 config, std::move(pc_dependencies));
1423 EXPECT_TRUE(result.ok());
1424 observer_.SetPeerConnectionInterface(result.value().get());
1426 // Now validate that the config fields set above were applied to the
1427 // PortAllocator, as flags or otherwise.
1428 EXPECT_FALSE(raw_port_allocator->flags() &
1429 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1430 EXPECT_EQ(10, raw_port_allocator->max_ipv6_networks());
1431 EXPECT_TRUE(raw_port_allocator->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
1432 EXPECT_TRUE(raw_port_allocator->flags() &
1433 cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
1434 EXPECT_EQ(webrtc::PRUNE_BASED_ON_PRIORITY,
1435 raw_port_allocator->turn_port_prune_policy());
1438 // Check that GetConfiguration returns the configuration the PeerConnection was
1439 // constructed with, before SetConfiguration is called.
1440 TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
1441 PeerConnectionInterface::RTCConfiguration config;
1442 config.sdp_semantics = sdp_semantics_;
1443 config.type = PeerConnectionInterface::kRelay;
1444 CreatePeerConnection(config);
1446 PeerConnectionInterface::RTCConfiguration returned_config =
1447 pc_->GetConfiguration();
1448 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1451 // Check that GetConfiguration returns the last configuration passed into
1452 // SetConfiguration.
1453 TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
1454 PeerConnectionInterface::RTCConfiguration starting_config;
1455 starting_config.sdp_semantics = sdp_semantics_;
1456 starting_config.bundle_policy =
1457 webrtc::PeerConnection::kBundlePolicyMaxBundle;
1458 CreatePeerConnection(starting_config);
1460 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
1461 config.type = PeerConnectionInterface::kRelay;
1462 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
1464 PeerConnectionInterface::RTCConfiguration returned_config =
1465 pc_->GetConfiguration();
1466 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1469 TEST_P(PeerConnectionInterfaceTest, SetConfigurationFailsAfterClose) {
1470 CreatePeerConnection();
1472 pc_->Close();
1474 EXPECT_FALSE(
1475 pc_->SetConfiguration(PeerConnectionInterface::RTCConfiguration()).ok());
1478 TEST_F(PeerConnectionInterfaceTestPlanB, AddStreams) {
1479 CreatePeerConnectionWithoutDtls();
1480 AddVideoStream(kStreamId1);
1481 AddAudioStream(kStreamId2);
1482 ASSERT_EQ(2u, pc_->local_streams()->count());
1484 // Test we can add multiple local streams to one peerconnection.
1485 rtc::scoped_refptr<MediaStreamInterface> stream(
1486 pc_factory_->CreateLocalMediaStream(kStreamId3));
1487 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1488 pc_factory_->CreateAudioTrack(
1489 kStreamId3, static_cast<AudioSourceInterface*>(nullptr)));
1490 stream->AddTrack(audio_track);
1491 EXPECT_TRUE(pc_->AddStream(stream.get()));
1492 EXPECT_EQ(3u, pc_->local_streams()->count());
1494 // Remove the third stream.
1495 pc_->RemoveStream(pc_->local_streams()->at(2));
1496 EXPECT_EQ(2u, pc_->local_streams()->count());
1498 // Remove the second stream.
1499 pc_->RemoveStream(pc_->local_streams()->at(1));
1500 EXPECT_EQ(1u, pc_->local_streams()->count());
1502 // Remove the first stream.
1503 pc_->RemoveStream(pc_->local_streams()->at(0));
1504 EXPECT_EQ(0u, pc_->local_streams()->count());
1507 // Test that the created offer includes streams we added.
1508 // Don't run under Unified Plan since the stream API is not available.
1509 TEST_F(PeerConnectionInterfaceTestPlanB, AddedStreamsPresentInOffer) {
1510 CreatePeerConnectionWithoutDtls();
1511 AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
1512 std::unique_ptr<SessionDescriptionInterface> offer;
1513 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1515 const cricket::AudioContentDescription* audio_desc =
1516 cricket::GetFirstAudioContentDescription(offer->description());
1517 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));
1519 const cricket::VideoContentDescription* video_desc =
1520 cricket::GetFirstVideoContentDescription(offer->description());
1521 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));
1523 // Add another stream and ensure the offer includes both the old and new
1524 // streams.
1525 AddAudioVideoStream(kStreamId2, "audio_track2", "video_track2");
1526 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1528 audio_desc = cricket::GetFirstAudioContentDescription(offer->description());
1529 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));
1530 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId2, "audio_track2"));
1532 video_desc = cricket::GetFirstVideoContentDescription(offer->description());
1533 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));
1534 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId2, "video_track2"));
1537 // Don't run under Unified Plan since the stream API is not available.
1538 TEST_F(PeerConnectionInterfaceTestPlanB, RemoveStream) {
1539 CreatePeerConnectionWithoutDtls();
1540 AddVideoStream(kStreamId1);
1541 ASSERT_EQ(1u, pc_->local_streams()->count());
1542 pc_->RemoveStream(pc_->local_streams()->at(0));
1543 EXPECT_EQ(0u, pc_->local_streams()->count());
1546 // Test for AddTrack and RemoveTrack methods.
1547 // Tests that the created offer includes tracks we added,
1548 // and that the RtpSenders are created correctly.
1549 // Also tests that RemoveTrack removes the tracks from subsequent offers.
1550 // Only tested with Plan B since Unified Plan is covered in more detail by tests
1551 // in peerconnection_jsep_unittests.cc
1552 TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackRemoveTrack) {
1553 CreatePeerConnectionWithoutDtls();
1554 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1555 CreateAudioTrack("audio_track"));
1556 rtc::scoped_refptr<VideoTrackInterface> video_track(
1557 CreateVideoTrack("video_track"));
1558 auto audio_sender = pc_->AddTrack(audio_track, {kStreamId1}).MoveValue();
1559 auto video_sender = pc_->AddTrack(video_track, {kStreamId1}).MoveValue();
1560 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1561 EXPECT_EQ(kStreamId1, audio_sender->stream_ids()[0]);
1562 EXPECT_EQ("audio_track", audio_sender->id());
1563 EXPECT_EQ(audio_track, audio_sender->track());
1564 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1565 EXPECT_EQ(kStreamId1, video_sender->stream_ids()[0]);
1566 EXPECT_EQ("video_track", video_sender->id());
1567 EXPECT_EQ(video_track, video_sender->track());
1569 // Now create an offer and check for the senders.
1570 std::unique_ptr<SessionDescriptionInterface> offer;
1571 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1573 const cricket::ContentInfo* audio_content =
1574 cricket::GetFirstAudioContent(offer->description());
1575 EXPECT_TRUE(ContainsTrack(audio_content->media_description()->streams(),
1576 kStreamId1, "audio_track"));
1578 const cricket::ContentInfo* video_content =
1579 cricket::GetFirstVideoContent(offer->description());
1580 EXPECT_TRUE(ContainsTrack(video_content->media_description()->streams(),
1581 kStreamId1, "video_track"));
1583 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
1585 // Now try removing the tracks.
1586 EXPECT_TRUE(pc_->RemoveTrackOrError(audio_sender).ok());
1587 EXPECT_TRUE(pc_->RemoveTrackOrError(video_sender).ok());
1589 // Create a new offer and ensure it doesn't contain the removed senders.
1590 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1592 audio_content = cricket::GetFirstAudioContent(offer->description());
1593 EXPECT_FALSE(ContainsTrack(audio_content->media_description()->streams(),
1594 kStreamId1, "audio_track"));
1596 video_content = cricket::GetFirstVideoContent(offer->description());
1597 EXPECT_FALSE(ContainsTrack(video_content->media_description()->streams(),
1598 kStreamId1, "video_track"));
1600 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
1602 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1603 // should return false.
1604 EXPECT_FALSE(pc_->RemoveTrackOrError(audio_sender).ok());
1605 EXPECT_FALSE(pc_->RemoveTrackOrError(video_sender).ok());
1608 // Test for AddTrack with init_send_encoding.
1609 TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackWithSendEncodings) {
1610 CreatePeerConnectionWithoutDtls();
1611 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1612 CreateAudioTrack("audio_track"));
1613 rtc::scoped_refptr<VideoTrackInterface> video_track(
1614 CreateVideoTrack("video_track"));
1615 RtpEncodingParameters audio_encodings;
1616 audio_encodings.active = false;
1617 auto audio_sender =
1618 pc_->AddTrack(audio_track, {kStreamId1}, {audio_encodings}).MoveValue();
1619 RtpEncodingParameters video_encodings;
1620 video_encodings.active = true;
1621 auto video_sender =
1622 pc_->AddTrack(video_track, {kStreamId1}, {video_encodings}).MoveValue();
1623 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1624 EXPECT_EQ(kStreamId1, audio_sender->stream_ids()[0]);
1625 EXPECT_EQ("audio_track", audio_sender->id());
1626 EXPECT_EQ(audio_track, audio_sender->track());
1627 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1628 EXPECT_EQ(kStreamId1, video_sender->stream_ids()[0]);
1629 EXPECT_EQ("video_track", video_sender->id());
1630 EXPECT_EQ(video_track, video_sender->track());
1632 // Now create an offer and check for the senders.
1633 std::unique_ptr<SessionDescriptionInterface> offer;
1634 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1636 const cricket::ContentInfo* audio_content =
1637 cricket::GetFirstAudioContent(offer->description());
1638 EXPECT_TRUE(ContainsTrack(audio_content->media_description()->streams(),
1639 kStreamId1, "audio_track"));
1641 const cricket::ContentInfo* video_content =
1642 cricket::GetFirstVideoContent(offer->description());
1643 EXPECT_TRUE(ContainsTrack(video_content->media_description()->streams(),
1644 kStreamId1, "video_track"));
1646 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
1648 // Check the encodings.
1649 ASSERT_THAT(audio_sender->GetParameters().encodings, SizeIs(1));
1650 EXPECT_THAT(audio_sender->GetParameters().encodings[0].active, Eq(false));
1651 ASSERT_THAT(video_sender->GetParameters().encodings, SizeIs(1));
1652 EXPECT_THAT(video_sender->GetParameters().encodings[0].active, Eq(true));
1654 // Now try removing the tracks.
1655 EXPECT_TRUE(pc_->RemoveTrackOrError(audio_sender).ok());
1656 EXPECT_TRUE(pc_->RemoveTrackOrError(video_sender).ok());
1659 // Test creating senders without a stream specified,
1660 // expecting a random stream ID to be generated.
1661 TEST_P(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
1662 CreatePeerConnectionWithoutDtls();
1663 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1664 CreateAudioTrack("audio_track"));
1665 rtc::scoped_refptr<VideoTrackInterface> video_track(
1666 CreateVideoTrack("video_track"));
1667 auto audio_sender =
1668 pc_->AddTrack(audio_track, std::vector<std::string>()).MoveValue();
1669 auto video_sender =
1670 pc_->AddTrack(video_track, std::vector<std::string>()).MoveValue();
1671 EXPECT_EQ("audio_track", audio_sender->id());
1672 EXPECT_EQ(audio_track, audio_sender->track());
1673 EXPECT_EQ("video_track", video_sender->id());
1674 EXPECT_EQ(video_track, video_sender->track());
1675 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
1676 // If the ID is truly a random GUID, it should be infinitely unlikely they
1677 // will be the same.
1678 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
1679 } else {
1680 // We allows creating tracks without stream ids under Unified Plan
1681 // semantics.
1682 EXPECT_EQ(0u, video_sender->stream_ids().size());
1683 EXPECT_EQ(0u, audio_sender->stream_ids().size());
1687 // Test that we can call GetStats() after AddTrack but before connecting
1688 // the PeerConnection to a peer.
1689 TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) {
1690 CreatePeerConnectionWithoutDtls();
1691 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1692 CreateAudioTrack("audio_track"));
1693 rtc::scoped_refptr<VideoTrackInterface> video_track(
1694 CreateVideoTrack("video_track"));
1695 auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
1696 auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
1697 EXPECT_TRUE(DoGetStats(nullptr));
1700 TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) {
1701 CreatePeerConnectionWithoutDtls();
1702 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1703 CreateAudioTrack("audio_track"));
1704 rtc::scoped_refptr<VideoTrackInterface> video_track(
1705 CreateVideoTrack("video_track"));
1706 auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
1707 ASSERT_TRUE(audio_sender.ok());
1708 auto* audio_sender_proxy =
1709 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1710 audio_sender.value().get());
1711 EXPECT_NE(0, audio_sender_proxy->internal()->AttachmentId());
1713 auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
1714 ASSERT_TRUE(video_sender.ok());
1715 auto* video_sender_proxy =
1716 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1717 video_sender.value().get());
1718 EXPECT_NE(0, video_sender_proxy->internal()->AttachmentId());
1721 // Don't run under Unified Plan since the stream API is not available.
1722 TEST_F(PeerConnectionInterfaceTestPlanB, AttachmentIdIsSetOnAddStream) {
1723 CreatePeerConnectionWithoutDtls();
1724 AddVideoStream(kStreamId1);
1725 auto senders = pc_->GetSenders();
1726 ASSERT_EQ(1u, senders.size());
1727 auto* sender_proxy =
1728 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1729 senders[0].get());
1730 EXPECT_NE(0, sender_proxy->internal()->AttachmentId());
1733 TEST_P(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
1734 InitiateCall();
1735 WaitAndVerifyOnAddStream(kStreamId1, 2);
1736 VerifyRemoteRtpHeaderExtensions();
1739 TEST_P(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
1740 CreatePeerConnectionWithoutDtls();
1741 AddVideoTrack(kVideoTracks[0], {kStreamId1});
1742 CreateOfferAsLocalDescription();
1743 std::string offer;
1744 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1745 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
1746 WaitAndVerifyOnAddStream(kStreamId1, 1);
1749 TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
1750 CreatePeerConnectionWithoutDtls();
1751 AddVideoTrack(kVideoTracks[0], {kStreamId1});
1753 CreateOfferAsRemoteDescription();
1754 CreateAnswerAsLocalDescription();
1756 WaitAndVerifyOnAddStream(kStreamId1, 1);
1759 TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
1760 CreatePeerConnectionWithoutDtls();
1761 AddVideoTrack(kVideoTracks[0], {kStreamId1});
1763 CreateOfferAsRemoteDescription();
1764 CreatePrAnswerAsLocalDescription();
1765 CreateAnswerAsLocalDescription();
1767 WaitAndVerifyOnAddStream(kStreamId1, 1);
1770 // Don't run under Unified Plan since the stream API is not available.
1771 TEST_F(PeerConnectionInterfaceTestPlanB, Renegotiate) {
1772 InitiateCall();
1773 ASSERT_EQ(1u, pc_->remote_streams()->count());
1774 pc_->RemoveStream(pc_->local_streams()->at(0));
1775 CreateOfferReceiveAnswer();
1776 EXPECT_EQ(0u, pc_->remote_streams()->count());
1777 AddVideoStream(kStreamId1);
1778 CreateOfferReceiveAnswer();
1781 // Tests that after negotiating an audio only call, the respondent can perform a
1782 // renegotiation that removes the audio stream.
1783 TEST_F(PeerConnectionInterfaceTestPlanB, RenegotiateAudioOnly) {
1784 CreatePeerConnectionWithoutDtls();
1785 AddAudioStream(kStreamId1);
1786 CreateOfferAsRemoteDescription();
1787 CreateAnswerAsLocalDescription();
1789 ASSERT_EQ(1u, pc_->remote_streams()->count());
1790 pc_->RemoveStream(pc_->local_streams()->at(0));
1791 CreateOfferReceiveAnswer();
1792 EXPECT_EQ(0u, pc_->remote_streams()->count());
1795 // Test that candidates are generated and that we can parse our own candidates.
1796 TEST_P(PeerConnectionInterfaceTest, IceCandidates) {
1797 CreatePeerConnectionWithoutDtls();
1799 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate()));
1800 // SetRemoteDescription takes ownership of offer.
1801 std::unique_ptr<SessionDescriptionInterface> offer;
1802 AddVideoTrack(kVideoTracks[0]);
1803 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1804 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
1806 // SetLocalDescription takes ownership of answer.
1807 std::unique_ptr<SessionDescriptionInterface> answer;
1808 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1809 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
1811 EXPECT_TRUE_WAIT(observer_.last_candidate() != nullptr, kTimeout);
1812 EXPECT_TRUE_WAIT(observer_.ice_gathering_complete_, kTimeout);
1814 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate()));
1817 // Test that CreateOffer and CreateAnswer will fail if the track labels are
1818 // not unique.
1819 TEST_F(PeerConnectionInterfaceTestPlanB, CreateOfferAnswerWithInvalidStream) {
1820 CreatePeerConnectionWithoutDtls();
1821 // Create a regular offer for the CreateAnswer test later.
1822 std::unique_ptr<SessionDescriptionInterface> offer;
1823 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1824 EXPECT_TRUE(offer);
1825 offer.reset();
1827 // Create a local stream with audio&video tracks having same label.
1828 AddAudioTrack("track_label", {kStreamId1});
1829 AddVideoTrack("track_label", {kStreamId1});
1831 // Test CreateOffer
1832 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
1834 // Test CreateAnswer
1835 std::unique_ptr<SessionDescriptionInterface> answer;
1836 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
1839 // Test that we will get different SSRCs for each tracks in the offer and answer
1840 // we created.
1841 TEST_P(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
1842 CreatePeerConnectionWithoutDtls();
1843 // Create a local stream with audio&video tracks having different labels.
1844 AddAudioTrack(kAudioTracks[0], {kStreamId1});
1845 AddVideoTrack(kVideoTracks[0], {kStreamId1});
1847 // Test CreateOffer
1848 std::unique_ptr<SessionDescriptionInterface> offer;
1849 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1850 int audio_ssrc = 0;
1851 int video_ssrc = 0;
1852 EXPECT_TRUE(
1853 GetFirstSsrc(GetFirstAudioContent(offer->description()), &audio_ssrc));
1854 EXPECT_TRUE(
1855 GetFirstSsrc(GetFirstVideoContent(offer->description()), &video_ssrc));
1856 EXPECT_NE(audio_ssrc, video_ssrc);
1858 // Test CreateAnswer
1859 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
1860 std::unique_ptr<SessionDescriptionInterface> answer;
1861 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
1862 audio_ssrc = 0;
1863 video_ssrc = 0;
1864 EXPECT_TRUE(
1865 GetFirstSsrc(GetFirstAudioContent(answer->description()), &audio_ssrc));
1866 EXPECT_TRUE(
1867 GetFirstSsrc(GetFirstVideoContent(answer->description()), &video_ssrc));
1868 EXPECT_NE(audio_ssrc, video_ssrc);
1871 // Test that it's possible to call AddTrack on a MediaStream after adding
1872 // the stream to a PeerConnection.
1873 // TODO(deadbeef): Remove this test once this behavior is no longer supported.
1874 // Don't run under Unified Plan since the stream API is not available.
1875 TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackAfterAddStream) {
1876 CreatePeerConnectionWithoutDtls();
1877 // Create audio stream and add to PeerConnection.
1878 AddAudioStream(kStreamId1);
1879 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1881 // Add video track to the audio-only stream.
1882 rtc::scoped_refptr<VideoTrackInterface> video_track(
1883 CreateVideoTrack("video_label"));
1884 stream->AddTrack(video_track);
1886 std::unique_ptr<SessionDescriptionInterface> offer;
1887 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1889 const cricket::MediaContentDescription* video_desc =
1890 cricket::GetFirstVideoContentDescription(offer->description());
1891 EXPECT_TRUE(video_desc != nullptr);
1894 // Test that it's possible to call RemoveTrack on a MediaStream after adding
1895 // the stream to a PeerConnection.
1896 // TODO(deadbeef): Remove this test once this behavior is no longer supported.
1897 // Don't run under Unified Plan since the stream API is not available.
1898 TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackAfterAddStream) {
1899 CreatePeerConnectionWithoutDtls();
1900 // Create audio/video stream and add to PeerConnection.
1901 AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
1902 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1904 // Remove the video track.
1905 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1907 std::unique_ptr<SessionDescriptionInterface> offer;
1908 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1910 const cricket::MediaContentDescription* video_desc =
1911 cricket::GetFirstVideoContentDescription(offer->description());
1912 EXPECT_TRUE(video_desc == nullptr);
1915 // Test creating a sender with a stream ID, and ensure the ID is populated
1916 // in the offer.
1917 // Don't run under Unified Plan since the stream API is not available.
1918 TEST_F(PeerConnectionInterfaceTestPlanB, CreateSenderWithStream) {
1919 CreatePeerConnectionWithoutDtls();
1920 pc_->CreateSender("video", kStreamId1);
1922 std::unique_ptr<SessionDescriptionInterface> offer;
1923 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
1925 const cricket::MediaContentDescription* video_desc =
1926 cricket::GetFirstVideoContentDescription(offer->description());
1927 ASSERT_TRUE(video_desc != nullptr);
1928 ASSERT_EQ(1u, video_desc->streams().size());
1929 EXPECT_EQ(kStreamId1, video_desc->streams()[0].first_stream_id());
1932 // Test that we can specify a certain track that we want statistics about.
1933 TEST_P(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
1934 InitiateCall();
1935 ASSERT_LT(0u, pc_->GetSenders().size());
1936 ASSERT_LT(0u, pc_->GetReceivers().size());
1937 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
1938 pc_->GetReceivers()[0]->track();
1939 EXPECT_TRUE(DoGetStats(remote_audio.get()));
1941 // Remove the stream. Since we are sending to our selves the local
1942 // and the remote stream is the same.
1943 pc_->RemoveTrackOrError(pc_->GetSenders()[0]);
1944 // Do a re-negotiation.
1945 CreateOfferReceiveAnswer();
1947 // Test that we still can get statistics for the old track. Even if it is not
1948 // sent any longer.
1949 EXPECT_TRUE(DoGetStats(remote_audio.get()));
1952 // Test that we can get stats on a video track.
1953 TEST_P(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
1954 InitiateCall();
1955 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
1956 ASSERT_TRUE(video_receiver);
1957 EXPECT_TRUE(DoGetStats(video_receiver->track().get()));
1960 // Test that we don't get statistics for an invalid track.
1961 TEST_P(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
1962 InitiateCall();
1963 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
1964 pc_factory_->CreateAudioTrack("unknown track", nullptr));
1965 EXPECT_FALSE(DoGetStats(unknown_audio_track.get()));
1968 TEST_P(PeerConnectionInterfaceTest, GetRTCStatsBeforeAndAfterCalling) {
1969 CreatePeerConnectionWithoutDtls();
1970 EXPECT_TRUE(DoGetRTCStats());
1971 // Clearing stats cache is needed now, but should be temporary.
1972 // https://bugs.chromium.org/p/webrtc/issues/detail?id=8693
1973 pc_->ClearStatsCache();
1974 AddAudioTrack(kAudioTracks[0], {kStreamId1});
1975 AddVideoTrack(kVideoTracks[0], {kStreamId1});
1976 EXPECT_TRUE(DoGetRTCStats());
1977 pc_->ClearStatsCache();
1978 CreateOfferReceiveAnswer();
1979 EXPECT_TRUE(DoGetRTCStats());
1982 // This tests that a SCTP data channel is returned using different
1983 // DataChannelInit configurations.
1984 TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
1985 RTCConfiguration rtc_config;
1986 CreatePeerConnection(rtc_config);
1988 webrtc::DataChannelInit config;
1989 auto channel = pc_->CreateDataChannelOrError("1", &config);
1990 EXPECT_TRUE(channel.ok());
1991 EXPECT_TRUE(channel.value()->reliable());
1992 EXPECT_TRUE(observer_.renegotiation_needed_);
1993 observer_.renegotiation_needed_ = false;
1995 config.ordered = false;
1996 channel = pc_->CreateDataChannelOrError("2", &config);
1997 EXPECT_TRUE(channel.ok());
1998 EXPECT_TRUE(channel.value()->reliable());
1999 EXPECT_FALSE(observer_.renegotiation_needed_);
2001 config.ordered = true;
2002 config.maxRetransmits = 0;
2003 channel = pc_->CreateDataChannelOrError("3", &config);
2004 EXPECT_TRUE(channel.ok());
2005 EXPECT_FALSE(channel.value()->reliable());
2006 EXPECT_FALSE(observer_.renegotiation_needed_);
2008 config.maxRetransmits = absl::nullopt;
2009 config.maxRetransmitTime = 0;
2010 channel = pc_->CreateDataChannelOrError("4", &config);
2011 EXPECT_TRUE(channel.ok());
2012 EXPECT_FALSE(channel.value()->reliable());
2013 EXPECT_FALSE(observer_.renegotiation_needed_);
2016 TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWhenClosed) {
2017 RTCConfiguration rtc_config;
2018 CreatePeerConnection(rtc_config);
2019 pc_->Close();
2020 webrtc::DataChannelInit config;
2021 auto ret = pc_->CreateDataChannelOrError("1", &config);
2022 ASSERT_FALSE(ret.ok());
2023 EXPECT_EQ(ret.error().type(), RTCErrorType::INVALID_STATE);
2026 // For backwards compatibility, we want people who "unset" maxRetransmits
2027 // and maxRetransmitTime by setting them to -1 to get what they want.
2028 TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWithMinusOne) {
2029 RTCConfiguration rtc_config;
2030 CreatePeerConnection(rtc_config);
2032 webrtc::DataChannelInit config;
2033 config.maxRetransmitTime = -1;
2034 config.maxRetransmits = -1;
2035 auto channel = pc_->CreateDataChannelOrError("1", &config);
2036 EXPECT_TRUE(channel.ok());
2039 // This tests that no data channel is returned if both maxRetransmits and
2040 // maxRetransmitTime are set for SCTP data channels.
2041 TEST_P(PeerConnectionInterfaceTest,
2042 CreateSctpDataChannelShouldFailForInvalidConfig) {
2043 RTCConfiguration rtc_config;
2044 CreatePeerConnection(rtc_config);
2046 std::string label = "test";
2047 webrtc::DataChannelInit config;
2048 config.maxRetransmits = 0;
2049 config.maxRetransmitTime = 0;
2051 auto channel = pc_->CreateDataChannelOrError(label, &config);
2052 EXPECT_FALSE(channel.ok());
2055 // The test verifies that creating a SCTP data channel with an id already in use
2056 // or out of range should fail.
2057 TEST_P(PeerConnectionInterfaceTest,
2058 CreateSctpDataChannelWithInvalidIdShouldFail) {
2059 RTCConfiguration rtc_config;
2060 CreatePeerConnection(rtc_config);
2062 webrtc::DataChannelInit config;
2064 config.id = 1;
2065 config.negotiated = true;
2066 auto channel = pc_->CreateDataChannelOrError("1", &config);
2067 EXPECT_TRUE(channel.ok());
2068 EXPECT_EQ(1, channel.value()->id());
2070 channel = pc_->CreateDataChannelOrError("x", &config);
2071 EXPECT_FALSE(channel.ok());
2073 config.id = cricket::kMaxSctpSid;
2074 config.negotiated = true;
2075 channel = pc_->CreateDataChannelOrError("max", &config);
2076 EXPECT_TRUE(channel.ok());
2077 EXPECT_EQ(config.id, channel.value()->id());
2079 config.id = cricket::kMaxSctpSid + 1;
2080 config.negotiated = true;
2081 channel = pc_->CreateDataChannelOrError("x", &config);
2082 EXPECT_FALSE(channel.ok());
2085 // Verifies that duplicated label is allowed for SCTP data channel.
2086 TEST_P(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
2087 RTCConfiguration rtc_config;
2088 CreatePeerConnection(rtc_config);
2090 std::string label = "test";
2091 auto channel = pc_->CreateDataChannelOrError(label, nullptr);
2092 EXPECT_TRUE(channel.ok());
2094 auto dup_channel = pc_->CreateDataChannelOrError(label, nullptr);
2095 EXPECT_TRUE(dup_channel.ok());
2098 #ifdef WEBRTC_HAVE_SCTP
2099 // This tests that SCTP data channels can be rejected in an answer.
2100 TEST_P(PeerConnectionInterfaceTest, TestRejectSctpDataChannelInAnswer)
2101 #else
2102 TEST_P(PeerConnectionInterfaceTest, DISABLED_TestRejectSctpDataChannelInAnswer)
2103 #endif
2105 RTCConfiguration rtc_config;
2106 CreatePeerConnection(rtc_config);
2108 auto offer_channel = pc_->CreateDataChannelOrError("offer_channel", NULL);
2110 CreateOfferAsLocalDescription();
2112 // Create an answer where the m-line for data channels are rejected.
2113 std::string sdp;
2114 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2115 std::unique_ptr<SessionDescriptionInterface> answer(
2116 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
2117 ASSERT_TRUE(answer);
2118 cricket::ContentInfo* data_info =
2119 cricket::GetFirstDataContent(answer->description());
2120 data_info->rejected = true;
2122 DoSetRemoteDescription(std::move(answer));
2123 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel.value()->state());
2126 // Test that we can create a session description from an SDP string from
2127 // FireFox, use it as a remote session description, generate an answer and use
2128 // the answer as a local description.
2129 TEST_P(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
2130 RTCConfiguration rtc_config;
2131 CreatePeerConnection(rtc_config);
2132 AddAudioTrack("audio_label");
2133 AddVideoTrack("video_label");
2134 std::unique_ptr<SessionDescriptionInterface> desc(
2135 webrtc::CreateSessionDescription(SdpType::kOffer,
2136 webrtc::kFireFoxSdpOffer, nullptr));
2137 EXPECT_TRUE(DoSetSessionDescription(std::move(desc), false));
2138 CreateAnswerAsLocalDescription();
2139 ASSERT_TRUE(pc_->local_description() != nullptr);
2140 ASSERT_TRUE(pc_->remote_description() != nullptr);
2142 const cricket::ContentInfo* content =
2143 cricket::GetFirstAudioContent(pc_->local_description()->description());
2144 ASSERT_TRUE(content != nullptr);
2145 EXPECT_FALSE(content->rejected);
2147 content =
2148 cricket::GetFirstVideoContent(pc_->local_description()->description());
2149 ASSERT_TRUE(content != nullptr);
2150 EXPECT_FALSE(content->rejected);
2151 #ifdef WEBRTC_HAVE_SCTP
2152 content =
2153 cricket::GetFirstDataContent(pc_->local_description()->description());
2154 ASSERT_TRUE(content != nullptr);
2155 EXPECT_FALSE(content->rejected);
2156 #endif
2159 // Test that fallback from DTLS to SDES is not supported.
2160 // The fallback was previously supported but was removed to simplify the code
2161 // and because it's non-standard.
2162 TEST_P(PeerConnectionInterfaceTest, DtlsSdesFallbackNotSupported) {
2163 RTCConfiguration rtc_config;
2164 CreatePeerConnection(rtc_config);
2165 // Wait for fake certificate to be generated. Previously, this is what caused
2166 // the "a=crypto" lines to be rejected.
2167 AddAudioTrack("audio_label");
2168 AddVideoTrack("video_label");
2169 ASSERT_NE(nullptr, fake_certificate_generator_);
2170 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2171 kTimeout);
2172 std::unique_ptr<SessionDescriptionInterface> desc(
2173 webrtc::CreateSessionDescription(SdpType::kOffer, kDtlsSdesFallbackSdp,
2174 nullptr));
2175 EXPECT_FALSE(DoSetSessionDescription(std::move(desc), /*local=*/false));
2178 // Test that we can create an audio only offer and receive an answer with a
2179 // limited set of audio codecs and receive an updated offer with more audio
2180 // codecs, where the added codecs are not supported.
2181 TEST_P(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
2182 CreatePeerConnectionWithoutDtls();
2183 AddAudioTrack("audio_label");
2184 CreateOfferAsLocalDescription();
2186 const char* answer_sdp = (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED
2187 ? webrtc::kAudioSdpPlanB
2188 : webrtc::kAudioSdpUnifiedPlan);
2189 std::unique_ptr<SessionDescriptionInterface> answer(
2190 webrtc::CreateSessionDescription(SdpType::kAnswer, answer_sdp, nullptr));
2191 EXPECT_TRUE(DoSetSessionDescription(std::move(answer), false));
2193 const char* reoffer_sdp =
2194 (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED
2195 ? webrtc::kAudioSdpWithUnsupportedCodecsPlanB
2196 : webrtc::kAudioSdpWithUnsupportedCodecsUnifiedPlan);
2197 std::unique_ptr<SessionDescriptionInterface> updated_offer(
2198 webrtc::CreateSessionDescription(SdpType::kOffer, reoffer_sdp, nullptr));
2199 EXPECT_TRUE(DoSetSessionDescription(std::move(updated_offer), false));
2200 CreateAnswerAsLocalDescription();
2203 // Test that if we're receiving (but not sending) a track, subsequent offers
2204 // will have m-lines with a=recvonly.
2205 TEST_P(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
2206 RTCConfiguration rtc_config;
2207 CreatePeerConnection(rtc_config);
2208 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2209 CreateAnswerAsLocalDescription();
2211 // At this point we should be receiving stream 1, but not sending anything.
2212 // A new offer should be recvonly.
2213 std::unique_ptr<SessionDescriptionInterface> offer;
2214 DoCreateOffer(&offer, nullptr);
2216 const cricket::ContentInfo* video_content =
2217 cricket::GetFirstVideoContent(offer->description());
2218 ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
2219 video_content->media_description()->direction());
2221 const cricket::ContentInfo* audio_content =
2222 cricket::GetFirstAudioContent(offer->description());
2223 ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
2224 audio_content->media_description()->direction());
2227 // Test that if we're receiving (but not sending) a track, and the
2228 // offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2229 // false, the generated m-lines will be a=inactive.
2230 TEST_P(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
2231 RTCConfiguration rtc_config;
2232 CreatePeerConnection(rtc_config);
2233 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2234 CreateAnswerAsLocalDescription();
2236 // At this point we should be receiving stream 1, but not sending anything.
2237 // A new offer would be recvonly, but we'll set the "no receive" constraints
2238 // to make it inactive.
2239 std::unique_ptr<SessionDescriptionInterface> offer;
2240 RTCOfferAnswerOptions options;
2241 options.offer_to_receive_audio = 0;
2242 options.offer_to_receive_video = 0;
2243 DoCreateOffer(&offer, &options);
2245 const cricket::ContentInfo* video_content =
2246 cricket::GetFirstVideoContent(offer->description());
2247 ASSERT_EQ(RtpTransceiverDirection::kInactive,
2248 video_content->media_description()->direction());
2250 const cricket::ContentInfo* audio_content =
2251 cricket::GetFirstAudioContent(offer->description());
2252 ASSERT_EQ(RtpTransceiverDirection::kInactive,
2253 audio_content->media_description()->direction());
2256 // Test that we can use SetConfiguration to change the ICE servers of the
2257 // PortAllocator.
2258 TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
2259 CreatePeerConnection();
2261 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2262 PeerConnectionInterface::IceServer server;
2263 server.uri = "stun:test_hostname";
2264 config.servers.push_back(server);
2265 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2267 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2268 EXPECT_EQ("test_hostname",
2269 port_allocator_->stun_servers().begin()->hostname());
2272 TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
2273 CreatePeerConnection();
2274 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2275 config.type = PeerConnectionInterface::kRelay;
2276 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2277 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2280 TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
2281 PeerConnectionInterface::RTCConfiguration config;
2282 config.prune_turn_ports = false;
2283 CreatePeerConnection(config);
2284 config = pc_->GetConfiguration();
2285 EXPECT_EQ(webrtc::NO_PRUNE, port_allocator_->turn_port_prune_policy());
2287 config.prune_turn_ports = true;
2288 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2289 EXPECT_EQ(webrtc::PRUNE_BASED_ON_PRIORITY,
2290 port_allocator_->turn_port_prune_policy());
2293 // Test that the ice check interval can be changed. This does not verify that
2294 // the setting makes it all the way to P2PTransportChannel, as that would
2295 // require a very complex set of mocks.
2296 TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
2297 PeerConnectionInterface::RTCConfiguration config;
2298 config.ice_check_min_interval = absl::nullopt;
2299 CreatePeerConnection(config);
2300 config = pc_->GetConfiguration();
2301 config.ice_check_min_interval = 100;
2302 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2303 config = pc_->GetConfiguration();
2304 EXPECT_EQ(config.ice_check_min_interval, 100);
2307 TEST_P(PeerConnectionInterfaceTest,
2308 SetConfigurationChangesSurfaceIceCandidatesOnIceTransportTypeChanged) {
2309 PeerConnectionInterface::RTCConfiguration config;
2310 config.surface_ice_candidates_on_ice_transport_type_changed = false;
2311 CreatePeerConnection(config);
2312 config = pc_->GetConfiguration();
2313 EXPECT_FALSE(config.surface_ice_candidates_on_ice_transport_type_changed);
2315 config.surface_ice_candidates_on_ice_transport_type_changed = true;
2316 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2317 config = pc_->GetConfiguration();
2318 EXPECT_TRUE(config.surface_ice_candidates_on_ice_transport_type_changed);
2321 // Test that when SetConfiguration changes both the pool size and other
2322 // attributes, the pooled session is created with the updated attributes.
2323 TEST_P(PeerConnectionInterfaceTest,
2324 SetConfigurationCreatesPooledSessionCorrectly) {
2325 CreatePeerConnection();
2326 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2327 config.ice_candidate_pool_size = 1;
2328 PeerConnectionInterface::IceServer server;
2329 server.uri = kStunAddressOnly;
2330 config.servers.push_back(server);
2331 config.type = PeerConnectionInterface::kRelay;
2332 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2334 const cricket::FakePortAllocatorSession* session =
2335 static_cast<const cricket::FakePortAllocatorSession*>(
2336 port_allocator_->GetPooledSession());
2337 ASSERT_NE(nullptr, session);
2338 EXPECT_EQ(1UL, session->stun_servers().size());
2341 // Test that after SetLocalDescription, changing the pool size is not allowed,
2342 // and an invalid modification error is returned.
2343 TEST_P(PeerConnectionInterfaceTest,
2344 CantChangePoolSizeAfterSetLocalDescription) {
2345 CreatePeerConnection();
2346 // Start by setting a size of 1.
2347 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2348 config.ice_candidate_pool_size = 1;
2349 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2351 // Set remote offer; can still change pool size at this point.
2352 CreateOfferAsRemoteDescription();
2353 config.ice_candidate_pool_size = 2;
2354 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2356 // Set local answer; now it's too late.
2357 CreateAnswerAsLocalDescription();
2358 config.ice_candidate_pool_size = 3;
2359 RTCError error = pc_->SetConfiguration(config);
2360 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2363 // Test that after setting an answer, extra pooled sessions are discarded. The
2364 // ICE candidate pool is only intended to be used for the first offer/answer.
2365 TEST_P(PeerConnectionInterfaceTest,
2366 ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
2367 CreatePeerConnection();
2369 // Set a larger-than-necessary size.
2370 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2371 config.ice_candidate_pool_size = 4;
2372 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2374 // Do offer/answer.
2375 CreateOfferAsRemoteDescription();
2376 CreateAnswerAsLocalDescription();
2378 // Expect no pooled sessions to be left.
2379 const cricket::PortAllocatorSession* session =
2380 port_allocator_->GetPooledSession();
2381 EXPECT_EQ(nullptr, session);
2384 // After Close is called, pooled candidates should be discarded so as to not
2385 // waste network resources.
2386 TEST_P(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
2387 CreatePeerConnection();
2389 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
2390 config.ice_candidate_pool_size = 3;
2391 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
2392 pc_->Close();
2394 // Expect no pooled sessions to be left.
2395 const cricket::PortAllocatorSession* session =
2396 port_allocator_->GetPooledSession();
2397 EXPECT_EQ(nullptr, session);
2400 // Test that SetConfiguration returns an invalid modification error if
2401 // modifying a field in the configuration that isn't allowed to be modified.
2402 TEST_P(PeerConnectionInterfaceTest,
2403 SetConfigurationReturnsInvalidModificationError) {
2404 PeerConnectionInterface::RTCConfiguration config;
2405 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2406 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2407 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
2408 CreatePeerConnection(config);
2410 PeerConnectionInterface::RTCConfiguration modified_config =
2411 pc_->GetConfiguration();
2412 modified_config.bundle_policy =
2413 PeerConnectionInterface::kBundlePolicyMaxBundle;
2414 RTCError error = pc_->SetConfiguration(modified_config);
2415 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2417 modified_config = pc_->GetConfiguration();
2418 modified_config.rtcp_mux_policy =
2419 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2420 error = pc_->SetConfiguration(modified_config);
2421 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2423 modified_config = pc_->GetConfiguration();
2424 modified_config.continual_gathering_policy =
2425 PeerConnectionInterface::GATHER_CONTINUALLY;
2426 error = pc_->SetConfiguration(modified_config);
2427 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2430 // Test that SetConfiguration returns a range error if the candidate pool size
2431 // is negative or larger than allowed by the spec.
2432 TEST_P(PeerConnectionInterfaceTest,
2433 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2434 PeerConnectionInterface::RTCConfiguration config;
2435 CreatePeerConnection(config);
2436 config = pc_->GetConfiguration();
2438 config.ice_candidate_pool_size = -1;
2439 RTCError error = pc_->SetConfiguration(config);
2440 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2442 config.ice_candidate_pool_size = INT_MAX;
2443 error = pc_->SetConfiguration(config);
2444 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2447 // Test that SetConfiguration returns a syntax error if parsing an ICE server
2448 // URL failed.
2449 TEST_P(PeerConnectionInterfaceTest,
2450 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2451 PeerConnectionInterface::RTCConfiguration config;
2452 CreatePeerConnection(config);
2453 config = pc_->GetConfiguration();
2455 PeerConnectionInterface::IceServer bad_server;
2456 bad_server.uri = "stunn:www.example.com";
2457 config.servers.push_back(bad_server);
2458 RTCError error = pc_->SetConfiguration(config);
2459 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2462 // Test that SetConfiguration returns an invalid parameter error if a TURN
2463 // IceServer is missing a username or password.
2464 TEST_P(PeerConnectionInterfaceTest,
2465 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2466 PeerConnectionInterface::RTCConfiguration config;
2467 CreatePeerConnection(config);
2468 config = pc_->GetConfiguration();
2470 PeerConnectionInterface::IceServer bad_server;
2471 bad_server.uri = "turn:www.example.com";
2472 // Missing password.
2473 bad_server.username = "foo";
2474 config.servers.push_back(bad_server);
2475 RTCError error;
2476 EXPECT_EQ(pc_->SetConfiguration(config).type(),
2477 RTCErrorType::INVALID_PARAMETER);
2480 // Test that PeerConnection::Close changes the states to closed and all remote
2481 // tracks change state to ended.
2482 TEST_P(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
2483 // Initialize a PeerConnection and negotiate local and remote session
2484 // description.
2485 InitiateCall();
2487 // With Plan B, verify the stream count. The analog with Unified Plan is the
2488 // RtpTransceiver count.
2489 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
2490 ASSERT_EQ(1u, pc_->local_streams()->count());
2491 ASSERT_EQ(1u, pc_->remote_streams()->count());
2492 } else {
2493 ASSERT_EQ(2u, pc_->GetTransceivers().size());
2496 pc_->Close();
2498 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2499 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2500 pc_->ice_connection_state());
2501 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2502 pc_->ice_gathering_state());
2504 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
2505 EXPECT_EQ(1u, pc_->local_streams()->count());
2506 EXPECT_EQ(1u, pc_->remote_streams()->count());
2507 } else {
2508 // Verify that the RtpTransceivers are still returned.
2509 EXPECT_EQ(2u, pc_->GetTransceivers().size());
2512 auto audio_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_AUDIO);
2513 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
2514 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
2515 ASSERT_TRUE(audio_receiver);
2516 ASSERT_TRUE(video_receiver);
2517 // Track state may be updated asynchronously.
2518 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2519 audio_receiver->track()->state(), kTimeout);
2520 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2521 video_receiver->track()->state(), kTimeout);
2522 } else {
2523 ASSERT_FALSE(audio_receiver);
2524 ASSERT_FALSE(video_receiver);
2528 // Test that PeerConnection methods fails gracefully after
2529 // PeerConnection::Close has been called.
2530 // Don't run under Unified Plan since the stream API is not available.
2531 TEST_F(PeerConnectionInterfaceTestPlanB, CloseAndTestMethods) {
2532 CreatePeerConnectionWithoutDtls();
2533 AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
2534 CreateOfferAsRemoteDescription();
2535 CreateAnswerAsLocalDescription();
2537 ASSERT_EQ(1u, pc_->local_streams()->count());
2538 rtc::scoped_refptr<MediaStreamInterface> local_stream(
2539 pc_->local_streams()->at(0));
2541 pc_->Close();
2543 pc_->RemoveStream(local_stream.get());
2544 EXPECT_FALSE(pc_->AddStream(local_stream.get()));
2546 EXPECT_FALSE(pc_->CreateDataChannelOrError("test", NULL).ok());
2548 EXPECT_TRUE(pc_->local_description() != nullptr);
2549 EXPECT_TRUE(pc_->remote_description() != nullptr);
2551 std::unique_ptr<SessionDescriptionInterface> offer;
2552 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
2553 std::unique_ptr<SessionDescriptionInterface> answer;
2554 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
2556 std::string sdp;
2557 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
2558 std::unique_ptr<SessionDescriptionInterface> remote_offer(
2559 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
2560 EXPECT_FALSE(DoSetRemoteDescription(std::move(remote_offer)));
2562 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
2563 std::unique_ptr<SessionDescriptionInterface> local_offer(
2564 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
2565 EXPECT_FALSE(DoSetLocalDescription(std::move(local_offer)));
2568 // Test that GetStats can still be called after PeerConnection::Close.
2569 TEST_P(PeerConnectionInterfaceTest, CloseAndGetStats) {
2570 InitiateCall();
2571 pc_->Close();
2572 DoGetStats(nullptr);
2575 // NOTE: The series of tests below come from what used to be
2576 // mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2577 // setting a remote or local description has the expected effects.
2579 // This test verifies that the remote MediaStreams corresponding to a received
2580 // SDP string is created. In this test the two separate MediaStreams are
2581 // signaled.
2582 TEST_P(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
2583 RTCConfiguration config;
2584 CreatePeerConnection(config);
2585 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2587 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
2588 EXPECT_TRUE(
2589 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2590 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2591 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2593 // Create a session description based on another SDP with another
2594 // MediaStream.
2595 CreateAndSetRemoteOffer(GetSdpStringWithStream1And2());
2597 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
2598 EXPECT_TRUE(
2599 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2602 // This test verifies that when remote tracks are added/removed from SDP, the
2603 // created remote streams are updated appropriately.
2604 // Don't run under Unified Plan since this test uses Plan B SDP to test Plan B
2605 // specific behavior.
2606 TEST_F(PeerConnectionInterfaceTestPlanB,
2607 AddRemoveTrackFromExistingRemoteMediaStream) {
2608 RTCConfiguration config;
2609 CreatePeerConnection(config);
2610 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
2611 CreateSessionDescriptionAndReference(1, 1);
2612 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1)));
2613 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2614 reference_collection_.get()));
2616 // Add extra audio and video tracks to the same MediaStream.
2617 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
2618 CreateSessionDescriptionAndReference(2, 2);
2619 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1_two_tracks)));
2620 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2621 reference_collection_.get()));
2622 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
2623 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2624 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
2625 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
2626 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2627 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
2629 // Remove the extra audio and video tracks.
2630 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
2631 CreateSessionDescriptionAndReference(1, 1);
2632 MockTrackObserver audio_track_observer(audio_track2.get());
2633 MockTrackObserver video_track_observer(video_track2.get());
2635 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2636 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
2637 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms2)));
2638 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2639 reference_collection_.get()));
2640 // Track state may be updated asynchronously.
2641 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2642 audio_track2->state(), kTimeout);
2643 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2644 video_track2->state(), kTimeout);
2647 // This tests that remote tracks are ended if a local session description is set
2648 // that rejects the media content type.
2649 TEST_P(PeerConnectionInterfaceTest, RejectMediaContent) {
2650 RTCConfiguration config;
2651 CreatePeerConnection(config);
2652 // First create and set a remote offer, then reject its video content in our
2653 // answer.
2654 CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
2655 auto audio_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_AUDIO);
2656 ASSERT_TRUE(audio_receiver);
2657 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
2658 ASSERT_TRUE(video_receiver);
2660 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
2661 audio_receiver->track();
2662 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2663 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
2664 video_receiver->track();
2665 EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_video->state());
2667 std::unique_ptr<SessionDescriptionInterface> local_answer;
2668 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
2669 cricket::ContentInfo* video_info =
2670 local_answer->description()->GetContentByName("video");
2671 video_info->rejected = true;
2672 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
2673 EXPECT_EQ(MediaStreamTrackInterface::kEnded, remote_video->state());
2674 EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_audio->state());
2676 // Now create an offer where we reject both video and audio.
2677 std::unique_ptr<SessionDescriptionInterface> local_offer;
2678 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
2679 video_info = local_offer->description()->GetContentByName("video");
2680 ASSERT_TRUE(video_info != nullptr);
2681 video_info->rejected = true;
2682 cricket::ContentInfo* audio_info =
2683 local_offer->description()->GetContentByName("audio");
2684 ASSERT_TRUE(audio_info != nullptr);
2685 audio_info->rejected = true;
2686 EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
2687 // Track state may be updated asynchronously.
2688 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, remote_audio->state(),
2689 kTimeout);
2690 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, remote_video->state(),
2691 kTimeout);
2694 // This tests that we won't crash if the remote track has been removed outside
2695 // of PeerConnection and then PeerConnection tries to reject the track.
2696 // Don't run under Unified Plan since the stream API is not available.
2697 TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackThenRejectMediaContent) {
2698 RTCConfiguration config;
2699 CreatePeerConnection(config);
2700 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2701 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2702 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2703 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2705 std::unique_ptr<SessionDescriptionInterface> local_answer(
2706 webrtc::CreateSessionDescription(SdpType::kAnswer,
2707 GetSdpStringWithStream1(), nullptr));
2708 cricket::ContentInfo* video_info =
2709 local_answer->description()->GetContentByName("video");
2710 video_info->rejected = true;
2711 cricket::ContentInfo* audio_info =
2712 local_answer->description()->GetContentByName("audio");
2713 audio_info->rejected = true;
2714 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
2716 // No crash is a pass.
2719 // This tests that if a recvonly remote description is set, no remote streams
2720 // will be created, even if the description contains SSRCs/MSIDs.
2721 // See: https://code.google.com/p/webrtc/issues/detail?id=5054
2722 TEST_P(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
2723 RTCConfiguration config;
2724 CreatePeerConnection(config);
2726 std::string recvonly_offer = GetSdpStringWithStream1();
2727 absl::StrReplaceAll({{kSendrecv, kRecvonly}}, &recvonly_offer);
2728 CreateAndSetRemoteOffer(recvonly_offer);
2730 EXPECT_EQ(0u, observer_.remote_streams()->count());
2733 // This tests that a default MediaStream is created if a remote session
2734 // description doesn't contain any streams and no MSID support.
2735 // It also tests that the default stream is updated if a video m-line is added
2736 // in a subsequent session description.
2737 // Don't run under Unified Plan since this behavior is Plan B specific.
2738 TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithoutMsidCreatesDefaultStream) {
2739 RTCConfiguration config;
2740 CreatePeerConnection(config);
2741 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2743 ASSERT_EQ(1u, observer_.remote_streams()->count());
2744 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2746 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2747 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
2748 EXPECT_EQ("default", remote_stream->id());
2750 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2751 ASSERT_EQ(1u, observer_.remote_streams()->count());
2752 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2753 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
2754 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2755 remote_stream->GetAudioTracks()[0]->state());
2756 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2757 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
2758 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2759 remote_stream->GetVideoTracks()[0]->state());
2762 // This tests that a default MediaStream is created if a remote session
2763 // description doesn't contain any streams and media direction is send only.
2764 // Don't run under Unified Plan since this behavior is Plan B specific.
2765 TEST_F(PeerConnectionInterfaceTestPlanB,
2766 SendOnlySdpWithoutMsidCreatesDefaultStream) {
2767 RTCConfiguration config;
2768 CreatePeerConnection(config);
2769 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2771 ASSERT_EQ(1u, observer_.remote_streams()->count());
2772 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2774 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2775 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2776 EXPECT_EQ("default", remote_stream->id());
2779 // This tests that it won't crash when PeerConnection tries to remove
2780 // a remote track that as already been removed from the MediaStream.
2781 // Don't run under Unified Plan since this behavior is Plan B specific.
2782 TEST_F(PeerConnectionInterfaceTestPlanB, RemoveAlreadyGoneRemoteStream) {
2783 RTCConfiguration config;
2784 CreatePeerConnection(config);
2785 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2786 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2787 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2788 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2790 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2792 // No crash is a pass.
2795 // This tests that a default MediaStream is created if the remote session
2796 // description doesn't contain any streams and don't contain an indication if
2797 // MSID is supported.
2798 // Don't run under Unified Plan since this behavior is Plan B specific.
2799 TEST_F(PeerConnectionInterfaceTestPlanB,
2800 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
2801 RTCConfiguration config;
2802 CreatePeerConnection(config);
2803 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2805 ASSERT_EQ(1u, observer_.remote_streams()->count());
2806 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2807 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2808 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2811 // This tests that a default MediaStream is not created if the remote session
2812 // description doesn't contain any streams but does support MSID.
2813 // Don't run under Unified Plan since this behavior is Plan B specific.
2814 TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithMsidDontCreatesDefaultStream) {
2815 RTCConfiguration config;
2816 CreatePeerConnection(config);
2817 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2818 EXPECT_EQ(0u, observer_.remote_streams()->count());
2821 // This tests that when setting a new description, the old default tracks are
2822 // not destroyed and recreated.
2823 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
2824 // Don't run under Unified Plan since this behavior is Plan B specific.
2825 TEST_F(PeerConnectionInterfaceTestPlanB,
2826 DefaultTracksNotDestroyedAndRecreated) {
2827 RTCConfiguration config;
2828 CreatePeerConnection(config);
2829 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2831 ASSERT_EQ(1u, observer_.remote_streams()->count());
2832 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2833 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2835 // Set the track to "disabled", then set a new description and ensure the
2836 // track is still disabled, which ensures it hasn't been recreated.
2837 remote_stream->GetAudioTracks()[0]->set_enabled(false);
2838 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2839 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2840 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
2843 // This tests that a default MediaStream is not created if a remote session
2844 // description is updated to not have any MediaStreams.
2845 // Don't run under Unified Plan since this behavior is Plan B specific.
2846 TEST_F(PeerConnectionInterfaceTestPlanB, VerifyDefaultStreamIsNotCreated) {
2847 RTCConfiguration config;
2848 CreatePeerConnection(config);
2849 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
2850 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
2851 EXPECT_TRUE(
2852 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2854 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2855 EXPECT_EQ(0u, observer_.remote_streams()->count());
2858 // This tests that a default MediaStream is created if a remote SDP comes from
2859 // an endpoint that doesn't signal SSRCs, but signals media stream IDs.
2860 TEST_F(PeerConnectionInterfaceTestPlanB,
2861 SdpWithMsidWithoutSsrcCreatesDefaultStream) {
2862 RTCConfiguration config;
2863 CreatePeerConnection(config);
2864 std::string sdp_string = kSdpStringWithoutStreamsAudioOnly;
2865 // Add a=msid lines to simulate a Unified Plan endpoint that only
2866 // signals stream IDs with a=msid lines.
2867 sdp_string.append("a=msid:audio_stream_id audio_track_id\n");
2869 CreateAndSetRemoteOffer(sdp_string);
2871 ASSERT_EQ(1u, observer_.remote_streams()->count());
2872 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2873 EXPECT_EQ("default", remote_stream->id());
2874 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2877 // This tests that when a Plan B endpoint receives an SDP that signals no media
2878 // stream IDs indicated by the special character "-" in the a=msid line, that
2879 // a default stream ID will be used for the MediaStream ID. This can occur
2880 // when a Unified Plan endpoint signals no media stream IDs, but signals both
2881 // a=ssrc msid and a=msid lines for interop signaling with Plan B.
2882 TEST_F(PeerConnectionInterfaceTestPlanB,
2883 SdpWithEmptyMsidAndSsrcCreatesDefaultStreamId) {
2884 RTCConfiguration config;
2885 CreatePeerConnection(config);
2886 // Add a a=msid line to the SDP. This is prioritized when parsing the SDP, so
2887 // the sender's stream ID will be interpreted as no stream IDs.
2888 std::string sdp_string = kSdpStringWithStream1AudioTrackOnly;
2889 sdp_string.append("a=msid:- audiotrack0\n");
2891 CreateAndSetRemoteOffer(sdp_string);
2893 ASSERT_EQ(1u, observer_.remote_streams()->count());
2894 // Because SSRCs are signaled the track ID will be what was signaled in the
2895 // a=msid line.
2896 EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
2897 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2898 EXPECT_EQ("default", remote_stream->id());
2899 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2901 // Previously a bug ocurred when setting the remote description a second time.
2902 // This is because we checked equality of the remote StreamParams stream ID
2903 // (empty), and the previously set stream ID for the remote sender
2904 // ("default"). This cause a track to be removed, then added, when really
2905 // nothing should occur because it is the same track.
2906 CreateAndSetRemoteOffer(sdp_string);
2907 EXPECT_EQ(0u, observer_.remove_track_events_.size());
2908 EXPECT_EQ(1u, observer_.add_track_events_.size());
2909 EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
2910 remote_stream = observer_.remote_streams()->at(0);
2911 EXPECT_EQ("default", remote_stream->id());
2912 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2915 // This tests that an RtpSender is created when the local description is set
2916 // after adding a local stream.
2917 // TODO(deadbeef): This test and the one below it need to be updated when
2918 // an RtpSender's lifetime isn't determined by when a local description is set.
2919 // Don't run under Unified Plan since this behavior is Plan B specific.
2920 TEST_F(PeerConnectionInterfaceTestPlanB, LocalDescriptionChanged) {
2921 RTCConfiguration config;
2922 CreatePeerConnection(config);
2924 // Create an offer with 1 stream with 2 tracks of each type.
2925 rtc::scoped_refptr<StreamCollection> stream_collection =
2926 CreateStreamCollection(1, 2);
2927 pc_->AddStream(stream_collection->at(0));
2928 std::unique_ptr<SessionDescriptionInterface> offer;
2929 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2930 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
2932 auto senders = pc_->GetSenders();
2933 EXPECT_EQ(4u, senders.size());
2934 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2935 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2936 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2937 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2939 // Remove an audio and video track.
2940 pc_->RemoveStream(stream_collection->at(0));
2941 stream_collection = CreateStreamCollection(1, 1);
2942 pc_->AddStream(stream_collection->at(0));
2943 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2944 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
2946 senders = pc_->GetSenders();
2947 EXPECT_EQ(2u, senders.size());
2948 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2949 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2950 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
2951 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
2954 // This tests that an RtpSender is created when the local description is set
2955 // before adding a local stream.
2956 // Don't run under Unified Plan since this behavior is Plan B specific.
2957 TEST_F(PeerConnectionInterfaceTestPlanB,
2958 AddLocalStreamAfterLocalDescriptionChanged) {
2959 RTCConfiguration config;
2960 CreatePeerConnection(config);
2962 rtc::scoped_refptr<StreamCollection> stream_collection =
2963 CreateStreamCollection(1, 2);
2964 // Add a stream to create the offer, but remove it afterwards.
2965 pc_->AddStream(stream_collection->at(0));
2966 std::unique_ptr<SessionDescriptionInterface> offer;
2967 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2968 pc_->RemoveStream(stream_collection->at(0));
2970 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
2971 auto senders = pc_->GetSenders();
2972 EXPECT_EQ(0u, senders.size());
2974 pc_->AddStream(stream_collection->at(0));
2975 senders = pc_->GetSenders();
2976 EXPECT_EQ(4u, senders.size());
2977 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2978 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2979 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2980 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2983 // This tests that the expected behavior occurs if the SSRC on a local track is
2984 // changed when SetLocalDescription is called.
2985 TEST_P(PeerConnectionInterfaceTest,
2986 ChangeSsrcOnTrackInLocalSessionDescription) {
2987 RTCConfiguration config;
2988 CreatePeerConnection(config);
2990 AddAudioTrack(kAudioTracks[0]);
2991 AddVideoTrack(kVideoTracks[0]);
2992 std::unique_ptr<SessionDescriptionInterface> offer;
2993 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2994 // Grab a copy of the offer before it gets passed into the PC.
2995 std::unique_ptr<SessionDescriptionInterface> modified_offer =
2996 webrtc::CreateSessionDescription(
2997 webrtc::SdpType::kOffer, offer->session_id(),
2998 offer->session_version(), offer->description()->Clone());
2999 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
3001 auto senders = pc_->GetSenders();
3002 EXPECT_EQ(2u, senders.size());
3003 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3004 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3006 // Change the ssrc of the audio and video track.
3007 cricket::MediaContentDescription* desc =
3008 cricket::GetFirstAudioContentDescription(modified_offer->description());
3009 ASSERT_TRUE(desc != nullptr);
3010 for (StreamParams& stream : desc->mutable_streams()) {
3011 for (unsigned int& ssrc : stream.ssrcs) {
3012 ++ssrc;
3016 desc =
3017 cricket::GetFirstVideoContentDescription(modified_offer->description());
3018 ASSERT_TRUE(desc != nullptr);
3019 for (StreamParams& stream : desc->mutable_streams()) {
3020 for (unsigned int& ssrc : stream.ssrcs) {
3021 ++ssrc;
3025 EXPECT_TRUE(DoSetLocalDescription(std::move(modified_offer)));
3026 senders = pc_->GetSenders();
3027 EXPECT_EQ(2u, senders.size());
3028 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3029 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3030 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
3031 // changed.
3034 // This tests that the expected behavior occurs if a new session description is
3035 // set with the same tracks, but on a different MediaStream.
3036 // Don't run under Unified Plan since the stream API is not available.
3037 TEST_F(PeerConnectionInterfaceTestPlanB,
3038 SignalSameTracksInSeparateMediaStream) {
3039 RTCConfiguration config;
3040 CreatePeerConnection(config);
3042 rtc::scoped_refptr<StreamCollection> stream_collection =
3043 CreateStreamCollection(2, 1);
3044 pc_->AddStream(stream_collection->at(0));
3045 std::unique_ptr<SessionDescriptionInterface> offer;
3046 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3047 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
3049 auto senders = pc_->GetSenders();
3050 EXPECT_EQ(2u, senders.size());
3051 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
3052 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
3054 // Add a new MediaStream but with the same tracks as in the first stream.
3055 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
3056 webrtc::MediaStream::Create(kStreams[1]));
3057 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
3058 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
3059 pc_->AddStream(stream_1.get());
3061 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3062 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
3064 auto new_senders = pc_->GetSenders();
3065 // Should be the same senders as before, but with updated stream id.
3066 // Note that this behavior is subject to change in the future.
3067 // We may decide the PC should ignore existing tracks in AddStream.
3068 EXPECT_EQ(senders, new_senders);
3069 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
3070 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
3073 // This tests that PeerConnectionObserver::OnAddTrack is correctly called.
3074 TEST_P(PeerConnectionInterfaceTest, OnAddTrackCallback) {
3075 RTCConfiguration config;
3076 CreatePeerConnection(config);
3077 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
3078 EXPECT_EQ(observer_.num_added_tracks_, 1);
3079 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
3081 // Create and set the updated remote SDP.
3082 CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
3083 EXPECT_EQ(observer_.num_added_tracks_, 2);
3084 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
3087 // Test that when SetConfiguration is called and the configuration is
3088 // changing, the next offer causes an ICE restart.
3089 TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingIceRestart) {
3090 PeerConnectionInterface::RTCConfiguration config;
3091 config.sdp_semantics = sdp_semantics_;
3092 config.type = PeerConnectionInterface::kRelay;
3093 CreatePeerConnection(config);
3094 config = pc_->GetConfiguration();
3095 AddAudioTrack(kAudioTracks[0], {kStreamId1});
3096 AddVideoTrack(kVideoTracks[0], {kStreamId1});
3098 // Do initial offer/answer so there's something to restart.
3099 CreateOfferAsLocalDescription();
3100 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
3102 // Grab the ufrags.
3103 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3105 // Change ICE policy, which should trigger an ICE restart on the next offer.
3106 config.type = PeerConnectionInterface::kAll;
3107 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
3108 CreateOfferAsLocalDescription();
3110 // Grab the new ufrags.
3111 std::vector<std::string> subsequent_ufrags =
3112 GetUfrags(pc_->local_description());
3114 // Sanity check.
3115 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
3116 // Check that each ufrag is different.
3117 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
3118 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
3122 // Test that when SetConfiguration is called and the configuration *isn't*
3123 // changing, the next offer does *not* cause an ICE restart.
3124 TEST_P(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRestart) {
3125 PeerConnectionInterface::RTCConfiguration config;
3126 config.sdp_semantics = sdp_semantics_;
3127 config.type = PeerConnectionInterface::kRelay;
3128 CreatePeerConnection(config);
3129 config = pc_->GetConfiguration();
3130 AddAudioTrack(kAudioTracks[0]);
3131 AddVideoTrack(kVideoTracks[0]);
3133 // Do initial offer/answer so there's something to restart.
3134 CreateOfferAsLocalDescription();
3135 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
3137 // Grab the ufrags.
3138 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3140 // Call SetConfiguration with a config identical to what the PC was
3141 // constructed with.
3142 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
3143 CreateOfferAsLocalDescription();
3145 // Grab the new ufrags.
3146 std::vector<std::string> subsequent_ufrags =
3147 GetUfrags(pc_->local_description());
3149 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
3152 // Test for a weird corner case scenario:
3153 // 1. Audio/video session established.
3154 // 2. SetConfiguration changes ICE config; ICE restart needed.
3155 // 3. ICE restart initiated by remote peer, but only for one m= section.
3156 // 4. Next createOffer should initiate an ICE restart, but only for the other
3157 // m= section; it would be pointless to do an ICE restart for the m= section
3158 // that was already restarted.
3159 TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
3160 PeerConnectionInterface::RTCConfiguration config;
3161 config.sdp_semantics = sdp_semantics_;
3162 config.type = PeerConnectionInterface::kRelay;
3163 CreatePeerConnection(config);
3164 config = pc_->GetConfiguration();
3165 AddAudioTrack(kAudioTracks[0], {kStreamId1});
3166 AddVideoTrack(kVideoTracks[0], {kStreamId1});
3168 // Do initial offer/answer so there's something to restart.
3169 CreateOfferAsLocalDescription();
3170 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
3172 // Change ICE policy, which should set the "needs-ice-restart" flag.
3173 config.type = PeerConnectionInterface::kAll;
3174 EXPECT_TRUE(pc_->SetConfiguration(config).ok());
3176 // Do ICE restart for the first m= section, initiated by remote peer.
3177 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_offer(
3178 webrtc::CreateSessionDescription(SdpType::kOffer,
3179 GetSdpStringWithStream1(), nullptr));
3180 ASSERT_TRUE(remote_offer);
3181 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3182 "modified";
3183 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
3184 CreateAnswerAsLocalDescription();
3186 // Grab the ufrags.
3187 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3188 ASSERT_EQ(2U, initial_ufrags.size());
3190 // Create offer and grab the new ufrags.
3191 CreateOfferAsLocalDescription();
3192 std::vector<std::string> subsequent_ufrags =
3193 GetUfrags(pc_->local_description());
3194 ASSERT_EQ(2U, subsequent_ufrags.size());
3196 // Ensure that only the ufrag for the second m= section changed.
3197 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3198 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3201 // Tests that the methods to return current/pending descriptions work as
3202 // expected at different points in the offer/answer exchange. This test does
3203 // one offer/answer exchange as the offerer, then another as the answerer.
3204 TEST_P(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
3205 // This disables DTLS so we can apply an answer to ourselves.
3206 CreatePeerConnection();
3208 // Create initial local offer and get SDP (which will also be used as
3209 // answer/pranswer);
3210 std::unique_ptr<SessionDescriptionInterface> local_offer;
3211 ASSERT_TRUE(DoCreateOffer(&local_offer, nullptr));
3212 std::string sdp;
3213 EXPECT_TRUE(local_offer->ToString(&sdp));
3215 // Set local offer.
3216 SessionDescriptionInterface* local_offer_ptr = local_offer.get();
3217 EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
3218 EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
3219 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3220 EXPECT_EQ(nullptr, pc_->current_local_description());
3221 EXPECT_EQ(nullptr, pc_->current_remote_description());
3223 // Set remote pranswer.
3224 std::unique_ptr<SessionDescriptionInterface> remote_pranswer(
3225 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
3226 SessionDescriptionInterface* remote_pranswer_ptr = remote_pranswer.get();
3227 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_pranswer)));
3228 EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
3229 EXPECT_EQ(remote_pranswer_ptr, pc_->pending_remote_description());
3230 EXPECT_EQ(nullptr, pc_->current_local_description());
3231 EXPECT_EQ(nullptr, pc_->current_remote_description());
3233 // Set remote answer.
3234 std::unique_ptr<SessionDescriptionInterface> remote_answer(
3235 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
3236 SessionDescriptionInterface* remote_answer_ptr = remote_answer.get();
3237 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_answer)));
3238 EXPECT_EQ(nullptr, pc_->pending_local_description());
3239 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3240 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3241 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
3243 // Set remote offer.
3244 std::unique_ptr<SessionDescriptionInterface> remote_offer(
3245 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
3246 SessionDescriptionInterface* remote_offer_ptr = remote_offer.get();
3247 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
3248 EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
3249 EXPECT_EQ(nullptr, pc_->pending_local_description());
3250 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3251 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
3253 // Set local pranswer.
3254 std::unique_ptr<SessionDescriptionInterface> local_pranswer(
3255 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
3256 SessionDescriptionInterface* local_pranswer_ptr = local_pranswer.get();
3257 EXPECT_TRUE(DoSetLocalDescription(std::move(local_pranswer)));
3258 EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
3259 EXPECT_EQ(local_pranswer_ptr, pc_->pending_local_description());
3260 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3261 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
3263 // Set local answer.
3264 std::unique_ptr<SessionDescriptionInterface> local_answer(
3265 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
3266 SessionDescriptionInterface* local_answer_ptr = local_answer.get();
3267 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
3268 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3269 EXPECT_EQ(nullptr, pc_->pending_local_description());
3270 EXPECT_EQ(remote_offer_ptr, pc_->current_remote_description());
3271 EXPECT_EQ(local_answer_ptr, pc_->current_local_description());
3274 // Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3275 // after the PeerConnection is closed.
3276 // This version tests the StartRtcEventLog version that receives an object
3277 // of type `RtcEventLogOutput`.
3278 TEST_P(PeerConnectionInterfaceTest,
3279 StartAndStopLoggingToOutputAfterPeerConnectionClosed) {
3280 CreatePeerConnection();
3281 // The RtcEventLog will be reset when the PeerConnection is closed.
3282 pc_->Close();
3284 EXPECT_FALSE(
3285 pc_->StartRtcEventLog(std::make_unique<webrtc::RtcEventLogOutputNull>(),
3286 webrtc::RtcEventLog::kImmediateOutput));
3287 pc_->StopRtcEventLog();
3290 // Test that generated offers/answers include "ice-option:trickle".
3291 TEST_P(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
3292 CreatePeerConnection();
3294 // First, create an offer with audio/video.
3295 RTCOfferAnswerOptions options;
3296 options.offer_to_receive_audio = 1;
3297 options.offer_to_receive_video = 1;
3298 std::unique_ptr<SessionDescriptionInterface> offer;
3299 ASSERT_TRUE(DoCreateOffer(&offer, &options));
3300 cricket::SessionDescription* desc = offer->description();
3301 ASSERT_EQ(2u, desc->transport_infos().size());
3302 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3303 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3305 // Apply the offer as a remote description, then create an answer.
3306 EXPECT_FALSE(pc_->can_trickle_ice_candidates());
3307 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3308 ASSERT_TRUE(pc_->can_trickle_ice_candidates());
3309 EXPECT_TRUE(*(pc_->can_trickle_ice_candidates()));
3310 std::unique_ptr<SessionDescriptionInterface> answer;
3311 ASSERT_TRUE(DoCreateAnswer(&answer, &options));
3312 desc = answer->description();
3313 ASSERT_EQ(2u, desc->transport_infos().size());
3314 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3315 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3318 // Test that ICE renomination isn't offered if it's not enabled in the PC's
3319 // RTCConfiguration.
3320 TEST_P(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
3321 PeerConnectionInterface::RTCConfiguration config;
3322 config.sdp_semantics = sdp_semantics_;
3323 config.enable_ice_renomination = false;
3324 CreatePeerConnection(config);
3325 AddAudioTrack("foo");
3327 std::unique_ptr<SessionDescriptionInterface> offer;
3328 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3329 cricket::SessionDescription* desc = offer->description();
3330 EXPECT_EQ(1u, desc->transport_infos().size());
3331 EXPECT_FALSE(
3332 desc->transport_infos()[0].description.GetIceParameters().renomination);
3335 // Test that the ICE renomination option is present in generated offers/answers
3336 // if it's enabled in the PC's RTCConfiguration.
3337 TEST_P(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
3338 PeerConnectionInterface::RTCConfiguration config;
3339 config.sdp_semantics = sdp_semantics_;
3340 config.enable_ice_renomination = true;
3341 CreatePeerConnection(config);
3342 AddAudioTrack("foo");
3344 std::unique_ptr<SessionDescriptionInterface> offer;
3345 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3346 cricket::SessionDescription* desc = offer->description();
3347 EXPECT_EQ(1u, desc->transport_infos().size());
3348 EXPECT_TRUE(
3349 desc->transport_infos()[0].description.GetIceParameters().renomination);
3351 // Set the offer as a remote description, then create an answer and ensure it
3352 // has the renomination flag too.
3353 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3354 std::unique_ptr<SessionDescriptionInterface> answer;
3355 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3356 desc = answer->description();
3357 EXPECT_EQ(1u, desc->transport_infos().size());
3358 EXPECT_TRUE(
3359 desc->transport_infos()[0].description.GetIceParameters().renomination);
3362 // Test that if CreateOffer is called with the deprecated "offer to receive
3363 // audio/video" constraints, they're processed and result in an offer with
3364 // audio/video sections just as if RTCOfferAnswerOptions had been used.
3365 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
3366 CreatePeerConnection();
3368 RTCOfferAnswerOptions options;
3369 options.offer_to_receive_audio = 1;
3370 options.offer_to_receive_video = 1;
3371 std::unique_ptr<SessionDescriptionInterface> offer;
3372 ASSERT_TRUE(DoCreateOffer(&offer, &options));
3374 cricket::SessionDescription* desc = offer->description();
3375 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3376 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3377 ASSERT_NE(nullptr, audio);
3378 ASSERT_NE(nullptr, video);
3379 EXPECT_FALSE(audio->rejected);
3380 EXPECT_FALSE(video->rejected);
3383 // Test that if CreateAnswer is called with the deprecated "offer to receive
3384 // audio/video" constraints, they're processed and can be used to reject an
3385 // offered m= section just as can be done with RTCOfferAnswerOptions;
3386 // Don't run under Unified Plan since this behavior is not supported.
3387 TEST_F(PeerConnectionInterfaceTestPlanB,
3388 CreateAnswerWithOfferToReceiveConstraints) {
3389 CreatePeerConnection();
3391 // First, create an offer with audio/video and apply it as a remote
3392 // description.
3393 RTCOfferAnswerOptions options;
3394 options.offer_to_receive_audio = 1;
3395 options.offer_to_receive_video = 1;
3396 std::unique_ptr<SessionDescriptionInterface> offer;
3397 ASSERT_TRUE(DoCreateOffer(&offer, &options));
3398 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3400 // Now create answer that rejects audio/video.
3401 options.offer_to_receive_audio = 0;
3402 options.offer_to_receive_video = 0;
3403 std::unique_ptr<SessionDescriptionInterface> answer;
3404 ASSERT_TRUE(DoCreateAnswer(&answer, &options));
3406 cricket::SessionDescription* desc = answer->description();
3407 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3408 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3409 ASSERT_NE(nullptr, audio);
3410 ASSERT_NE(nullptr, video);
3411 EXPECT_TRUE(audio->rejected);
3412 EXPECT_TRUE(video->rejected);
3415 // Test that negotiation can succeed with a data channel only, and with the max
3416 // bundle policy. Previously there was a bug that prevented this.
3417 #ifdef WEBRTC_HAVE_SCTP
3418 TEST_P(PeerConnectionInterfaceTest, DataChannelOnlyOfferWithMaxBundlePolicy) {
3419 #else
3420 TEST_P(PeerConnectionInterfaceTest,
3421 DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy) {
3422 #endif // WEBRTC_HAVE_SCTP
3423 PeerConnectionInterface::RTCConfiguration config;
3424 config.sdp_semantics = sdp_semantics_;
3425 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3426 CreatePeerConnection(config);
3428 // First, create an offer with only a data channel and apply it as a remote
3429 // description.
3430 pc_->CreateDataChannelOrError("test", nullptr);
3431 std::unique_ptr<SessionDescriptionInterface> offer;
3432 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3433 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3435 // Create and set answer as well.
3436 std::unique_ptr<SessionDescriptionInterface> answer;
3437 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3438 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
3441 TEST_P(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
3442 CreatePeerConnection();
3443 BitrateSettings bitrate;
3444 bitrate.start_bitrate_bps = 100000;
3445 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3448 TEST_P(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
3449 CreatePeerConnection();
3450 BitrateSettings bitrate;
3451 bitrate.min_bitrate_bps = -1;
3452 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3455 TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
3456 CreatePeerConnection();
3457 BitrateSettings bitrate;
3458 bitrate.min_bitrate_bps = 5;
3459 bitrate.start_bitrate_bps = 3;
3460 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3463 TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
3464 CreatePeerConnection();
3465 BitrateSettings bitrate;
3466 bitrate.start_bitrate_bps = -1;
3467 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3470 TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
3471 CreatePeerConnection();
3472 BitrateSettings bitrate;
3473 bitrate.start_bitrate_bps = 10;
3474 bitrate.max_bitrate_bps = 8;
3475 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3478 TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
3479 CreatePeerConnection();
3480 BitrateSettings bitrate;
3481 bitrate.min_bitrate_bps = 10;
3482 bitrate.max_bitrate_bps = 8;
3483 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3486 TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
3487 CreatePeerConnection();
3488 BitrateSettings bitrate;
3489 bitrate.max_bitrate_bps = -1;
3490 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3493 // The current bitrate from BitrateSettings is currently clamped
3494 // by Call's BitrateConstraints, which comes from the SDP or a default value.
3495 // This test checks that a call to SetBitrate with a current bitrate that will
3496 // be clamped succeeds.
3497 TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
3498 CreatePeerConnection();
3499 BitrateSettings bitrate;
3500 bitrate.start_bitrate_bps = 1;
3501 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3504 // The following tests verify that the offer can be created correctly.
3505 TEST_P(PeerConnectionInterfaceTest,
3506 CreateOfferFailsWithInvalidOfferToReceiveAudio) {
3507 RTCOfferAnswerOptions rtc_options;
3509 // Setting offer_to_receive_audio to a value lower than kUndefined or greater
3510 // than kMaxOfferToReceiveMedia should be treated as invalid.
3511 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3512 CreatePeerConnection();
3513 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3515 rtc_options.offer_to_receive_audio =
3516 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
3517 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3520 TEST_P(PeerConnectionInterfaceTest,
3521 CreateOfferFailsWithInvalidOfferToReceiveVideo) {
3522 RTCOfferAnswerOptions rtc_options;
3524 // Setting offer_to_receive_video to a value lower than kUndefined or greater
3525 // than kMaxOfferToReceiveMedia should be treated as invalid.
3526 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3527 CreatePeerConnection();
3528 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3530 rtc_options.offer_to_receive_video =
3531 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
3532 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3535 // Test that the audio and video content will be added to an offer if both
3536 // `offer_to_receive_audio` and `offer_to_receive_video` options are 1.
3537 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioVideoOptions) {
3538 RTCOfferAnswerOptions rtc_options;
3539 rtc_options.offer_to_receive_audio = 1;
3540 rtc_options.offer_to_receive_video = 1;
3542 std::unique_ptr<SessionDescriptionInterface> offer;
3543 CreatePeerConnection();
3544 offer = CreateOfferWithOptions(rtc_options);
3545 ASSERT_TRUE(offer);
3546 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3547 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3550 // Test that only audio content will be added to the offer if only
3551 // `offer_to_receive_audio` options is 1.
3552 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioOnlyOptions) {
3553 RTCOfferAnswerOptions rtc_options;
3554 rtc_options.offer_to_receive_audio = 1;
3555 rtc_options.offer_to_receive_video = 0;
3557 std::unique_ptr<SessionDescriptionInterface> offer;
3558 CreatePeerConnection();
3559 offer = CreateOfferWithOptions(rtc_options);
3560 ASSERT_TRUE(offer);
3561 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3562 EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
3565 // Test that only video content will be added if only `offer_to_receive_video`
3566 // options is 1.
3567 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithVideoOnlyOptions) {
3568 RTCOfferAnswerOptions rtc_options;
3569 rtc_options.offer_to_receive_audio = 0;
3570 rtc_options.offer_to_receive_video = 1;
3572 std::unique_ptr<SessionDescriptionInterface> offer;
3573 CreatePeerConnection();
3574 offer = CreateOfferWithOptions(rtc_options);
3575 ASSERT_TRUE(offer);
3576 EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
3577 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3580 // Test that no media content will be added to the offer if using default
3581 // RTCOfferAnswerOptions.
3582 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithDefaultOfferAnswerOptions) {
3583 RTCOfferAnswerOptions rtc_options;
3585 std::unique_ptr<SessionDescriptionInterface> offer;
3586 CreatePeerConnection();
3587 offer = CreateOfferWithOptions(rtc_options);
3588 ASSERT_TRUE(offer);
3589 EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
3590 EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
3593 // Test that if `ice_restart` is true, the ufrag/pwd will change, otherwise
3594 // ufrag/pwd will be the same in the new offer.
3595 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithIceRestart) {
3596 CreatePeerConnection();
3598 RTCOfferAnswerOptions rtc_options;
3599 rtc_options.ice_restart = false;
3600 rtc_options.offer_to_receive_audio = 1;
3602 std::unique_ptr<SessionDescriptionInterface> offer;
3603 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
3604 std::string mid = cricket::GetFirstAudioContent(offer->description())->name;
3605 auto ufrag1 =
3606 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3607 auto pwd1 =
3608 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
3610 // `ice_restart` is false, the ufrag/pwd shouldn't change.
3611 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
3612 auto ufrag2 =
3613 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3614 auto pwd2 =
3615 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
3617 // `ice_restart` is true, the ufrag/pwd should change.
3618 rtc_options.ice_restart = true;
3619 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
3620 auto ufrag3 =
3621 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3622 auto pwd3 =
3623 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
3625 EXPECT_EQ(ufrag1, ufrag2);
3626 EXPECT_EQ(pwd1, pwd2);
3627 EXPECT_NE(ufrag2, ufrag3);
3628 EXPECT_NE(pwd2, pwd3);
3631 // Test that if `use_rtp_mux` is true, the bundling will be enabled in the
3632 // offer; if it is false, there won't be any bundle group in the offer.
3633 TEST_P(PeerConnectionInterfaceTest, CreateOfferWithRtpMux) {
3634 RTCOfferAnswerOptions rtc_options;
3635 rtc_options.offer_to_receive_audio = 1;
3636 rtc_options.offer_to_receive_video = 1;
3638 std::unique_ptr<SessionDescriptionInterface> offer;
3639 CreatePeerConnection();
3641 rtc_options.use_rtp_mux = true;
3642 offer = CreateOfferWithOptions(rtc_options);
3643 ASSERT_TRUE(offer);
3644 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3645 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3646 EXPECT_TRUE(offer->description()->HasGroup(cricket::GROUP_TYPE_BUNDLE));
3648 rtc_options.use_rtp_mux = false;
3649 offer = CreateOfferWithOptions(rtc_options);
3650 ASSERT_TRUE(offer);
3651 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3652 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3653 EXPECT_FALSE(offer->description()->HasGroup(cricket::GROUP_TYPE_BUNDLE));
3656 // This test ensures OnRenegotiationNeeded is called when we add track with
3657 // MediaStream -> AddTrack in the same way it is called when we add track with
3658 // PeerConnection -> AddTrack.
3659 // The test can be removed once addStream is rewritten in terms of addTrack
3660 // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
3661 // Don't run under Unified Plan since the stream API is not available.
3662 TEST_F(PeerConnectionInterfaceTestPlanB,
3663 MediaStreamAddTrackRemoveTrackRenegotiate) {
3664 CreatePeerConnectionWithoutDtls();
3665 rtc::scoped_refptr<MediaStreamInterface> stream(
3666 pc_factory_->CreateLocalMediaStream(kStreamId1));
3667 pc_->AddStream(stream.get());
3668 rtc::scoped_refptr<AudioTrackInterface> audio_track(
3669 CreateAudioTrack("audio_track"));
3670 rtc::scoped_refptr<VideoTrackInterface> video_track(
3671 CreateVideoTrack("video_track"));
3672 stream->AddTrack(audio_track);
3673 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3674 observer_.renegotiation_needed_ = false;
3676 CreateOfferReceiveAnswer();
3677 stream->AddTrack(video_track);
3678 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3679 observer_.renegotiation_needed_ = false;
3681 CreateOfferReceiveAnswer();
3682 stream->RemoveTrack(audio_track);
3683 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3684 observer_.renegotiation_needed_ = false;
3686 CreateOfferReceiveAnswer();
3687 stream->RemoveTrack(video_track);
3688 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3689 observer_.renegotiation_needed_ = false;
3692 // Tests that an error is returned if a description is applied that has fewer
3693 // media sections than the existing description.
3694 TEST_P(PeerConnectionInterfaceTest,
3695 MediaSectionCountEnforcedForSubsequentOffer) {
3696 CreatePeerConnection();
3697 AddAudioTrack("audio_label");
3698 AddVideoTrack("video_label");
3700 std::unique_ptr<SessionDescriptionInterface> offer;
3701 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3702 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3704 // A remote offer with fewer media sections should be rejected.
3705 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3706 offer->description()->contents().pop_back();
3707 offer->description()->contents().pop_back();
3708 ASSERT_TRUE(offer->description()->contents().empty());
3709 EXPECT_FALSE(DoSetRemoteDescription(std::move(offer)));
3711 std::unique_ptr<SessionDescriptionInterface> answer;
3712 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3713 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
3715 // A subsequent local offer with fewer media sections should be rejected.
3716 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3717 offer->description()->contents().pop_back();
3718 offer->description()->contents().pop_back();
3719 ASSERT_TRUE(offer->description()->contents().empty());
3720 EXPECT_FALSE(DoSetLocalDescription(std::move(offer)));
3723 TEST_P(PeerConnectionInterfaceTest, ExtmapAllowMixedIsConfigurable) {
3724 RTCConfiguration config;
3725 // Default behavior is true.
3726 CreatePeerConnection(config);
3727 std::unique_ptr<SessionDescriptionInterface> offer;
3728 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3729 EXPECT_TRUE(offer->description()->extmap_allow_mixed());
3730 // Possible to set to false.
3731 config.offer_extmap_allow_mixed = false;
3732 CreatePeerConnection(config);
3733 offer = nullptr;
3734 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3735 EXPECT_FALSE(offer->description()->extmap_allow_mixed());
3738 TEST_P(PeerConnectionInterfaceTest,
3739 RtpSenderSetDegradationPreferenceWithoutEncodings) {
3740 CreatePeerConnection();
3741 AddVideoTrack("video_label");
3743 std::vector<rtc::scoped_refptr<RtpSenderInterface>> rtp_senders =
3744 pc_->GetSenders();
3745 ASSERT_EQ(rtp_senders.size(), 1u);
3746 ASSERT_EQ(rtp_senders[0]->media_type(), cricket::MEDIA_TYPE_VIDEO);
3747 rtc::scoped_refptr<RtpSenderInterface> video_rtp_sender = rtp_senders[0];
3748 RtpParameters parameters = video_rtp_sender->GetParameters();
3749 ASSERT_NE(parameters.degradation_preference,
3750 DegradationPreference::MAINTAIN_RESOLUTION);
3751 parameters.degradation_preference =
3752 DegradationPreference::MAINTAIN_RESOLUTION;
3753 ASSERT_TRUE(video_rtp_sender->SetParameters(parameters).ok());
3755 std::unique_ptr<SessionDescriptionInterface> local_offer;
3756 ASSERT_TRUE(DoCreateOffer(&local_offer, nullptr));
3757 ASSERT_TRUE(DoSetLocalDescription(std::move(local_offer)));
3759 RtpParameters parameters_new = video_rtp_sender->GetParameters();
3760 ASSERT_EQ(parameters_new.degradation_preference,
3761 DegradationPreference::MAINTAIN_RESOLUTION);
3764 INSTANTIATE_TEST_SUITE_P(PeerConnectionInterfaceTest,
3765 PeerConnectionInterfaceTest,
3766 Values(SdpSemantics::kPlanB_DEPRECATED,
3767 SdpSemantics::kUnifiedPlan));
3769 class PeerConnectionMediaConfigTest : public ::testing::Test {
3770 protected:
3771 void SetUp() override {
3772 pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
3774 const cricket::MediaConfig TestCreatePeerConnection(
3775 const RTCConfiguration& config) {
3776 PeerConnectionDependencies pc_dependencies(&observer_);
3777 auto result =
3778 pcf_->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
3779 EXPECT_TRUE(result.ok());
3780 observer_.SetPeerConnectionInterface(result.value().get());
3781 return result.value()->GetConfiguration().media_config;
3784 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
3785 MockPeerConnectionObserver observer_;
3788 // This sanity check validates the test infrastructure itself.
3789 TEST_F(PeerConnectionMediaConfigTest, TestCreateAndClose) {
3790 PeerConnectionInterface::RTCConfiguration config;
3791 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3792 PeerConnectionDependencies pc_dependencies(&observer_);
3793 auto result =
3794 pcf_->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
3795 EXPECT_TRUE(result.ok());
3796 observer_.SetPeerConnectionInterface(result.value().get());
3797 result.value()->Close(); // No abort -> ok.
3798 SUCCEED();
3801 // This test verifies the default behaviour with no constraints and a
3802 // default RTCConfiguration.
3803 TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3804 PeerConnectionInterface::RTCConfiguration config;
3805 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3807 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
3809 EXPECT_TRUE(media_config.enable_dscp);
3810 EXPECT_TRUE(media_config.video.enable_cpu_adaptation);
3811 EXPECT_TRUE(media_config.video.enable_prerenderer_smoothing);
3812 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
3813 EXPECT_FALSE(media_config.video.experiment_cpu_load_estimator);
3816 // This test verifies that the enable_prerenderer_smoothing flag is
3817 // propagated from RTCConfiguration to the PeerConnection.
3818 TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3819 PeerConnectionInterface::RTCConfiguration config;
3820 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3822 config.set_prerenderer_smoothing(false);
3823 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
3825 EXPECT_FALSE(media_config.video.enable_prerenderer_smoothing);
3828 // This test verifies that the experiment_cpu_load_estimator flag is
3829 // propagated from RTCConfiguration to the PeerConnection.
3830 TEST_F(PeerConnectionMediaConfigTest, TestEnableExperimentCpuLoadEstimator) {
3831 PeerConnectionInterface::RTCConfiguration config;
3832 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3834 config.set_experiment_cpu_load_estimator(true);
3835 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
3837 EXPECT_TRUE(media_config.video.experiment_cpu_load_estimator);
3840 // Tests a few random fields being different.
3841 TEST(RTCConfigurationTest, ComparisonOperators) {
3842 PeerConnectionInterface::RTCConfiguration a;
3843 PeerConnectionInterface::RTCConfiguration b;
3844 EXPECT_EQ(a, b);
3846 PeerConnectionInterface::RTCConfiguration c;
3847 c.servers.push_back(PeerConnectionInterface::IceServer());
3848 EXPECT_NE(a, c);
3850 PeerConnectionInterface::RTCConfiguration d;
3851 d.type = PeerConnectionInterface::kRelay;
3852 EXPECT_NE(a, d);
3854 PeerConnectionInterface::RTCConfiguration e;
3855 e.audio_jitter_buffer_max_packets = 5;
3856 EXPECT_NE(a, e);
3858 PeerConnectionInterface::RTCConfiguration f;
3859 f.ice_connection_receiving_timeout = 1337;
3860 EXPECT_NE(a, f);
3862 PeerConnectionInterface::RTCConfiguration h(
3863 PeerConnectionInterface::RTCConfigurationType::kAggressive);
3864 EXPECT_NE(a, h);
3867 } // namespace
3868 } // namespace webrtc