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