blob: 2f6c0efbe038bff95206500b21d45f1908ed5123 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Zhi Huang2a5e4262017-09-14 01:15:03 -070011#include <algorithm>
kwibergd1fe2812016-04-27 06:47:29 -070012#include <memory>
deadbeef3edec7c2016-12-10 11:44:26 -080013#include <sstream>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000014#include <string>
kwiberg0eb15ed2015-12-17 03:04:15 -080015#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
Karl Wiberg918f50c2018-07-05 11:40:33 +020017#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/audio_codecs/builtin_audio_decoder_factory.h"
19#include "api/audio_codecs/builtin_audio_encoder_factory.h"
20#include "api/jsepsessiondescription.h"
21#include "api/mediastreaminterface.h"
22#include "api/peerconnectioninterface.h"
23#include "api/rtpreceiverinterface.h"
24#include "api/rtpsenderinterface.h"
Anders Carlsson67537952018-05-03 11:28:29 +020025#include "api/video_codecs/builtin_video_decoder_factory.h"
26#include "api/video_codecs/builtin_video_encoder_factory.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020027#include "logging/rtc_event_log/output/rtc_event_log_output_file.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "media/base/fakevideocapturer.h"
29#include "media/engine/webrtcmediaengine.h"
30#include "media/sctp/sctptransportinternal.h"
31#include "modules/audio_processing/include/audio_processing.h"
32#include "p2p/base/fakeportallocator.h"
33#include "pc/audiotrack.h"
34#include "pc/mediasession.h"
35#include "pc/mediastream.h"
36#include "pc/peerconnection.h"
Steve Anton57858b32018-02-15 15:19:50 -080037#include "pc/rtpsender.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "pc/streamcollection.h"
39#include "pc/test/fakeaudiocapturemodule.h"
40#include "pc/test/fakertccertificategenerator.h"
41#include "pc/test/fakevideotracksource.h"
42#include "pc/test/mockpeerconnectionobservers.h"
43#include "pc/test/testsdpstrings.h"
44#include "pc/videocapturertracksource.h"
45#include "pc/videotrack.h"
46#include "rtc_base/gunit.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020047#include "rtc_base/stringutils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "rtc_base/virtualsocketserver.h"
49#include "test/gmock.h"
Elad Alon9e6565b2017-10-11 16:04:13 +020050#include "test/testsupport/fileutils.h"
kwibergac9f8762016-09-30 22:29:43 -070051
52#ifdef WEBRTC_ANDROID
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "pc/test/androidtestinitializer.h"
kwibergac9f8762016-09-30 22:29:43 -070054#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055
Seth Hampson845e8782018-03-02 11:34:10 -080056static const char kStreamId1[] = "local_stream_1";
57static const char kStreamId2[] = "local_stream_2";
58static const char kStreamId3[] = "local_stream_3";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059static const int kDefaultStunPort = 3478;
60static const char kStunAddressOnly[] = "stun:address";
61static const char kStunInvalidPort[] = "stun:address:-1";
62static const char kStunAddressPortAndMore1[] = "stun:address:port:more";
63static const char kStunAddressPortAndMore2[] = "stun:address:port more";
64static const char kTurnIceServerUri[] = "turn:user@turn.example.org";
65static const char kTurnUsername[] = "user";
66static const char kTurnPassword[] = "password";
67static const char kTurnHostname[] = "turn.example.org";
Peter Boström0c4e06b2015-10-07 12:23:21 +020068static const uint32_t kTimeout = 10000U;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
deadbeefab9b2d12015-10-14 11:33:11 -070070static const char kStreams[][8] = {"stream1", "stream2"};
71static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
72static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
73
deadbeef5e97fb52015-10-15 12:49:08 -070074static const char kRecvonly[] = "recvonly";
75static const char kSendrecv[] = "sendrecv";
76
deadbeefab9b2d12015-10-14 11:33:11 -070077// Reference SDP with a MediaStream with label "stream1" and audio track with
78// id "audio_1" and a video track with id "video_1;
Steve Anton36da6ff2018-02-16 16:04:20 -080079static const char kSdpStringWithStream1PlanB[] =
deadbeefab9b2d12015-10-14 11:33:11 -070080 "v=0\r\n"
81 "o=- 0 0 IN IP4 127.0.0.1\r\n"
82 "s=-\r\n"
83 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080084 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070085 "a=ice-ufrag:e5785931\r\n"
86 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
87 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
88 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070089 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070090 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080091 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070092 "a=rtpmap:103 ISAC/16000\r\n"
93 "a=ssrc:1 cname:stream1\r\n"
94 "a=ssrc:1 mslabel:stream1\r\n"
95 "a=ssrc:1 label:audiotrack0\r\n"
96 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080097 "a=ice-ufrag:e5785931\r\n"
98 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
99 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
100 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700101 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700102 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800103 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700104 "a=rtpmap:120 VP8/90000\r\n"
105 "a=ssrc:2 cname:stream1\r\n"
106 "a=ssrc:2 mslabel:stream1\r\n"
107 "a=ssrc:2 label:videotrack0\r\n";
Steve Anton36da6ff2018-02-16 16:04:20 -0800108// Same string as above but with the MID changed to the Unified Plan default.
109// This is needed so that this SDP can be used as an answer for a Unified Plan
110// offer.
111static const char kSdpStringWithStream1UnifiedPlan[] =
112 "v=0\r\n"
113 "o=- 0 0 IN IP4 127.0.0.1\r\n"
114 "s=-\r\n"
115 "t=0 0\r\n"
116 "m=audio 1 RTP/AVPF 103\r\n"
117 "a=ice-ufrag:e5785931\r\n"
118 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
119 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
120 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
121 "a=mid:0\r\n"
122 "a=sendrecv\r\n"
123 "a=rtcp-mux\r\n"
124 "a=rtpmap:103 ISAC/16000\r\n"
125 "a=ssrc:1 cname:stream1\r\n"
126 "a=ssrc:1 mslabel:stream1\r\n"
127 "a=ssrc:1 label:audiotrack0\r\n"
128 "m=video 1 RTP/AVPF 120\r\n"
129 "a=ice-ufrag:e5785931\r\n"
130 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
131 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
132 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
133 "a=mid:1\r\n"
134 "a=sendrecv\r\n"
135 "a=rtcp-mux\r\n"
136 "a=rtpmap:120 VP8/90000\r\n"
137 "a=ssrc:2 cname:stream1\r\n"
138 "a=ssrc:2 mslabel:stream1\r\n"
139 "a=ssrc:2 label:videotrack0\r\n";
deadbeefab9b2d12015-10-14 11:33:11 -0700140
zhihuang81c3a032016-11-17 12:06:24 -0800141// Reference SDP with a MediaStream with label "stream1" and audio track with
142// id "audio_1";
143static const char kSdpStringWithStream1AudioTrackOnly[] =
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"
deadbeefd1a38b52016-12-10 13:15:33 -0800148 "m=audio 1 RTP/AVPF 103\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800149 "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"
zhihuang81c3a032016-11-17 12:06:24 -0800153 "a=mid:audio\r\n"
154 "a=sendrecv\r\n"
155 "a=rtpmap:103 ISAC/16000\r\n"
156 "a=ssrc:1 cname:stream1\r\n"
157 "a=ssrc:1 mslabel:stream1\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800158 "a=ssrc:1 label:audiotrack0\r\n"
159 "a=rtcp-mux\r\n";
zhihuang81c3a032016-11-17 12:06:24 -0800160
deadbeefab9b2d12015-10-14 11:33:11 -0700161// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
162// MediaStreams have one audio track and one video track.
163// This uses MSID.
Steve Anton36da6ff2018-02-16 16:04:20 -0800164static const char kSdpStringWithStream1And2PlanB[] =
deadbeefab9b2d12015-10-14 11:33:11 -0700165 "v=0\r\n"
166 "o=- 0 0 IN IP4 127.0.0.1\r\n"
167 "s=-\r\n"
168 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800169 "a=msid-semantic: WMS stream1 stream2\r\n"
170 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700171 "a=ice-ufrag:e5785931\r\n"
172 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
173 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
174 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700175 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700176 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800177 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700178 "a=rtpmap:103 ISAC/16000\r\n"
179 "a=ssrc:1 cname:stream1\r\n"
180 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
181 "a=ssrc:3 cname:stream2\r\n"
182 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
183 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800184 "a=ice-ufrag:e5785931\r\n"
185 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
186 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
187 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700188 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700189 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800190 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700191 "a=rtpmap:120 VP8/0\r\n"
192 "a=ssrc:2 cname:stream1\r\n"
193 "a=ssrc:2 msid:stream1 videotrack0\r\n"
194 "a=ssrc:4 cname:stream2\r\n"
195 "a=ssrc:4 msid:stream2 videotrack1\r\n";
Steve Anton36da6ff2018-02-16 16:04:20 -0800196static const char kSdpStringWithStream1And2UnifiedPlan[] =
197 "v=0\r\n"
198 "o=- 0 0 IN IP4 127.0.0.1\r\n"
199 "s=-\r\n"
200 "t=0 0\r\n"
201 "a=msid-semantic: WMS stream1 stream2\r\n"
202 "m=audio 1 RTP/AVPF 103\r\n"
203 "a=ice-ufrag:e5785931\r\n"
204 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
205 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
206 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
207 "a=mid:0\r\n"
208 "a=sendrecv\r\n"
209 "a=rtcp-mux\r\n"
210 "a=rtpmap:103 ISAC/16000\r\n"
211 "a=ssrc:1 cname:stream1\r\n"
212 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
213 "m=video 1 RTP/AVPF 120\r\n"
214 "a=ice-ufrag:e5785931\r\n"
215 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
216 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
217 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
218 "a=mid:1\r\n"
219 "a=sendrecv\r\n"
220 "a=rtcp-mux\r\n"
221 "a=rtpmap:120 VP8/0\r\n"
222 "a=ssrc:2 cname:stream1\r\n"
223 "a=ssrc:2 msid:stream1 videotrack0\r\n"
224 "m=audio 1 RTP/AVPF 103\r\n"
225 "a=ice-ufrag:e5785931\r\n"
226 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
227 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
228 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
229 "a=mid:2\r\n"
230 "a=sendrecv\r\n"
231 "a=rtcp-mux\r\n"
232 "a=rtpmap:103 ISAC/16000\r\n"
233 "a=ssrc:3 cname:stream2\r\n"
234 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
235 "m=video 1 RTP/AVPF 120\r\n"
236 "a=ice-ufrag:e5785931\r\n"
237 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
238 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
239 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
240 "a=mid:3\r\n"
241 "a=sendrecv\r\n"
242 "a=rtcp-mux\r\n"
243 "a=rtpmap:120 VP8/0\r\n"
244 "a=ssrc:4 cname:stream2\r\n"
245 "a=ssrc:4 msid:stream2 videotrack1\r\n";
deadbeefab9b2d12015-10-14 11:33:11 -0700246
247// Reference SDP without MediaStreams. Msid is not supported.
248static const char kSdpStringWithoutStreams[] =
249 "v=0\r\n"
250 "o=- 0 0 IN IP4 127.0.0.1\r\n"
251 "s=-\r\n"
252 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800253 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700254 "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"
deadbeefab9b2d12015-10-14 11:33:11 -0700258 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700259 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800260 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700261 "a=rtpmap:103 ISAC/16000\r\n"
262 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800263 "a=ice-ufrag:e5785931\r\n"
264 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
265 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
266 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700267 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700268 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800269 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700270 "a=rtpmap:120 VP8/90000\r\n";
271
272// Reference SDP without MediaStreams. Msid is supported.
273static const char kSdpStringWithMsidWithoutStreams[] =
274 "v=0\r\n"
275 "o=- 0 0 IN IP4 127.0.0.1\r\n"
276 "s=-\r\n"
277 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800278 "a=msid-semantic: WMS\r\n"
279 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700280 "a=ice-ufrag:e5785931\r\n"
281 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
282 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
283 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700284 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700285 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800286 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700287 "a=rtpmap:103 ISAC/16000\r\n"
288 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800289 "a=ice-ufrag:e5785931\r\n"
290 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
291 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
292 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700293 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700294 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800295 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700296 "a=rtpmap:120 VP8/90000\r\n";
297
298// Reference SDP without MediaStreams and audio only.
299static const char kSdpStringWithoutStreamsAudioOnly[] =
300 "v=0\r\n"
301 "o=- 0 0 IN IP4 127.0.0.1\r\n"
302 "s=-\r\n"
303 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800304 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700305 "a=ice-ufrag:e5785931\r\n"
306 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
307 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
308 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700309 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700310 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800311 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700312 "a=rtpmap:103 ISAC/16000\r\n";
313
314// Reference SENDONLY SDP without MediaStreams. Msid is not supported.
315static const char kSdpStringSendOnlyWithoutStreams[] =
316 "v=0\r\n"
317 "o=- 0 0 IN IP4 127.0.0.1\r\n"
318 "s=-\r\n"
319 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800320 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700321 "a=ice-ufrag:e5785931\r\n"
322 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
323 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
324 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700325 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700326 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700327 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800328 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700329 "a=rtpmap:103 ISAC/16000\r\n"
330 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800331 "a=ice-ufrag:e5785931\r\n"
332 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
333 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
334 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700335 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700336 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700337 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800338 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700339 "a=rtpmap:120 VP8/90000\r\n";
340
341static const char kSdpStringInit[] =
342 "v=0\r\n"
343 "o=- 0 0 IN IP4 127.0.0.1\r\n"
344 "s=-\r\n"
345 "t=0 0\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700346 "a=msid-semantic: WMS\r\n";
347
348static const char kSdpStringAudio[] =
349 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800350 "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"
deadbeefab9b2d12015-10-14 11:33:11 -0700354 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700355 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800356 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700357 "a=rtpmap:103 ISAC/16000\r\n";
358
359static const char kSdpStringVideo[] =
360 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800361 "a=ice-ufrag:e5785931\r\n"
362 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
363 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
364 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700365 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700366 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800367 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700368 "a=rtpmap:120 VP8/90000\r\n";
369
370static const char kSdpStringMs1Audio0[] =
371 "a=ssrc:1 cname:stream1\r\n"
372 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
373
374static const char kSdpStringMs1Video0[] =
375 "a=ssrc:2 cname:stream1\r\n"
376 "a=ssrc:2 msid:stream1 videotrack0\r\n";
377
378static const char kSdpStringMs1Audio1[] =
379 "a=ssrc:3 cname:stream1\r\n"
380 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
381
382static const char kSdpStringMs1Video1[] =
383 "a=ssrc:4 cname:stream1\r\n"
384 "a=ssrc:4 msid:stream1 videotrack1\r\n";
385
deadbeef8662f942017-01-20 21:20:51 -0800386static const char kDtlsSdesFallbackSdp[] =
387 "v=0\r\n"
388 "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n"
389 "s=-\r\n"
390 "c=IN IP4 0.0.0.0\r\n"
391 "t=0 0\r\n"
392 "a=group:BUNDLE audio\r\n"
393 "a=msid-semantic: WMS\r\n"
394 "m=audio 1 RTP/SAVPF 0\r\n"
395 "a=sendrecv\r\n"
396 "a=rtcp-mux\r\n"
397 "a=mid:audio\r\n"
398 "a=ssrc:1 cname:stream1\r\n"
399 "a=ssrc:1 mslabel:stream1\r\n"
400 "a=ssrc:1 label:audiotrack0\r\n"
401 "a=ice-ufrag:e5785931\r\n"
402 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
403 "a=rtpmap:0 pcmu/8000\r\n"
404 "a=fingerprint:sha-1 "
405 "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
406 "a=setup:actpass\r\n"
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700407 "a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
deadbeef8662f942017-01-20 21:20:51 -0800408 "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
409 "dummy_session_params\r\n";
410
perkjd61bf802016-03-24 03:16:19 -0700411using ::testing::Exactly;
Steve Anton36da6ff2018-02-16 16:04:20 -0800412using ::testing::Values;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700413using cricket::StreamParams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414using webrtc::AudioSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700415using webrtc::AudioTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000416using webrtc::AudioTrackInterface;
417using webrtc::DataBuffer;
418using webrtc::DataChannelInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000419using webrtc::IceCandidateInterface;
deadbeefc80741f2015-10-22 13:14:45 -0700420using webrtc::MediaConstraintsInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700421using webrtc::MediaStream;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000422using webrtc::MediaStreamInterface;
423using webrtc::MediaStreamTrackInterface;
424using webrtc::MockCreateSessionDescriptionObserver;
425using webrtc::MockDataChannelObserver;
Steve Anton94286cb2017-09-26 16:20:19 -0700426using webrtc::MockPeerConnectionObserver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000427using webrtc::MockSetSessionDescriptionObserver;
428using webrtc::MockStatsObserver;
perkjd61bf802016-03-24 03:16:19 -0700429using webrtc::NotifierInterface;
430using webrtc::ObserverInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431using webrtc::PeerConnectionInterface;
432using webrtc::PeerConnectionObserver;
deadbeef293e9262017-01-11 12:28:30 -0800433using webrtc::RTCError;
434using webrtc::RTCErrorType;
deadbeefab9b2d12015-10-14 11:33:11 -0700435using webrtc::RtpReceiverInterface;
436using webrtc::RtpSenderInterface;
Steve Anton57858b32018-02-15 15:19:50 -0800437using webrtc::RtpSenderProxyWithInternal;
438using webrtc::RtpSenderInternal;
Steve Anton4e70a722017-11-28 14:57:10 -0800439using webrtc::RtpTransceiverDirection;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440using webrtc::SdpParseError;
Steve Anton36da6ff2018-02-16 16:04:20 -0800441using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800442using webrtc::SdpType;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443using webrtc::SessionDescriptionInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700444using webrtc::StreamCollection;
445using webrtc::StreamCollectionInterface;
perkja3ede6c2016-03-08 01:27:48 +0100446using webrtc::VideoTrackSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700447using webrtc::VideoTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000448using webrtc::VideoTrackInterface;
449
Steve Anton36da6ff2018-02-16 16:04:20 -0800450using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
451using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
deadbeefab9b2d12015-10-14 11:33:11 -0700452
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453namespace {
454
455// Gets the first ssrc of given content type from the ContentInfo.
456bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
457 if (!content_info || !ssrc) {
458 return false;
459 }
460 const cricket::MediaContentDescription* media_desc =
Steve Antonb1c1de12017-12-21 15:14:30 -0800461 content_info->media_description();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 if (!media_desc || media_desc->streams().empty()) {
463 return false;
464 }
465 *ssrc = media_desc->streams().begin()->first_ssrc();
466 return true;
467}
468
deadbeefd1a38b52016-12-10 13:15:33 -0800469// Get the ufrags out of an SDP blob. Useful for testing ICE restart
470// behavior.
471std::vector<std::string> GetUfrags(
472 const webrtc::SessionDescriptionInterface* desc) {
473 std::vector<std::string> ufrags;
474 for (const cricket::TransportInfo& info :
475 desc->description()->transport_infos()) {
476 ufrags.push_back(info.description.ice_ufrag);
477 }
478 return ufrags;
479}
480
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000481void SetSsrcToZero(std::string* sdp) {
482 const char kSdpSsrcAtribute[] = "a=ssrc:";
483 const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
484 size_t ssrc_pos = 0;
485 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
Yves Gerey665174f2018-06-19 15:03:05 +0200486 std::string::npos) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000487 size_t end_ssrc = sdp->find(" ", ssrc_pos);
488 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
489 ssrc_pos = end_ssrc;
490 }
491}
492
deadbeefab9b2d12015-10-14 11:33:11 -0700493// Check if |streams| contains the specified track.
494bool ContainsTrack(const std::vector<cricket::StreamParams>& streams,
Seth Hampson845e8782018-03-02 11:34:10 -0800495 const std::string& stream_id,
deadbeefab9b2d12015-10-14 11:33:11 -0700496 const std::string& track_id) {
497 for (const cricket::StreamParams& params : streams) {
Seth Hampson845e8782018-03-02 11:34:10 -0800498 if (params.first_stream_id() == stream_id && params.id == track_id) {
deadbeefab9b2d12015-10-14 11:33:11 -0700499 return true;
500 }
501 }
502 return false;
503}
504
505// Check if |senders| contains the specified sender, by id.
506bool ContainsSender(
507 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
508 const std::string& id) {
509 for (const auto& sender : senders) {
510 if (sender->id() == id) {
511 return true;
512 }
513 }
514 return false;
515}
516
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700517// Check if |senders| contains the specified sender, by id and stream id.
518bool ContainsSender(
519 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
520 const std::string& id,
521 const std::string& stream_id) {
522 for (const auto& sender : senders) {
deadbeefa601f5c2016-06-06 14:27:39 -0700523 if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700524 return true;
525 }
526 }
527 return false;
528}
529
deadbeefab9b2d12015-10-14 11:33:11 -0700530// Create a collection of streams.
531// CreateStreamCollection(1) creates a collection that
532// correspond to kSdpStringWithStream1.
533// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
534rtc::scoped_refptr<StreamCollection> CreateStreamCollection(
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700535 int number_of_streams,
536 int tracks_per_stream) {
deadbeefab9b2d12015-10-14 11:33:11 -0700537 rtc::scoped_refptr<StreamCollection> local_collection(
538 StreamCollection::Create());
539
540 for (int i = 0; i < number_of_streams; ++i) {
541 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
542 webrtc::MediaStream::Create(kStreams[i]));
543
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700544 for (int j = 0; j < tracks_per_stream; ++j) {
545 // Add a local audio track.
546 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
547 webrtc::AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j],
548 nullptr));
549 stream->AddTrack(audio_track);
deadbeefab9b2d12015-10-14 11:33:11 -0700550
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700551 // Add a local video track.
552 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
553 webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
perkj773be362017-07-31 23:22:01 -0700554 webrtc::FakeVideoTrackSource::Create(),
555 rtc::Thread::Current()));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700556 stream->AddTrack(video_track);
557 }
deadbeefab9b2d12015-10-14 11:33:11 -0700558
559 local_collection->AddStream(stream);
560 }
561 return local_collection;
562}
563
564// Check equality of StreamCollections.
565bool CompareStreamCollections(StreamCollectionInterface* s1,
566 StreamCollectionInterface* s2) {
567 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
568 return false;
569 }
570
571 for (size_t i = 0; i != s1->count(); ++i) {
Seth Hampson13b8bad2018-03-13 16:05:28 -0700572 if (s1->at(i)->id() != s2->at(i)->id()) {
deadbeefab9b2d12015-10-14 11:33:11 -0700573 return false;
574 }
575 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
576 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
577 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
578 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
579
580 if (audio_tracks1.size() != audio_tracks2.size()) {
581 return false;
582 }
583 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
584 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
585 return false;
586 }
587 }
588 if (video_tracks1.size() != video_tracks2.size()) {
589 return false;
590 }
591 for (size_t j = 0; j != video_tracks1.size(); ++j) {
592 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
593 return false;
594 }
595 }
596 }
597 return true;
598}
599
perkjd61bf802016-03-24 03:16:19 -0700600// Helper class to test Observer.
601class MockTrackObserver : public ObserverInterface {
602 public:
603 explicit MockTrackObserver(NotifierInterface* notifier)
604 : notifier_(notifier) {
605 notifier_->RegisterObserver(this);
606 }
607
608 ~MockTrackObserver() { Unregister(); }
609
610 void Unregister() {
611 if (notifier_) {
612 notifier_->UnregisterObserver(this);
613 notifier_ = nullptr;
614 }
615 }
616
617 MOCK_METHOD0(OnChanged, void());
618
619 private:
620 NotifierInterface* notifier_;
621};
622
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623} // namespace
deadbeefab9b2d12015-10-14 11:33:11 -0700624
nisse528b7932017-05-08 03:21:43 -0700625// The PeerConnectionMediaConfig tests below verify that configuration and
626// constraints are propagated into the PeerConnection's MediaConfig. These
627// settings are intended for MediaChannel constructors, but that is not
628// exercised by these unittest.
zhihuang29ff8442016-07-27 11:07:25 -0700629class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
630 public:
zhihuang38ede132017-06-15 12:52:32 -0700631 static rtc::scoped_refptr<PeerConnectionFactoryForTest>
632 CreatePeerConnectionFactoryForTest() {
633 auto audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
634 auto audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
Anders Carlssonb3306882018-05-14 10:11:42 +0200635 auto video_encoder_factory = webrtc::CreateBuiltinVideoEncoderFactory();
636 auto video_decoder_factory = webrtc::CreateBuiltinVideoDecoderFactory();
zhihuang38ede132017-06-15 12:52:32 -0700637
henrika919dc2e2017-10-12 14:24:55 +0200638 // Use fake audio device module since we're only testing the interface
639 // level, and using a real one could make tests flaky when run in parallel.
zhihuang38ede132017-06-15 12:52:32 -0700640 auto media_engine = std::unique_ptr<cricket::MediaEngineInterface>(
641 cricket::WebRtcMediaEngineFactory::Create(
henrika919dc2e2017-10-12 14:24:55 +0200642 FakeAudioCaptureModule::Create(), audio_encoder_factory,
Anders Carlssonb3306882018-05-14 10:11:42 +0200643 audio_decoder_factory, std::move(video_encoder_factory),
644 std::move(video_decoder_factory), nullptr,
Ivo Creusen62337e52018-01-09 14:17:33 +0100645 webrtc::AudioProcessingBuilder().Create()));
zhihuang38ede132017-06-15 12:52:32 -0700646
647 std::unique_ptr<webrtc::CallFactoryInterface> call_factory =
648 webrtc::CreateCallFactory();
649
650 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory =
651 webrtc::CreateRtcEventLogFactory();
652
653 return new rtc::RefCountedObject<PeerConnectionFactoryForTest>(
654 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200655 std::move(media_engine), std::move(call_factory),
zhihuang38ede132017-06-15 12:52:32 -0700656 std::move(event_log_factory));
657 }
658
659 PeerConnectionFactoryForTest(
660 rtc::Thread* network_thread,
661 rtc::Thread* worker_thread,
662 rtc::Thread* signaling_thread,
zhihuang38ede132017-06-15 12:52:32 -0700663 std::unique_ptr<cricket::MediaEngineInterface> media_engine,
664 std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
665 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory)
666 : webrtc::PeerConnectionFactory(network_thread,
667 worker_thread,
668 signaling_thread,
zhihuang38ede132017-06-15 12:52:32 -0700669 std::move(media_engine),
670 std::move(call_factory),
671 std::move(event_log_factory)) {}
kwiberg1e4e8cb2017-01-31 01:48:08 -0800672
deadbeefd7850b22017-08-23 10:59:19 -0700673 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
zhihuang29ff8442016-07-27 11:07:25 -0700674};
675
Steve Anton36da6ff2018-02-16 16:04:20 -0800676// TODO(steveanton): Convert to use the new PeerConnectionWrapper.
677class PeerConnectionInterfaceBaseTest : public testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 protected:
Steve Anton36da6ff2018-02-16 16:04:20 -0800679 explicit PeerConnectionInterfaceBaseTest(SdpSemantics sdp_semantics)
680 : vss_(new rtc::VirtualSocketServer()),
681 main_(vss_.get()),
682 sdp_semantics_(sdp_semantics) {
phoglund37ebcf02016-01-08 05:04:57 -0800683#ifdef WEBRTC_ANDROID
684 webrtc::InitializeAndroidObjects();
685#endif
686 }
687
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688 virtual void SetUp() {
deadbeefd7850b22017-08-23 10:59:19 -0700689 // Use fake audio capture module since we're only testing the interface
690 // level, and using a real one could make tests flaky when run in parallel.
691 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 pc_factory_ = webrtc::CreatePeerConnectionFactory(
danilchape9021a32016-05-17 01:52:02 -0700693 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Anders Carlsson67537952018-05-03 11:28:29 +0200694 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
695 fake_audio_capture_module_),
696 webrtc::CreateBuiltinAudioEncoderFactory(),
697 webrtc::CreateBuiltinAudioDecoderFactory(),
698 webrtc::CreateBuiltinVideoEncoderFactory(),
699 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
700 nullptr /* audio_processing */);
danilchape9021a32016-05-17 01:52:02 -0700701 ASSERT_TRUE(pc_factory_);
zhihuang29ff8442016-07-27 11:07:25 -0700702 pc_factory_for_test_ =
zhihuang38ede132017-06-15 12:52:32 -0700703 PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
zhihuang29ff8442016-07-27 11:07:25 -0700704 pc_factory_for_test_->Initialize();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 }
706
707 void CreatePeerConnection() {
Niels Möllerf06f9232018-08-07 12:32:18 +0200708 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 }
710
deadbeef293e9262017-01-11 12:28:30 -0800711 // DTLS does not work in a loopback call, so is disabled for most of the
712 // tests in this file.
713 void CreatePeerConnectionWithoutDtls() {
Niels Möllerf06f9232018-08-07 12:32:18 +0200714 RTCConfiguration config;
715 config.enable_dtls_srtp = false;
deadbeef293e9262017-01-11 12:28:30 -0800716
Niels Möllerf06f9232018-08-07 12:32:18 +0200717 CreatePeerConnection(config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 }
719
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700720 void CreatePeerConnectionWithIceTransportsType(
721 PeerConnectionInterface::IceTransportsType type) {
722 PeerConnectionInterface::RTCConfiguration config;
723 config.type = type;
Niels Möllerf06f9232018-08-07 12:32:18 +0200724 return CreatePeerConnection(config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700725 }
726
727 void CreatePeerConnectionWithIceServer(const std::string& uri,
728 const std::string& password) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800729 PeerConnectionInterface::RTCConfiguration config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 PeerConnectionInterface::IceServer server;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700731 server.uri = uri;
732 server.password = password;
733 config.servers.push_back(server);
Niels Möllerf06f9232018-08-07 12:32:18 +0200734 CreatePeerConnection(config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700735 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736
Niels Möllerf06f9232018-08-07 12:32:18 +0200737 void CreatePeerConnection(const RTCConfiguration& config) {
kwibergd1fe2812016-04-27 06:47:29 -0700738 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800739 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
740 port_allocator_ = port_allocator.get();
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000741
deadbeef1dcb1642017-03-29 21:08:16 -0700742 // Create certificate generator unless DTLS constraint is explicitly set to
743 // false.
Henrik Boströmd79599d2016-06-01 13:58:50 +0200744 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
Niels Möllerf06f9232018-08-07 12:32:18 +0200745
746 if (config.enable_dtls_srtp.value_or(true)) {
deadbeef8662f942017-01-20 21:20:51 -0800747 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
748 cert_generator.reset(fake_certificate_generator_);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000749 }
Steve Anton36da6ff2018-02-16 16:04:20 -0800750 RTCConfiguration modified_config = config;
751 modified_config.sdp_semantics = sdp_semantics_;
Henrik Boströmd79599d2016-06-01 13:58:50 +0200752 pc_ = pc_factory_->CreatePeerConnection(
Niels Möllerf06f9232018-08-07 12:32:18 +0200753 modified_config, std::move(port_allocator), std::move(cert_generator),
754 &observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 ASSERT_TRUE(pc_.get() != NULL);
756 observer_.SetPeerConnectionInterface(pc_.get());
757 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
758 }
759
deadbeef0a6c4ca2015-10-06 11:38:28 -0700760 void CreatePeerConnectionExpectFail(const std::string& uri) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800761 PeerConnectionInterface::RTCConfiguration config;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700762 PeerConnectionInterface::IceServer server;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700763 server.uri = uri;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800764 config.servers.push_back(server);
Steve Anton36da6ff2018-02-16 16:04:20 -0800765 config.sdp_semantics = sdp_semantics_;
766 rtc::scoped_refptr<PeerConnectionInterface> pc =
Niels Möllerf06f9232018-08-07 12:32:18 +0200767 pc_factory_->CreatePeerConnection(config, nullptr, nullptr, &observer_);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800768 EXPECT_EQ(nullptr, pc);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700769 }
770
Steve Anton038834f2017-07-14 15:59:59 -0700771 void CreatePeerConnectionExpectFail(
772 PeerConnectionInterface::RTCConfiguration config) {
773 PeerConnectionInterface::IceServer server;
774 server.uri = kTurnIceServerUri;
775 server.password = kTurnPassword;
776 config.servers.push_back(server);
Steve Anton36da6ff2018-02-16 16:04:20 -0800777 config.sdp_semantics = sdp_semantics_;
Steve Anton038834f2017-07-14 15:59:59 -0700778 rtc::scoped_refptr<PeerConnectionInterface> pc =
779 pc_factory_->CreatePeerConnection(config, nullptr, nullptr, &observer_);
780 EXPECT_EQ(nullptr, pc);
781 }
782
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 void CreatePeerConnectionWithDifferentConfigurations() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700784 CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800785 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
786 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
787 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 EXPECT_EQ(kDefaultStunPort,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800789 port_allocator_->stun_servers().begin()->port());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790
deadbeef0a6c4ca2015-10-06 11:38:28 -0700791 CreatePeerConnectionExpectFail(kStunInvalidPort);
792 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
793 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700795 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800796 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
797 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798 EXPECT_EQ(kTurnUsername,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800799 port_allocator_->turn_servers()[0].credentials.username);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 EXPECT_EQ(kTurnPassword,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800801 port_allocator_->turn_servers()[0].credentials.password);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802 EXPECT_EQ(kTurnHostname,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800803 port_allocator_->turn_servers()[0].ports[0].address.hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804 }
805
806 void ReleasePeerConnection() {
807 pc_ = NULL;
808 observer_.SetPeerConnectionInterface(NULL);
809 }
810
Steve Anton36da6ff2018-02-16 16:04:20 -0800811 rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
812 const std::string& label) {
813 auto video_source = pc_factory_->CreateVideoSource(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200814 absl::make_unique<cricket::FakeVideoCapturer>(), nullptr);
Steve Anton36da6ff2018-02-16 16:04:20 -0800815 return pc_factory_->CreateVideoTrack(label, video_source);
816 }
817
818 void AddVideoTrack(const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800819 const std::vector<std::string>& stream_ids = {}) {
Steve Anton36da6ff2018-02-16 16:04:20 -0800820 auto sender_or_error =
Seth Hampson845e8782018-03-02 11:34:10 -0800821 pc_->AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton36da6ff2018-02-16 16:04:20 -0800822 ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
824 observer_.renegotiation_needed_ = false;
825 }
826
Steve Anton36da6ff2018-02-16 16:04:20 -0800827 void AddVideoStream(const std::string& label) {
zhihuang9763d562016-08-05 11:14:50 -0700828 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 pc_factory_->CreateLocalMediaStream(label));
Steve Anton36da6ff2018-02-16 16:04:20 -0800830 stream->AddTrack(CreateVideoTrack(label + "v0"));
831 ASSERT_TRUE(pc_->AddStream(stream));
832 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
833 observer_.renegotiation_needed_ = false;
834 }
835
836 rtc::scoped_refptr<AudioTrackInterface> CreateAudioTrack(
837 const std::string& label) {
838 return pc_factory_->CreateAudioTrack(label, nullptr);
839 }
840
841 void AddAudioTrack(const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800842 const std::vector<std::string>& stream_ids = {}) {
Steve Anton36da6ff2018-02-16 16:04:20 -0800843 auto sender_or_error =
Seth Hampson845e8782018-03-02 11:34:10 -0800844 pc_->AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton36da6ff2018-02-16 16:04:20 -0800845 ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
846 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
847 observer_.renegotiation_needed_ = false;
848 }
849
850 void AddAudioStream(const std::string& label) {
851 rtc::scoped_refptr<MediaStreamInterface> stream(
852 pc_factory_->CreateLocalMediaStream(label));
853 stream->AddTrack(CreateAudioTrack(label + "a0"));
854 ASSERT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
856 observer_.renegotiation_needed_ = false;
857 }
858
Seth Hampson845e8782018-03-02 11:34:10 -0800859 void AddAudioVideoStream(const std::string& stream_id,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860 const std::string& audio_track_label,
861 const std::string& video_track_label) {
862 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700863 rtc::scoped_refptr<MediaStreamInterface> stream(
Seth Hampson845e8782018-03-02 11:34:10 -0800864 pc_factory_->CreateLocalMediaStream(stream_id));
Steve Anton36da6ff2018-02-16 16:04:20 -0800865 stream->AddTrack(CreateAudioTrack(audio_track_label));
866 stream->AddTrack(CreateVideoTrack(video_track_label));
867 ASSERT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
869 observer_.renegotiation_needed_ = false;
870 }
871
Steve Anton36da6ff2018-02-16 16:04:20 -0800872 rtc::scoped_refptr<RtpReceiverInterface> GetFirstReceiverOfType(
873 cricket::MediaType media_type) {
874 for (auto receiver : pc_->GetReceivers()) {
875 if (receiver->media_type() == media_type) {
876 return receiver;
877 }
878 }
879 return nullptr;
880 }
881
kwibergd1fe2812016-04-27 06:47:29 -0700882 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
Niels Möllerf06f9232018-08-07 12:32:18 +0200883 const RTCOfferAnswerOptions* options,
884 bool offer) {
Yves Gerey665174f2018-06-19 15:03:05 +0200885 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
886 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887 if (offer) {
Niels Möllerf06f9232018-08-07 12:32:18 +0200888 pc_->CreateOffer(observer, options ? *options : RTCOfferAnswerOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889 } else {
Niels Möllerf06f9232018-08-07 12:32:18 +0200890 pc_->CreateAnswer(observer, options ? *options : RTCOfferAnswerOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891 }
892 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700893 *desc = observer->MoveDescription();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894 return observer->result();
895 }
896
kwibergd1fe2812016-04-27 06:47:29 -0700897 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
Niels Möllerf06f9232018-08-07 12:32:18 +0200898 const RTCOfferAnswerOptions* options) {
899 return DoCreateOfferAnswer(desc, options, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900 }
901
kwibergd1fe2812016-04-27 06:47:29 -0700902 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
Niels Möllerf06f9232018-08-07 12:32:18 +0200903 const RTCOfferAnswerOptions* options) {
904 return DoCreateOfferAnswer(desc, options, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 }
906
Steve Antondb45ca82017-09-11 18:27:34 -0700907 bool DoSetSessionDescription(
908 std::unique_ptr<SessionDescriptionInterface> desc,
909 bool local) {
Yves Gerey665174f2018-06-19 15:03:05 +0200910 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
911 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912 if (local) {
Steve Antondb45ca82017-09-11 18:27:34 -0700913 pc_->SetLocalDescription(observer, desc.release());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914 } else {
Steve Antondb45ca82017-09-11 18:27:34 -0700915 pc_->SetRemoteDescription(observer, desc.release());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916 }
zhihuang29ff8442016-07-27 11:07:25 -0700917 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
918 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
919 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920 return observer->result();
921 }
922
Steve Antondb45ca82017-09-11 18:27:34 -0700923 bool DoSetLocalDescription(
924 std::unique_ptr<SessionDescriptionInterface> desc) {
925 return DoSetSessionDescription(std::move(desc), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926 }
927
Steve Antondb45ca82017-09-11 18:27:34 -0700928 bool DoSetRemoteDescription(
929 std::unique_ptr<SessionDescriptionInterface> desc) {
930 return DoSetSessionDescription(std::move(desc), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931 }
932
933 // Calls PeerConnection::GetStats and check the return value.
934 // It does not verify the values in the StatReports since a RTCP packet might
935 // be required.
936 bool DoGetStats(MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000937 rtc::scoped_refptr<MockStatsObserver> observer(
938 new rtc::RefCountedObject<MockStatsObserver>());
Yves Gerey665174f2018-06-19 15:03:05 +0200939 if (!pc_->GetStats(observer, track,
940 PeerConnectionInterface::kStatsOutputLevelStandard))
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000941 return false;
942 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
943 return observer->called();
944 }
945
Harald Alvestrand89061872018-01-02 14:08:34 +0100946 // Call the standards-compliant GetStats function.
947 bool DoGetRTCStats() {
948 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
949 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
950 pc_->GetStats(callback);
951 EXPECT_TRUE_WAIT(callback->called(), kTimeout);
952 return callback->called();
953 }
954
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955 void InitiateCall() {
deadbeef293e9262017-01-11 12:28:30 -0800956 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 // Create a local stream with audio&video tracks.
Steve Anton36da6ff2018-02-16 16:04:20 -0800958 if (sdp_semantics_ == SdpSemantics::kPlanB) {
Seth Hampson845e8782018-03-02 11:34:10 -0800959 AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
Steve Anton36da6ff2018-02-16 16:04:20 -0800960 } else {
961 // Unified Plan does not support AddStream, so just add an audio and video
962 // track.
Seth Hampson845e8782018-03-02 11:34:10 -0800963 AddAudioTrack(kAudioTracks[0], {kStreamId1});
964 AddVideoTrack(kVideoTracks[0], {kStreamId1});
Steve Anton36da6ff2018-02-16 16:04:20 -0800965 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966 CreateOfferReceiveAnswer();
967 }
968
969 // Verify that RTP Header extensions has been negotiated for audio and video.
970 void VerifyRemoteRtpHeaderExtensions() {
971 const cricket::MediaContentDescription* desc =
972 cricket::GetFirstAudioContentDescription(
973 pc_->remote_description()->description());
974 ASSERT_TRUE(desc != NULL);
975 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
976
977 desc = cricket::GetFirstVideoContentDescription(
978 pc_->remote_description()->description());
979 ASSERT_TRUE(desc != NULL);
980 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
981 }
982
983 void CreateOfferAsRemoteDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700984 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -0700985 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986 std::string sdp;
987 EXPECT_TRUE(offer->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -0700988 std::unique_ptr<SessionDescriptionInterface> remote_offer(
Steve Antona3a92c22017-12-07 10:27:41 -0800989 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -0700990 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
992 }
993
deadbeefab9b2d12015-10-14 11:33:11 -0700994 void CreateAndSetRemoteOffer(const std::string& sdp) {
Steve Antondb45ca82017-09-11 18:27:34 -0700995 std::unique_ptr<SessionDescriptionInterface> remote_offer(
Steve Antona3a92c22017-12-07 10:27:41 -0800996 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -0700997 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
deadbeefab9b2d12015-10-14 11:33:11 -0700998 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
999 }
1000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001 void CreateAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001002 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001003 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1006 // audio codec change, even if the parameter has nothing to do with
1007 // receiving. Not all parameters are serialized to SDP.
1008 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1009 // the SessionDescription, it is necessary to do that here to in order to
1010 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1011 // https://code.google.com/p/webrtc/issues/detail?id=1356
1012 std::string sdp;
1013 EXPECT_TRUE(answer->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001014 std::unique_ptr<SessionDescriptionInterface> new_answer(
Steve Antona3a92c22017-12-07 10:27:41 -08001015 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001016 EXPECT_TRUE(DoSetLocalDescription(std::move(new_answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001017 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1018 }
1019
1020 void CreatePrAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001021 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001022 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023
1024 std::string sdp;
1025 EXPECT_TRUE(answer->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001026 std::unique_ptr<SessionDescriptionInterface> pr_answer(
Steve Antona3a92c22017-12-07 10:27:41 -08001027 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001028 EXPECT_TRUE(DoSetLocalDescription(std::move(pr_answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
1030 }
1031
1032 void CreateOfferReceiveAnswer() {
1033 CreateOfferAsLocalDescription();
1034 std::string sdp;
1035 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1036 CreateAnswerAsRemoteDescription(sdp);
1037 }
1038
1039 void CreateOfferAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001040 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001041 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001042 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1043 // audio codec change, even if the parameter has nothing to do with
1044 // receiving. Not all parameters are serialized to SDP.
1045 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1046 // the SessionDescription, it is necessary to do that here to in order to
1047 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1048 // https://code.google.com/p/webrtc/issues/detail?id=1356
1049 std::string sdp;
1050 EXPECT_TRUE(offer->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001051 std::unique_ptr<SessionDescriptionInterface> new_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08001052 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053
Steve Antondb45ca82017-09-11 18:27:34 -07001054 EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001055 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
mallinath@webrtc.org68cbd012014-01-22 00:16:46 +00001056 // Wait for the ice_complete message, so that SDP will have candidates.
Steve Anton6f25b092017-10-23 09:39:20 -07001057 EXPECT_TRUE_WAIT(observer_.ice_gathering_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001058 }
1059
deadbeefab9b2d12015-10-14 11:33:11 -07001060 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
Steve Antondb45ca82017-09-11 18:27:34 -07001061 std::unique_ptr<SessionDescriptionInterface> answer(
Steve Antona3a92c22017-12-07 10:27:41 -08001062 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001063 ASSERT_TRUE(answer);
1064 EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1066 }
1067
deadbeefab9b2d12015-10-14 11:33:11 -07001068 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
Steve Antondb45ca82017-09-11 18:27:34 -07001069 std::unique_ptr<SessionDescriptionInterface> pr_answer(
Steve Antona3a92c22017-12-07 10:27:41 -08001070 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001071 ASSERT_TRUE(pr_answer);
1072 EXPECT_TRUE(DoSetRemoteDescription(std::move(pr_answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
Steve Antondb45ca82017-09-11 18:27:34 -07001074 std::unique_ptr<SessionDescriptionInterface> answer(
Steve Antona3a92c22017-12-07 10:27:41 -08001075 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001076 ASSERT_TRUE(answer);
1077 EXPECT_TRUE(DoSetRemoteDescription(std::move(answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001078 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1079 }
1080
Seth Hampson845e8782018-03-02 11:34:10 -08001081 // Waits until a remote stream with the given id is signaled. This helper
Steve Anton36da6ff2018-02-16 16:04:20 -08001082 // function will verify both OnAddTrack and OnAddStream (Plan B only) are
Seth Hampson845e8782018-03-02 11:34:10 -08001083 // called with the given stream id and expected number of tracks.
1084 void WaitAndVerifyOnAddStream(const std::string& stream_id,
Steve Anton36da6ff2018-02-16 16:04:20 -08001085 int expected_num_tracks) {
1086 // Verify that both OnAddStream and OnAddTrack are called.
Seth Hampson845e8782018-03-02 11:34:10 -08001087 EXPECT_EQ_WAIT(stream_id, observer_.GetLastAddedStreamId(), kTimeout);
Steve Anton36da6ff2018-02-16 16:04:20 -08001088 EXPECT_EQ_WAIT(expected_num_tracks,
Seth Hampson845e8782018-03-02 11:34:10 -08001089 observer_.CountAddTrackEventsForStream(stream_id), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001090 }
1091
1092 // Creates an offer and applies it as a local session description.
1093 // Creates an answer with the same SDP an the offer but removes all lines
1094 // that start with a:ssrc"
1095 void CreateOfferReceiveAnswerWithoutSsrc() {
1096 CreateOfferAsLocalDescription();
1097 std::string sdp;
1098 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1099 SetSsrcToZero(&sdp);
1100 CreateAnswerAsRemoteDescription(sdp);
1101 }
1102
deadbeefab9b2d12015-10-14 11:33:11 -07001103 // This function creates a MediaStream with label kStreams[0] and
1104 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
1105 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
kwiberg2bbff992016-03-16 11:03:04 -07001106 // is returned and the MediaStream is stored in
deadbeefab9b2d12015-10-14 11:33:11 -07001107 // |reference_collection_|
kwibergd1fe2812016-04-27 06:47:29 -07001108 std::unique_ptr<SessionDescriptionInterface>
kwiberg2bbff992016-03-16 11:03:04 -07001109 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1110 size_t number_of_video_tracks) {
1111 EXPECT_LE(number_of_audio_tracks, 2u);
1112 EXPECT_LE(number_of_video_tracks, 2u);
deadbeefab9b2d12015-10-14 11:33:11 -07001113
1114 reference_collection_ = StreamCollection::Create();
1115 std::string sdp_ms1 = std::string(kSdpStringInit);
1116
Seth Hampson845e8782018-03-02 11:34:10 -08001117 std::string mediastream_id = kStreams[0];
deadbeefab9b2d12015-10-14 11:33:11 -07001118
1119 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001120 webrtc::MediaStream::Create(mediastream_id));
deadbeefab9b2d12015-10-14 11:33:11 -07001121 reference_collection_->AddStream(stream);
1122
1123 if (number_of_audio_tracks > 0) {
1124 sdp_ms1 += std::string(kSdpStringAudio);
1125 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1126 AddAudioTrack(kAudioTracks[0], stream);
1127 }
1128 if (number_of_audio_tracks > 1) {
1129 sdp_ms1 += kSdpStringMs1Audio1;
1130 AddAudioTrack(kAudioTracks[1], stream);
1131 }
1132
1133 if (number_of_video_tracks > 0) {
1134 sdp_ms1 += std::string(kSdpStringVideo);
1135 sdp_ms1 += std::string(kSdpStringMs1Video0);
1136 AddVideoTrack(kVideoTracks[0], stream);
1137 }
1138 if (number_of_video_tracks > 1) {
1139 sdp_ms1 += kSdpStringMs1Video1;
1140 AddVideoTrack(kVideoTracks[1], stream);
1141 }
1142
kwibergd1fe2812016-04-27 06:47:29 -07001143 return std::unique_ptr<SessionDescriptionInterface>(
Steve Antona3a92c22017-12-07 10:27:41 -08001144 webrtc::CreateSessionDescription(SdpType::kOffer, sdp_ms1));
deadbeefab9b2d12015-10-14 11:33:11 -07001145 }
1146
1147 void AddAudioTrack(const std::string& track_id,
1148 MediaStreamInterface* stream) {
1149 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1150 webrtc::AudioTrack::Create(track_id, nullptr));
1151 ASSERT_TRUE(stream->AddTrack(audio_track));
1152 }
1153
1154 void AddVideoTrack(const std::string& track_id,
1155 MediaStreamInterface* stream) {
1156 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -07001157 webrtc::VideoTrack::Create(track_id,
perkj773be362017-07-31 23:22:01 -07001158 webrtc::FakeVideoTrackSource::Create(),
1159 rtc::Thread::Current()));
deadbeefab9b2d12015-10-14 11:33:11 -07001160 ASSERT_TRUE(stream->AddTrack(video_track));
1161 }
1162
Steve Anton36da6ff2018-02-16 16:04:20 -08001163 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioTrack() {
deadbeef293e9262017-01-11 12:28:30 -08001164 CreatePeerConnectionWithoutDtls();
Steve Anton36da6ff2018-02-16 16:04:20 -08001165 AddAudioTrack(kAudioTracks[0]);
kwibergfd8be342016-05-14 19:44:11 -07001166 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001167 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1168 return offer;
1169 }
1170
Steve Anton36da6ff2018-02-16 16:04:20 -08001171 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
1172 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001173 AddAudioStream(kStreamId1);
Steve Anton36da6ff2018-02-16 16:04:20 -08001174 std::unique_ptr<SessionDescriptionInterface> offer;
1175 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1176 return offer;
1177 }
1178
1179 std::unique_ptr<SessionDescriptionInterface> CreateAnswerWithOneAudioTrack() {
1180 EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioTrack()));
1181 std::unique_ptr<SessionDescriptionInterface> answer;
1182 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1183 return answer;
1184 }
1185
kwibergfd8be342016-05-14 19:44:11 -07001186 std::unique_ptr<SessionDescriptionInterface>
zhihuang8f65cdf2016-05-06 18:40:30 -07001187 CreateAnswerWithOneAudioStream() {
Steve Antondb45ca82017-09-11 18:27:34 -07001188 EXPECT_TRUE(DoSetRemoteDescription(CreateOfferWithOneAudioStream()));
kwibergfd8be342016-05-14 19:44:11 -07001189 std::unique_ptr<SessionDescriptionInterface> answer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001190 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1191 return answer;
1192 }
1193
1194 const std::string& GetFirstAudioStreamCname(
1195 const SessionDescriptionInterface* desc) {
zhihuang8f65cdf2016-05-06 18:40:30 -07001196 const cricket::AudioContentDescription* audio_desc =
Steve Antonb1c1de12017-12-21 15:14:30 -08001197 cricket::GetFirstAudioContentDescription(desc->description());
zhihuang8f65cdf2016-05-06 18:40:30 -07001198 return audio_desc->streams()[0].cname;
1199 }
1200
zhihuang1c378ed2017-08-17 14:10:50 -07001201 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOptions(
1202 const RTCOfferAnswerOptions& offer_answer_options) {
1203 RTC_DCHECK(pc_);
1204 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
1205 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
1206 pc_->CreateOffer(observer, offer_answer_options);
1207 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
1208 return observer->MoveDescription();
1209 }
1210
1211 void CreateOfferWithOptionsAsRemoteDescription(
1212 std::unique_ptr<SessionDescriptionInterface>* desc,
1213 const RTCOfferAnswerOptions& offer_answer_options) {
1214 *desc = CreateOfferWithOptions(offer_answer_options);
1215 ASSERT_TRUE(desc != nullptr);
1216 std::string sdp;
1217 EXPECT_TRUE((*desc)->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001218 std::unique_ptr<SessionDescriptionInterface> remote_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08001219 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001220 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
zhihuang1c378ed2017-08-17 14:10:50 -07001221 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
1222 }
1223
1224 void CreateOfferWithOptionsAsLocalDescription(
1225 std::unique_ptr<SessionDescriptionInterface>* desc,
1226 const RTCOfferAnswerOptions& offer_answer_options) {
1227 *desc = CreateOfferWithOptions(offer_answer_options);
1228 ASSERT_TRUE(desc != nullptr);
1229 std::string sdp;
1230 EXPECT_TRUE((*desc)->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07001231 std::unique_ptr<SessionDescriptionInterface> new_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08001232 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
zhihuang1c378ed2017-08-17 14:10:50 -07001233
Steve Antondb45ca82017-09-11 18:27:34 -07001234 EXPECT_TRUE(DoSetLocalDescription(std::move(new_offer)));
zhihuang1c378ed2017-08-17 14:10:50 -07001235 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
1236 }
1237
1238 bool HasCNCodecs(const cricket::ContentInfo* content) {
Steve Antonb1c1de12017-12-21 15:14:30 -08001239 RTC_DCHECK(content);
1240 RTC_DCHECK(content->media_description());
1241 for (const cricket::AudioCodec& codec :
1242 content->media_description()->as_audio()->codecs()) {
1243 if (codec.name == "CN") {
zhihuang1c378ed2017-08-17 14:10:50 -07001244 return true;
Steve Antonb1c1de12017-12-21 15:14:30 -08001245 }
zhihuang1c378ed2017-08-17 14:10:50 -07001246 }
1247 return false;
1248 }
1249
Steve Anton36da6ff2018-02-16 16:04:20 -08001250 const char* GetSdpStringWithStream1() const {
1251 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1252 return kSdpStringWithStream1PlanB;
1253 } else {
1254 return kSdpStringWithStream1UnifiedPlan;
1255 }
1256 }
1257
1258 const char* GetSdpStringWithStream1And2() const {
1259 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1260 return kSdpStringWithStream1And2PlanB;
1261 } else {
1262 return kSdpStringWithStream1And2UnifiedPlan;
1263 }
1264 }
1265
deadbeef9a6f4d42017-05-15 19:43:33 -07001266 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1267 rtc::AutoSocketServerThread main_;
deadbeefd7850b22017-08-23 10:59:19 -07001268 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08001269 cricket::FakePortAllocator* port_allocator_ = nullptr;
deadbeef8662f942017-01-20 21:20:51 -08001270 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
zhihuang9763d562016-08-05 11:14:50 -07001271 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1272 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_;
1273 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001274 MockPeerConnectionObserver observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001275 rtc::scoped_refptr<StreamCollection> reference_collection_;
Steve Anton36da6ff2018-02-16 16:04:20 -08001276 const SdpSemantics sdp_semantics_;
1277};
1278
1279class PeerConnectionInterfaceTest
1280 : public PeerConnectionInterfaceBaseTest,
1281 public ::testing::WithParamInterface<SdpSemantics> {
1282 protected:
1283 PeerConnectionInterfaceTest() : PeerConnectionInterfaceBaseTest(GetParam()) {}
1284};
1285
1286class PeerConnectionInterfaceTestPlanB
1287 : public PeerConnectionInterfaceBaseTest {
1288 protected:
1289 PeerConnectionInterfaceTestPlanB()
1290 : PeerConnectionInterfaceBaseTest(SdpSemantics::kPlanB) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291};
1292
zhihuang8f65cdf2016-05-06 18:40:30 -07001293// Generate different CNAMEs when PeerConnections are created.
1294// The CNAMEs are expected to be generated randomly. It is possible
1295// that the test fails, though the possibility is very low.
Steve Anton36da6ff2018-02-16 16:04:20 -08001296TEST_P(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
kwibergfd8be342016-05-14 19:44:11 -07001297 std::unique_ptr<SessionDescriptionInterface> offer1 =
Steve Anton36da6ff2018-02-16 16:04:20 -08001298 CreateOfferWithOneAudioTrack();
kwibergfd8be342016-05-14 19:44:11 -07001299 std::unique_ptr<SessionDescriptionInterface> offer2 =
Steve Anton36da6ff2018-02-16 16:04:20 -08001300 CreateOfferWithOneAudioTrack();
zhihuang8f65cdf2016-05-06 18:40:30 -07001301 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1302 GetFirstAudioStreamCname(offer2.get()));
1303}
1304
Steve Anton36da6ff2018-02-16 16:04:20 -08001305TEST_P(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
kwibergfd8be342016-05-14 19:44:11 -07001306 std::unique_ptr<SessionDescriptionInterface> answer1 =
Steve Anton36da6ff2018-02-16 16:04:20 -08001307 CreateAnswerWithOneAudioTrack();
kwibergfd8be342016-05-14 19:44:11 -07001308 std::unique_ptr<SessionDescriptionInterface> answer2 =
Steve Anton36da6ff2018-02-16 16:04:20 -08001309 CreateAnswerWithOneAudioTrack();
zhihuang8f65cdf2016-05-06 18:40:30 -07001310 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1311 GetFirstAudioStreamCname(answer2.get()));
1312}
1313
Steve Anton36da6ff2018-02-16 16:04:20 -08001314TEST_P(PeerConnectionInterfaceTest,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001315 CreatePeerConnectionWithDifferentConfigurations) {
1316 CreatePeerConnectionWithDifferentConfigurations();
1317}
1318
Steve Anton36da6ff2018-02-16 16:04:20 -08001319TEST_P(PeerConnectionInterfaceTest,
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001320 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1321 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1322 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1323 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1324 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1325 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1326 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1327 port_allocator_->candidate_filter());
1328 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1329 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1330}
1331
1332// Test that when a PeerConnection is created with a nonzero candidate pool
1333// size, the pooled PortAllocatorSession is created with all the attributes
1334// in the RTCConfiguration.
Steve Anton36da6ff2018-02-16 16:04:20 -08001335TEST_P(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001336 PeerConnectionInterface::RTCConfiguration config;
1337 PeerConnectionInterface::IceServer server;
1338 server.uri = kStunAddressOnly;
1339 config.servers.push_back(server);
1340 config.type = PeerConnectionInterface::kRelay;
1341 config.disable_ipv6 = true;
1342 config.tcp_candidate_policy =
1343 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
honghaiz60347052016-05-31 18:29:12 -07001344 config.candidate_network_policy =
1345 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001346 config.ice_candidate_pool_size = 1;
Niels Möllerf06f9232018-08-07 12:32:18 +02001347 CreatePeerConnection(config);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001348
1349 const cricket::FakePortAllocatorSession* session =
1350 static_cast<const cricket::FakePortAllocatorSession*>(
1351 port_allocator_->GetPooledSession());
1352 ASSERT_NE(nullptr, session);
1353 EXPECT_EQ(1UL, session->stun_servers().size());
1354 EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
1355 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
honghaiz60347052016-05-31 18:29:12 -07001356 EXPECT_LT(0U,
1357 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001358}
1359
deadbeefd21eab32017-07-26 16:50:11 -07001360// Test that network-related RTCConfiguration members are applied to the
1361// PortAllocator when CreatePeerConnection is called. Specifically:
1362// - disable_ipv6_on_wifi
1363// - max_ipv6_networks
1364// - tcp_candidate_policy
1365// - candidate_network_policy
1366// - prune_turn_ports
1367//
1368// Note that the candidate filter (RTCConfiguration::type) is already tested
1369// above.
Steve Anton36da6ff2018-02-16 16:04:20 -08001370TEST_P(PeerConnectionInterfaceTest,
deadbeefd21eab32017-07-26 16:50:11 -07001371 CreatePeerConnectionAppliesNetworkConfigToPortAllocator) {
1372 // Create fake port allocator.
1373 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1374 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
1375 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1376
1377 // Create RTCConfiguration with some network-related fields relevant to
1378 // PortAllocator populated.
1379 PeerConnectionInterface::RTCConfiguration config;
1380 config.disable_ipv6_on_wifi = true;
1381 config.max_ipv6_networks = 10;
1382 config.tcp_candidate_policy =
1383 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
1384 config.candidate_network_policy =
1385 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
1386 config.prune_turn_ports = true;
1387
1388 // Create the PC factory and PC with the above config.
1389 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1390 webrtc::CreatePeerConnectionFactory(
1391 rtc::Thread::Current(), rtc::Thread::Current(),
Karl Wiberg1b0eae32017-10-17 14:48:54 +02001392 rtc::Thread::Current(), fake_audio_capture_module_,
1393 webrtc::CreateBuiltinAudioEncoderFactory(),
Anders Carlsson67537952018-05-03 11:28:29 +02001394 webrtc::CreateBuiltinAudioDecoderFactory(),
1395 webrtc::CreateBuiltinVideoEncoderFactory(),
1396 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
1397 nullptr /* audio_processing */));
deadbeefd21eab32017-07-26 16:50:11 -07001398 rtc::scoped_refptr<PeerConnectionInterface> pc(
Niels Möllerf06f9232018-08-07 12:32:18 +02001399 pc_factory->CreatePeerConnection(config, std::move(port_allocator),
1400 nullptr, &observer_));
deadbeefd21eab32017-07-26 16:50:11 -07001401
1402 // Now validate that the config fields set above were applied to the
1403 // PortAllocator, as flags or otherwise.
1404 EXPECT_FALSE(raw_port_allocator->flags() &
1405 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1406 EXPECT_EQ(10, raw_port_allocator->max_ipv6_networks());
1407 EXPECT_TRUE(raw_port_allocator->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
1408 EXPECT_TRUE(raw_port_allocator->flags() &
1409 cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
1410 EXPECT_TRUE(raw_port_allocator->prune_turn_ports());
1411}
1412
deadbeef46c73892016-11-16 19:42:04 -08001413// Check that GetConfiguration returns the configuration the PeerConnection was
1414// constructed with, before SetConfiguration is called.
Steve Anton36da6ff2018-02-16 16:04:20 -08001415TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
deadbeef46c73892016-11-16 19:42:04 -08001416 PeerConnectionInterface::RTCConfiguration config;
1417 config.type = PeerConnectionInterface::kRelay;
Niels Möllerf06f9232018-08-07 12:32:18 +02001418 CreatePeerConnection(config);
deadbeef46c73892016-11-16 19:42:04 -08001419
1420 PeerConnectionInterface::RTCConfiguration returned_config =
1421 pc_->GetConfiguration();
1422 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1423}
1424
1425// Check that GetConfiguration returns the last configuration passed into
1426// SetConfiguration.
Steve Anton36da6ff2018-02-16 16:04:20 -08001427TEST_P(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
deadbeef46c73892016-11-16 19:42:04 -08001428 CreatePeerConnection();
1429
Steve Anton36da6ff2018-02-16 16:04:20 -08001430 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
deadbeef46c73892016-11-16 19:42:04 -08001431 config.type = PeerConnectionInterface::kRelay;
1432 EXPECT_TRUE(pc_->SetConfiguration(config));
1433
1434 PeerConnectionInterface::RTCConfiguration returned_config =
1435 pc_->GetConfiguration();
1436 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1437}
1438
Steve Antonc79268f2018-04-24 09:54:10 -07001439TEST_P(PeerConnectionInterfaceTest, SetConfigurationFailsAfterClose) {
1440 CreatePeerConnection();
1441
1442 pc_->Close();
1443
1444 EXPECT_FALSE(
1445 pc_->SetConfiguration(PeerConnectionInterface::RTCConfiguration()));
1446}
1447
Steve Anton36da6ff2018-02-16 16:04:20 -08001448TEST_F(PeerConnectionInterfaceTestPlanB, AddStreams) {
deadbeef293e9262017-01-11 12:28:30 -08001449 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001450 AddVideoStream(kStreamId1);
1451 AddAudioStream(kStreamId2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452 ASSERT_EQ(2u, pc_->local_streams()->count());
1453
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001454 // Test we can add multiple local streams to one peerconnection.
zhihuang9763d562016-08-05 11:14:50 -07001455 rtc::scoped_refptr<MediaStreamInterface> stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001456 pc_factory_->CreateLocalMediaStream(kStreamId3));
zhihuang9763d562016-08-05 11:14:50 -07001457 rtc::scoped_refptr<AudioTrackInterface> audio_track(
Seth Hampson845e8782018-03-02 11:34:10 -08001458 pc_factory_->CreateAudioTrack(kStreamId3,
zhihuang9763d562016-08-05 11:14:50 -07001459 static_cast<AudioSourceInterface*>(NULL)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00001461 EXPECT_TRUE(pc_->AddStream(stream));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001462 EXPECT_EQ(3u, pc_->local_streams()->count());
1463
1464 // Remove the third stream.
1465 pc_->RemoveStream(pc_->local_streams()->at(2));
1466 EXPECT_EQ(2u, pc_->local_streams()->count());
1467
1468 // Remove the second stream.
1469 pc_->RemoveStream(pc_->local_streams()->at(1));
1470 EXPECT_EQ(1u, pc_->local_streams()->count());
1471
1472 // Remove the first stream.
1473 pc_->RemoveStream(pc_->local_streams()->at(0));
1474 EXPECT_EQ(0u, pc_->local_streams()->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475}
1476
deadbeefab9b2d12015-10-14 11:33:11 -07001477// Test that the created offer includes streams we added.
Steve Anton36da6ff2018-02-16 16:04:20 -08001478// Don't run under Unified Plan since the stream API is not available.
1479TEST_F(PeerConnectionInterfaceTestPlanB, AddedStreamsPresentInOffer) {
deadbeef293e9262017-01-11 12:28:30 -08001480 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001481 AddAudioVideoStream(kStreamId1, "audio_track", "video_track");
kwibergd1fe2812016-04-27 06:47:29 -07001482 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001483 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001484
deadbeefab9b2d12015-10-14 11:33:11 -07001485 const cricket::AudioContentDescription* audio_desc =
Steve Antonb1c1de12017-12-21 15:14:30 -08001486 cricket::GetFirstAudioContentDescription(offer->description());
Seth Hampson845e8782018-03-02 11:34:10 -08001487 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));
deadbeefab9b2d12015-10-14 11:33:11 -07001488
deadbeefab9b2d12015-10-14 11:33:11 -07001489 const cricket::VideoContentDescription* video_desc =
Steve Antonb1c1de12017-12-21 15:14:30 -08001490 cricket::GetFirstVideoContentDescription(offer->description());
Seth Hampson845e8782018-03-02 11:34:10 -08001491 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));
deadbeefab9b2d12015-10-14 11:33:11 -07001492
1493 // Add another stream and ensure the offer includes both the old and new
1494 // streams.
Seth Hampson845e8782018-03-02 11:34:10 -08001495 AddAudioVideoStream(kStreamId2, "audio_track2", "video_track2");
kwiberg2bbff992016-03-16 11:03:04 -07001496 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001497
Steve Antonb1c1de12017-12-21 15:14:30 -08001498 audio_desc = cricket::GetFirstAudioContentDescription(offer->description());
Seth Hampson845e8782018-03-02 11:34:10 -08001499 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId1, "audio_track"));
1500 EXPECT_TRUE(ContainsTrack(audio_desc->streams(), kStreamId2, "audio_track2"));
deadbeefab9b2d12015-10-14 11:33:11 -07001501
Steve Antonb1c1de12017-12-21 15:14:30 -08001502 video_desc = cricket::GetFirstVideoContentDescription(offer->description());
Seth Hampson845e8782018-03-02 11:34:10 -08001503 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId1, "video_track"));
1504 EXPECT_TRUE(ContainsTrack(video_desc->streams(), kStreamId2, "video_track2"));
deadbeefab9b2d12015-10-14 11:33:11 -07001505}
1506
Steve Anton36da6ff2018-02-16 16:04:20 -08001507// Don't run under Unified Plan since the stream API is not available.
1508TEST_F(PeerConnectionInterfaceTestPlanB, RemoveStream) {
deadbeef293e9262017-01-11 12:28:30 -08001509 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001510 AddVideoStream(kStreamId1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511 ASSERT_EQ(1u, pc_->local_streams()->count());
1512 pc_->RemoveStream(pc_->local_streams()->at(0));
1513 EXPECT_EQ(0u, pc_->local_streams()->count());
1514}
1515
deadbeefe1f9d832016-01-14 15:35:42 -08001516// Test for AddTrack and RemoveTrack methods.
1517// Tests that the created offer includes tracks we added,
1518// and that the RtpSenders are created correctly.
1519// Also tests that RemoveTrack removes the tracks from subsequent offers.
Steve Anton36da6ff2018-02-16 16:04:20 -08001520// Only tested with Plan B since Unified Plan is covered in more detail by tests
1521// in peerconnection_jsep_unittests.cc
1522TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackRemoveTrack) {
deadbeef293e9262017-01-11 12:28:30 -08001523 CreatePeerConnectionWithoutDtls();
zhihuang9763d562016-08-05 11:14:50 -07001524 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001525 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001526 rtc::scoped_refptr<VideoTrackInterface> video_track(
1527 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001528 "video_track", pc_factory_->CreateVideoSource(
1529 std::unique_ptr<cricket::VideoCapturer>(
1530 new cricket::FakeVideoCapturer()))));
Seth Hampson845e8782018-03-02 11:34:10 -08001531 auto audio_sender = pc_->AddTrack(audio_track, {kStreamId1}).MoveValue();
1532 auto video_sender = pc_->AddTrack(video_track, {kStreamId1}).MoveValue();
deadbeefa601f5c2016-06-06 14:27:39 -07001533 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
Seth Hampson845e8782018-03-02 11:34:10 -08001534 EXPECT_EQ(kStreamId1, audio_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001535 EXPECT_EQ("audio_track", audio_sender->id());
1536 EXPECT_EQ(audio_track, audio_sender->track());
deadbeefa601f5c2016-06-06 14:27:39 -07001537 EXPECT_EQ(1UL, video_sender->stream_ids().size());
Seth Hampson845e8782018-03-02 11:34:10 -08001538 EXPECT_EQ(kStreamId1, video_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001539 EXPECT_EQ("video_track", video_sender->id());
1540 EXPECT_EQ(video_track, video_sender->track());
1541
1542 // Now create an offer and check for the senders.
kwibergd1fe2812016-04-27 06:47:29 -07001543 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001544 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001545
1546 const cricket::ContentInfo* audio_content =
1547 cricket::GetFirstAudioContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08001548 EXPECT_TRUE(ContainsTrack(audio_content->media_description()->streams(),
Seth Hampson845e8782018-03-02 11:34:10 -08001549 kStreamId1, "audio_track"));
deadbeefe1f9d832016-01-14 15:35:42 -08001550
1551 const cricket::ContentInfo* video_content =
1552 cricket::GetFirstVideoContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08001553 EXPECT_TRUE(ContainsTrack(video_content->media_description()->streams(),
Seth Hampson845e8782018-03-02 11:34:10 -08001554 kStreamId1, "video_track"));
deadbeefe1f9d832016-01-14 15:35:42 -08001555
Steve Antondb45ca82017-09-11 18:27:34 -07001556 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefe1f9d832016-01-14 15:35:42 -08001557
1558 // Now try removing the tracks.
1559 EXPECT_TRUE(pc_->RemoveTrack(audio_sender));
1560 EXPECT_TRUE(pc_->RemoveTrack(video_sender));
1561
1562 // Create a new offer and ensure it doesn't contain the removed senders.
kwiberg2bbff992016-03-16 11:03:04 -07001563 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001564
1565 audio_content = cricket::GetFirstAudioContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08001566 EXPECT_FALSE(ContainsTrack(audio_content->media_description()->streams(),
Seth Hampson845e8782018-03-02 11:34:10 -08001567 kStreamId1, "audio_track"));
deadbeefe1f9d832016-01-14 15:35:42 -08001568
1569 video_content = cricket::GetFirstVideoContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08001570 EXPECT_FALSE(ContainsTrack(video_content->media_description()->streams(),
Seth Hampson845e8782018-03-02 11:34:10 -08001571 kStreamId1, "video_track"));
deadbeefe1f9d832016-01-14 15:35:42 -08001572
Steve Antondb45ca82017-09-11 18:27:34 -07001573 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefe1f9d832016-01-14 15:35:42 -08001574
1575 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1576 // should return false.
1577 EXPECT_FALSE(pc_->RemoveTrack(audio_sender));
1578 EXPECT_FALSE(pc_->RemoveTrack(video_sender));
1579}
1580
1581// Test creating senders without a stream specified,
1582// expecting a random stream ID to be generated.
Steve Anton36da6ff2018-02-16 16:04:20 -08001583TEST_P(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
deadbeef293e9262017-01-11 12:28:30 -08001584 CreatePeerConnectionWithoutDtls();
zhihuang9763d562016-08-05 11:14:50 -07001585 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001586 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001587 rtc::scoped_refptr<VideoTrackInterface> video_track(
1588 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001589 "video_track", pc_factory_->CreateVideoSource(
1590 std::unique_ptr<cricket::VideoCapturer>(
1591 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001592 auto audio_sender =
Steve Anton2d6c76a2018-01-05 17:10:52 -08001593 pc_->AddTrack(audio_track, std::vector<std::string>()).MoveValue();
deadbeefe1f9d832016-01-14 15:35:42 -08001594 auto video_sender =
Steve Anton2d6c76a2018-01-05 17:10:52 -08001595 pc_->AddTrack(video_track, std::vector<std::string>()).MoveValue();
deadbeefe1f9d832016-01-14 15:35:42 -08001596 EXPECT_EQ("audio_track", audio_sender->id());
1597 EXPECT_EQ(audio_track, audio_sender->track());
1598 EXPECT_EQ("video_track", video_sender->id());
1599 EXPECT_EQ(video_track, video_sender->track());
Seth Hampson5b4f0752018-04-02 16:31:36 -07001600 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1601 // If the ID is truly a random GUID, it should be infinitely unlikely they
1602 // will be the same.
1603 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
1604 } else {
1605 // We allows creating tracks without stream ids under Unified Plan
1606 // semantics.
1607 EXPECT_EQ(0u, video_sender->stream_ids().size());
1608 EXPECT_EQ(0u, audio_sender->stream_ids().size());
1609 }
deadbeefe1f9d832016-01-14 15:35:42 -08001610}
1611
Harald Alvestrand89061872018-01-02 14:08:34 +01001612// Test that we can call GetStats() after AddTrack but before connecting
1613// the PeerConnection to a peer.
Steve Anton36da6ff2018-02-16 16:04:20 -08001614TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) {
Harald Alvestrand89061872018-01-02 14:08:34 +01001615 CreatePeerConnectionWithoutDtls();
1616 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1617 pc_factory_->CreateAudioTrack("audio_track", nullptr));
1618 rtc::scoped_refptr<VideoTrackInterface> video_track(
1619 pc_factory_->CreateVideoTrack(
1620 "video_track", pc_factory_->CreateVideoSource(
1621 std::unique_ptr<cricket::VideoCapturer>(
1622 new cricket::FakeVideoCapturer()))));
Steve Anton2d6c76a2018-01-05 17:10:52 -08001623 auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
1624 auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
Harald Alvestrand89061872018-01-02 14:08:34 +01001625 EXPECT_TRUE(DoGetStats(nullptr));
1626}
1627
Steve Anton36da6ff2018-02-16 16:04:20 -08001628TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) {
Harald Alvestrandc72af932018-01-11 17:18:19 +01001629 CreatePeerConnectionWithoutDtls();
1630 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1631 pc_factory_->CreateAudioTrack("audio_track", nullptr));
1632 rtc::scoped_refptr<VideoTrackInterface> video_track(
1633 pc_factory_->CreateVideoTrack(
1634 "video_track", pc_factory_->CreateVideoSource(
1635 std::unique_ptr<cricket::VideoCapturer>(
1636 new cricket::FakeVideoCapturer()))));
1637 auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
Steve Anton57858b32018-02-15 15:19:50 -08001638 ASSERT_TRUE(audio_sender.ok());
1639 auto* audio_sender_proxy =
1640 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1641 audio_sender.value().get());
1642 EXPECT_NE(0, audio_sender_proxy->internal()->AttachmentId());
1643
Harald Alvestrandc72af932018-01-11 17:18:19 +01001644 auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
Steve Anton57858b32018-02-15 15:19:50 -08001645 ASSERT_TRUE(video_sender.ok());
1646 auto* video_sender_proxy =
1647 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1648 video_sender.value().get());
1649 EXPECT_NE(0, video_sender_proxy->internal()->AttachmentId());
Harald Alvestrandc72af932018-01-11 17:18:19 +01001650}
1651
Steve Anton36da6ff2018-02-16 16:04:20 -08001652// Don't run under Unified Plan since the stream API is not available.
1653TEST_F(PeerConnectionInterfaceTestPlanB, AttachmentIdIsSetOnAddStream) {
Harald Alvestrandc72af932018-01-11 17:18:19 +01001654 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001655 AddVideoStream(kStreamId1);
Harald Alvestrandc72af932018-01-11 17:18:19 +01001656 auto senders = pc_->GetSenders();
Steve Anton57858b32018-02-15 15:19:50 -08001657 ASSERT_EQ(1u, senders.size());
1658 auto* sender_proxy =
1659 static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
1660 senders[0].get());
1661 EXPECT_NE(0, sender_proxy->internal()->AttachmentId());
Harald Alvestrandc72af932018-01-11 17:18:19 +01001662}
1663
Steve Anton36da6ff2018-02-16 16:04:20 -08001664TEST_P(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665 InitiateCall();
Seth Hampson845e8782018-03-02 11:34:10 -08001666 WaitAndVerifyOnAddStream(kStreamId1, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001667 VerifyRemoteRtpHeaderExtensions();
1668}
1669
Steve Anton36da6ff2018-02-16 16:04:20 -08001670TEST_P(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001671 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001672 AddVideoTrack(kVideoTracks[0], {kStreamId1});
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001673 CreateOfferAsLocalDescription();
1674 std::string offer;
1675 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1676 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
Seth Hampson845e8782018-03-02 11:34:10 -08001677 WaitAndVerifyOnAddStream(kStreamId1, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678}
1679
Steve Anton36da6ff2018-02-16 16:04:20 -08001680TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001681 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001682 AddVideoTrack(kVideoTracks[0], {kStreamId1});
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683
1684 CreateOfferAsRemoteDescription();
1685 CreateAnswerAsLocalDescription();
1686
Seth Hampson845e8782018-03-02 11:34:10 -08001687 WaitAndVerifyOnAddStream(kStreamId1, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001688}
1689
Steve Anton36da6ff2018-02-16 16:04:20 -08001690TEST_P(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001691 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001692 AddVideoTrack(kVideoTracks[0], {kStreamId1});
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693
1694 CreateOfferAsRemoteDescription();
1695 CreatePrAnswerAsLocalDescription();
1696 CreateAnswerAsLocalDescription();
1697
Seth Hampson845e8782018-03-02 11:34:10 -08001698 WaitAndVerifyOnAddStream(kStreamId1, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001699}
1700
Steve Anton36da6ff2018-02-16 16:04:20 -08001701// Don't run under Unified Plan since the stream API is not available.
1702TEST_F(PeerConnectionInterfaceTestPlanB, Renegotiate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001703 InitiateCall();
1704 ASSERT_EQ(1u, pc_->remote_streams()->count());
1705 pc_->RemoveStream(pc_->local_streams()->at(0));
1706 CreateOfferReceiveAnswer();
1707 EXPECT_EQ(0u, pc_->remote_streams()->count());
Seth Hampson845e8782018-03-02 11:34:10 -08001708 AddVideoStream(kStreamId1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709 CreateOfferReceiveAnswer();
1710}
1711
1712// Tests that after negotiating an audio only call, the respondent can perform a
1713// renegotiation that removes the audio stream.
Steve Anton36da6ff2018-02-16 16:04:20 -08001714TEST_F(PeerConnectionInterfaceTestPlanB, RenegotiateAudioOnly) {
deadbeef293e9262017-01-11 12:28:30 -08001715 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001716 AddAudioStream(kStreamId1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717 CreateOfferAsRemoteDescription();
1718 CreateAnswerAsLocalDescription();
1719
1720 ASSERT_EQ(1u, pc_->remote_streams()->count());
1721 pc_->RemoveStream(pc_->local_streams()->at(0));
1722 CreateOfferReceiveAnswer();
1723 EXPECT_EQ(0u, pc_->remote_streams()->count());
1724}
1725
1726// Test that candidates are generated and that we can parse our own candidates.
Steve Anton36da6ff2018-02-16 16:04:20 -08001727TEST_P(PeerConnectionInterfaceTest, IceCandidates) {
deadbeef293e9262017-01-11 12:28:30 -08001728 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729
Steve Antonf1c6db12017-10-13 11:13:35 -07001730 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731 // SetRemoteDescription takes ownership of offer.
kwibergd1fe2812016-04-27 06:47:29 -07001732 std::unique_ptr<SessionDescriptionInterface> offer;
Steve Anton36da6ff2018-02-16 16:04:20 -08001733 AddVideoTrack(kVideoTracks[0]);
deadbeefc80741f2015-10-22 13:14:45 -07001734 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07001735 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736
1737 // SetLocalDescription takes ownership of answer.
kwibergd1fe2812016-04-27 06:47:29 -07001738 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001739 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07001740 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001741
Steve Antonf1c6db12017-10-13 11:13:35 -07001742 EXPECT_TRUE_WAIT(observer_.last_candidate() != nullptr, kTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07001743 EXPECT_TRUE_WAIT(observer_.ice_gathering_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744
Steve Antonf1c6db12017-10-13 11:13:35 -07001745 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001746}
1747
deadbeefab9b2d12015-10-14 11:33:11 -07001748// Test that CreateOffer and CreateAnswer will fail if the track labels are
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001749// not unique.
Steve Anton07563732018-06-26 11:13:50 -07001750TEST_F(PeerConnectionInterfaceTestPlanB, CreateOfferAnswerWithInvalidStream) {
deadbeef293e9262017-01-11 12:28:30 -08001751 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752 // Create a regular offer for the CreateAnswer test later.
kwibergd1fe2812016-04-27 06:47:29 -07001753 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07001754 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001755 EXPECT_TRUE(offer);
1756 offer.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757
1758 // Create a local stream with audio&video tracks having same label.
Seth Hampson845e8782018-03-02 11:34:10 -08001759 AddAudioTrack("track_label", {kStreamId1});
1760 AddVideoTrack("track_label", {kStreamId1});
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001761
1762 // Test CreateOffer
deadbeefc80741f2015-10-22 13:14:45 -07001763 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764
1765 // Test CreateAnswer
kwibergd1fe2812016-04-27 06:47:29 -07001766 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001767 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768}
1769
1770// Test that we will get different SSRCs for each tracks in the offer and answer
1771// we created.
Steve Anton36da6ff2018-02-16 16:04:20 -08001772TEST_P(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001773 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774 // Create a local stream with audio&video tracks having different labels.
Seth Hampson845e8782018-03-02 11:34:10 -08001775 AddAudioTrack(kAudioTracks[0], {kStreamId1});
1776 AddVideoTrack(kVideoTracks[0], {kStreamId1});
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001777
1778 // Test CreateOffer
kwibergd1fe2812016-04-27 06:47:29 -07001779 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001780 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001781 int audio_ssrc = 0;
1782 int video_ssrc = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02001783 EXPECT_TRUE(
1784 GetFirstSsrc(GetFirstAudioContent(offer->description()), &audio_ssrc));
1785 EXPECT_TRUE(
1786 GetFirstSsrc(GetFirstVideoContent(offer->description()), &video_ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001787 EXPECT_NE(audio_ssrc, video_ssrc);
1788
1789 // Test CreateAnswer
Steve Antondb45ca82017-09-11 18:27:34 -07001790 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
kwibergd1fe2812016-04-27 06:47:29 -07001791 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001792 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793 audio_ssrc = 0;
1794 video_ssrc = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02001795 EXPECT_TRUE(
1796 GetFirstSsrc(GetFirstAudioContent(answer->description()), &audio_ssrc));
1797 EXPECT_TRUE(
1798 GetFirstSsrc(GetFirstVideoContent(answer->description()), &video_ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001799 EXPECT_NE(audio_ssrc, video_ssrc);
1800}
1801
deadbeefeb459812015-12-15 19:24:43 -08001802// Test that it's possible to call AddTrack on a MediaStream after adding
1803// the stream to a PeerConnection.
1804// TODO(deadbeef): Remove this test once this behavior is no longer supported.
Steve Anton36da6ff2018-02-16 16:04:20 -08001805// Don't run under Unified Plan since the stream API is not available.
1806TEST_F(PeerConnectionInterfaceTestPlanB, AddTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001807 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001808 // Create audio stream and add to PeerConnection.
Seth Hampson845e8782018-03-02 11:34:10 -08001809 AddAudioStream(kStreamId1);
deadbeefeb459812015-12-15 19:24:43 -08001810 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1811
1812 // Add video track to the audio-only stream.
zhihuang9763d562016-08-05 11:14:50 -07001813 rtc::scoped_refptr<VideoTrackInterface> video_track(
1814 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001815 "video_label", pc_factory_->CreateVideoSource(
1816 std::unique_ptr<cricket::VideoCapturer>(
1817 new cricket::FakeVideoCapturer()))));
deadbeefeb459812015-12-15 19:24:43 -08001818 stream->AddTrack(video_track.get());
1819
kwibergd1fe2812016-04-27 06:47:29 -07001820 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001821 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001822
1823 const cricket::MediaContentDescription* video_desc =
1824 cricket::GetFirstVideoContentDescription(offer->description());
1825 EXPECT_TRUE(video_desc != nullptr);
1826}
1827
1828// Test that it's possible to call RemoveTrack on a MediaStream after adding
1829// the stream to a PeerConnection.
1830// TODO(deadbeef): Remove this test once this behavior is no longer supported.
Steve Anton36da6ff2018-02-16 16:04:20 -08001831// Don't run under Unified Plan since the stream API is not available.
1832TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001833 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001834 // Create audio/video stream and add to PeerConnection.
Seth Hampson845e8782018-03-02 11:34:10 -08001835 AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
deadbeefeb459812015-12-15 19:24:43 -08001836 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1837
1838 // Remove the video track.
1839 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1840
kwibergd1fe2812016-04-27 06:47:29 -07001841 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001842 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001843
1844 const cricket::MediaContentDescription* video_desc =
1845 cricket::GetFirstVideoContentDescription(offer->description());
1846 EXPECT_TRUE(video_desc == nullptr);
1847}
1848
deadbeefbd7d8f72015-12-18 16:58:44 -08001849// Test creating a sender with a stream ID, and ensure the ID is populated
1850// in the offer.
Steve Anton36da6ff2018-02-16 16:04:20 -08001851// Don't run under Unified Plan since the stream API is not available.
1852TEST_F(PeerConnectionInterfaceTestPlanB, CreateSenderWithStream) {
deadbeef293e9262017-01-11 12:28:30 -08001853 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08001854 pc_->CreateSender("video", kStreamId1);
deadbeefbd7d8f72015-12-18 16:58:44 -08001855
kwibergd1fe2812016-04-27 06:47:29 -07001856 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001857 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefbd7d8f72015-12-18 16:58:44 -08001858
1859 const cricket::MediaContentDescription* video_desc =
1860 cricket::GetFirstVideoContentDescription(offer->description());
1861 ASSERT_TRUE(video_desc != nullptr);
1862 ASSERT_EQ(1u, video_desc->streams().size());
Seth Hampson845e8782018-03-02 11:34:10 -08001863 EXPECT_EQ(kStreamId1, video_desc->streams()[0].first_stream_id());
deadbeefbd7d8f72015-12-18 16:58:44 -08001864}
1865
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001866// Test that we can specify a certain track that we want statistics about.
Steve Anton36da6ff2018-02-16 16:04:20 -08001867TEST_P(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001868 InitiateCall();
Steve Anton36da6ff2018-02-16 16:04:20 -08001869 ASSERT_LT(0u, pc_->GetSenders().size());
1870 ASSERT_LT(0u, pc_->GetReceivers().size());
zhihuang9763d562016-08-05 11:14:50 -07001871 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
Steve Anton36da6ff2018-02-16 16:04:20 -08001872 pc_->GetReceivers()[0]->track();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001873 EXPECT_TRUE(DoGetStats(remote_audio));
1874
1875 // Remove the stream. Since we are sending to our selves the local
1876 // and the remote stream is the same.
Steve Anton36da6ff2018-02-16 16:04:20 -08001877 pc_->RemoveTrack(pc_->GetSenders()[0]);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878 // Do a re-negotiation.
1879 CreateOfferReceiveAnswer();
1880
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001881 // Test that we still can get statistics for the old track. Even if it is not
1882 // sent any longer.
1883 EXPECT_TRUE(DoGetStats(remote_audio));
1884}
1885
1886// Test that we can get stats on a video track.
Steve Anton36da6ff2018-02-16 16:04:20 -08001887TEST_P(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001888 InitiateCall();
Steve Anton36da6ff2018-02-16 16:04:20 -08001889 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
1890 ASSERT_TRUE(video_receiver);
1891 EXPECT_TRUE(DoGetStats(video_receiver->track()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001892}
1893
1894// Test that we don't get statistics for an invalid track.
Steve Anton36da6ff2018-02-16 16:04:20 -08001895TEST_P(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896 InitiateCall();
zhihuang9763d562016-08-05 11:14:50 -07001897 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001898 pc_factory_->CreateAudioTrack("unknown track", NULL));
1899 EXPECT_FALSE(DoGetStats(unknown_audio_track));
1900}
1901
Steve Anton36da6ff2018-02-16 16:04:20 -08001902TEST_P(PeerConnectionInterfaceTest, GetRTCStatsBeforeAndAfterCalling) {
Harald Alvestrand89061872018-01-02 14:08:34 +01001903 CreatePeerConnectionWithoutDtls();
1904 EXPECT_TRUE(DoGetRTCStats());
1905 // Clearing stats cache is needed now, but should be temporary.
1906 // https://bugs.chromium.org/p/webrtc/issues/detail?id=8693
1907 pc_->ClearStatsCache();
Seth Hampson845e8782018-03-02 11:34:10 -08001908 AddAudioTrack(kAudioTracks[0], {kStreamId1});
1909 AddVideoTrack(kVideoTracks[0], {kStreamId1});
Harald Alvestrand89061872018-01-02 14:08:34 +01001910 EXPECT_TRUE(DoGetRTCStats());
1911 pc_->ClearStatsCache();
1912 CreateOfferReceiveAnswer();
1913 EXPECT_TRUE(DoGetRTCStats());
1914}
1915
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001916// This test setup two RTP data channels in loop back.
Steve Anton36da6ff2018-02-16 16:04:20 -08001917TEST_P(PeerConnectionInterfaceTest, TestDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02001918 RTCConfiguration config;
1919 config.enable_rtp_data_channel = true;
1920 config.enable_dtls_srtp = false;
1921 CreatePeerConnection(config);
zhihuang9763d562016-08-05 11:14:50 -07001922 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001923 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001924 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925 pc_->CreateDataChannel("test2", NULL);
1926 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001927 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001929 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001930 new MockDataChannelObserver(data2));
1931
1932 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1933 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1934 std::string data_to_send1 = "testing testing";
1935 std::string data_to_send2 = "testing something else";
1936 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1)));
1937
1938 CreateOfferReceiveAnswer();
1939 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1940 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1941
1942 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1943 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1944 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1)));
1945 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1946
1947 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout);
1948 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1949
1950 data1->Close();
1951 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1952 CreateOfferReceiveAnswer();
1953 EXPECT_FALSE(observer1->IsOpen());
1954 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1955 EXPECT_TRUE(observer2->IsOpen());
1956
1957 data_to_send2 = "testing something else again";
1958 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1959
1960 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1961}
1962
1963// This test verifies that sendnig binary data over RTP data channels should
1964// fail.
Steve Anton36da6ff2018-02-16 16:04:20 -08001965TEST_P(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02001966 RTCConfiguration config;
1967 config.enable_rtp_data_channel = true;
1968 config.enable_dtls_srtp = false;
1969 CreatePeerConnection(config);
zhihuang9763d562016-08-05 11:14:50 -07001970 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001971 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001972 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001973 pc_->CreateDataChannel("test2", NULL);
1974 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001975 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001976 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001977 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001978 new MockDataChannelObserver(data2));
1979
1980 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1981 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1982
1983 CreateOfferReceiveAnswer();
1984 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1985 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1986
1987 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1988 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1989
jbaucheec21bd2016-03-20 06:15:43 -07001990 rtc::CopyOnWriteBuffer buffer("test", 4);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001991 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true)));
1992}
1993
1994// This test setup a RTP data channels in loop back and test that a channel is
1995// opened even if the remote end answer with a zero SSRC.
Steve Anton36da6ff2018-02-16 16:04:20 -08001996TEST_P(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02001997 RTCConfiguration config;
1998 config.enable_rtp_data_channel = true;
1999 config.enable_dtls_srtp = false;
2000 CreatePeerConnection(config);
zhihuang9763d562016-08-05 11:14:50 -07002001 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002002 pc_->CreateDataChannel("test1", NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002003 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002004 new MockDataChannelObserver(data1));
2005
2006 CreateOfferReceiveAnswerWithoutSsrc();
2007
2008 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2009
2010 data1->Close();
2011 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
2012 CreateOfferReceiveAnswerWithoutSsrc();
2013 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2014 EXPECT_FALSE(observer1->IsOpen());
2015}
2016
2017// This test that if a data channel is added in an answer a receive only channel
2018// channel is created.
Steve Anton36da6ff2018-02-16 16:04:20 -08002019TEST_P(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002020 RTCConfiguration config;
2021 config.enable_rtp_data_channel = true;
2022 config.enable_dtls_srtp = false;
2023
2024 CreatePeerConnection(config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002025
2026 std::string offer_label = "offer_channel";
zhihuang9763d562016-08-05 11:14:50 -07002027 rtc::scoped_refptr<DataChannelInterface> offer_channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002028 pc_->CreateDataChannel(offer_label, NULL);
2029
2030 CreateOfferAsLocalDescription();
2031
2032 // Replace the data channel label in the offer and apply it as an answer.
2033 std::string receive_label = "answer_channel";
2034 std::string sdp;
2035 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002036 rtc::replace_substrs(offer_label.c_str(), offer_label.length(),
Yves Gerey665174f2018-06-19 15:03:05 +02002037 receive_label.c_str(), receive_label.length(), &sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002038 CreateAnswerAsRemoteDescription(sdp);
2039
2040 // Verify that a new incoming data channel has been created and that
2041 // it is open but can't we written to.
2042 ASSERT_TRUE(observer_.last_datachannel_ != NULL);
2043 DataChannelInterface* received_channel = observer_.last_datachannel_;
2044 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state());
2045 EXPECT_EQ(receive_label, received_channel->label());
2046 EXPECT_FALSE(received_channel->Send(DataBuffer("something")));
2047
2048 // Verify that the channel we initially offered has been rejected.
2049 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2050
2051 // Do another offer / answer exchange and verify that the data channel is
2052 // opened.
2053 CreateOfferReceiveAnswer();
2054 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(),
2055 kTimeout);
2056}
2057
2058// This test that no data channel is returned if a reliable channel is
2059// requested.
2060// TODO(perkj): Remove this test once reliable channels are implemented.
Steve Anton36da6ff2018-02-16 16:04:20 -08002061TEST_P(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002062 RTCConfiguration rtc_config;
2063 rtc_config.enable_rtp_data_channel = true;
2064 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002065
2066 std::string label = "test";
2067 webrtc::DataChannelInit config;
2068 config.reliable = true;
zhihuang9763d562016-08-05 11:14:50 -07002069 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002070 pc_->CreateDataChannel(label, &config);
2071 EXPECT_TRUE(channel == NULL);
2072}
2073
deadbeefab9b2d12015-10-14 11:33:11 -07002074// Verifies that duplicated label is not allowed for RTP data channel.
Steve Anton36da6ff2018-02-16 16:04:20 -08002075TEST_P(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002076 RTCConfiguration config;
2077 config.enable_rtp_data_channel = true;
2078 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002079
2080 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07002081 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002082 pc_->CreateDataChannel(label, nullptr);
2083 EXPECT_NE(channel, nullptr);
2084
zhihuang9763d562016-08-05 11:14:50 -07002085 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002086 pc_->CreateDataChannel(label, nullptr);
2087 EXPECT_EQ(dup_channel, nullptr);
2088}
2089
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002090// This tests that a SCTP data channel is returned using different
2091// DataChannelInit configurations.
Steve Anton36da6ff2018-02-16 16:04:20 -08002092TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002093 RTCConfiguration rtc_config;
2094 rtc_config.enable_dtls_srtp = true;
2095 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002096
2097 webrtc::DataChannelInit config;
2098
zhihuang9763d562016-08-05 11:14:50 -07002099 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100 pc_->CreateDataChannel("1", &config);
2101 EXPECT_TRUE(channel != NULL);
2102 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002103 EXPECT_TRUE(observer_.renegotiation_needed_);
2104 observer_.renegotiation_needed_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002105
2106 config.ordered = false;
2107 channel = pc_->CreateDataChannel("2", &config);
2108 EXPECT_TRUE(channel != NULL);
2109 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002110 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111
2112 config.ordered = true;
2113 config.maxRetransmits = 0;
2114 channel = pc_->CreateDataChannel("3", &config);
2115 EXPECT_TRUE(channel != NULL);
2116 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002117 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118
2119 config.maxRetransmits = -1;
2120 config.maxRetransmitTime = 0;
2121 channel = pc_->CreateDataChannel("4", &config);
2122 EXPECT_TRUE(channel != NULL);
2123 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002124 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002125}
2126
2127// This tests that no data channel is returned if both maxRetransmits and
2128// maxRetransmitTime are set for SCTP data channels.
Steve Anton36da6ff2018-02-16 16:04:20 -08002129TEST_P(PeerConnectionInterfaceTest,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130 CreateSctpDataChannelShouldFailForInvalidConfig) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002131 RTCConfiguration rtc_config;
2132 rtc_config.enable_dtls_srtp = true;
2133 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002134
2135 std::string label = "test";
2136 webrtc::DataChannelInit config;
2137 config.maxRetransmits = 0;
2138 config.maxRetransmitTime = 0;
2139
zhihuang9763d562016-08-05 11:14:50 -07002140 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002141 pc_->CreateDataChannel(label, &config);
2142 EXPECT_TRUE(channel == NULL);
2143}
2144
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145// The test verifies that creating a SCTP data channel with an id already in use
2146// or out of range should fail.
Steve Anton36da6ff2018-02-16 16:04:20 -08002147TEST_P(PeerConnectionInterfaceTest,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002148 CreateSctpDataChannelWithInvalidIdShouldFail) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002149 RTCConfiguration rtc_config;
2150 rtc_config.enable_dtls_srtp = true;
2151 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002152
2153 webrtc::DataChannelInit config;
zhihuang9763d562016-08-05 11:14:50 -07002154 rtc::scoped_refptr<DataChannelInterface> channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002155
wu@webrtc.orgcecfd182013-10-30 05:18:12 +00002156 config.id = 1;
2157 channel = pc_->CreateDataChannel("1", &config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158 EXPECT_TRUE(channel != NULL);
2159 EXPECT_EQ(1, channel->id());
2160
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002161 channel = pc_->CreateDataChannel("x", &config);
2162 EXPECT_TRUE(channel == NULL);
2163
2164 config.id = cricket::kMaxSctpSid;
2165 channel = pc_->CreateDataChannel("max", &config);
2166 EXPECT_TRUE(channel != NULL);
2167 EXPECT_EQ(config.id, channel->id());
2168
2169 config.id = cricket::kMaxSctpSid + 1;
2170 channel = pc_->CreateDataChannel("x", &config);
2171 EXPECT_TRUE(channel == NULL);
2172}
2173
deadbeefab9b2d12015-10-14 11:33:11 -07002174// Verifies that duplicated label is allowed for SCTP data channel.
Steve Anton36da6ff2018-02-16 16:04:20 -08002175TEST_P(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002176 RTCConfiguration rtc_config;
2177 rtc_config.enable_dtls_srtp = true;
2178 CreatePeerConnection(rtc_config);
deadbeefab9b2d12015-10-14 11:33:11 -07002179
2180 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07002181 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002182 pc_->CreateDataChannel(label, nullptr);
2183 EXPECT_NE(channel, nullptr);
2184
zhihuang9763d562016-08-05 11:14:50 -07002185 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002186 pc_->CreateDataChannel(label, nullptr);
2187 EXPECT_NE(dup_channel, nullptr);
2188}
2189
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002190// This test verifies that OnRenegotiationNeeded is fired for every new RTP
2191// DataChannel.
Steve Anton36da6ff2018-02-16 16:04:20 -08002192TEST_P(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002193 RTCConfiguration rtc_config;
2194 rtc_config.enable_rtp_data_channel = true;
2195 rtc_config.enable_dtls_srtp = false;
2196 CreatePeerConnection(rtc_config);
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002197
zhihuang9763d562016-08-05 11:14:50 -07002198 rtc::scoped_refptr<DataChannelInterface> dc1 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002199 pc_->CreateDataChannel("test1", NULL);
2200 EXPECT_TRUE(observer_.renegotiation_needed_);
2201 observer_.renegotiation_needed_ = false;
2202
zhihuang9763d562016-08-05 11:14:50 -07002203 rtc::scoped_refptr<DataChannelInterface> dc2 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002204 pc_->CreateDataChannel("test2", NULL);
2205 EXPECT_TRUE(observer_.renegotiation_needed_);
2206}
2207
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002208// This test that a data channel closes when a PeerConnection is deleted/closed.
Steve Anton36da6ff2018-02-16 16:04:20 -08002209TEST_P(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002210 RTCConfiguration rtc_config;
2211 rtc_config.enable_rtp_data_channel = true;
2212 rtc_config.enable_dtls_srtp = false;
2213 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002214
zhihuang9763d562016-08-05 11:14:50 -07002215 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07002217 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218 pc_->CreateDataChannel("test2", NULL);
2219 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002220 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002221 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07002222 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002223 new MockDataChannelObserver(data2));
2224
2225 CreateOfferReceiveAnswer();
2226 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2227 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
2228
2229 ReleasePeerConnection();
2230 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2231 EXPECT_EQ(DataChannelInterface::kClosed, data2->state());
2232}
2233
Zhi Huang644fde42018-04-02 19:16:26 -07002234// This tests that RTP data channels can be rejected in an answer.
2235TEST_P(PeerConnectionInterfaceTest, TestRejectRtpDataChannelInAnswer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002236 RTCConfiguration rtc_config;
2237 rtc_config.enable_rtp_data_channel = true;
2238 rtc_config.enable_dtls_srtp = false;
2239 CreatePeerConnection(rtc_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002240
zhihuang9763d562016-08-05 11:14:50 -07002241 rtc::scoped_refptr<DataChannelInterface> offer_channel(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002242 pc_->CreateDataChannel("offer_channel", NULL));
2243
2244 CreateOfferAsLocalDescription();
2245
2246 // Create an answer where the m-line for data channels are rejected.
2247 std::string sdp;
2248 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002249 std::unique_ptr<SessionDescriptionInterface> answer(
Steve Antona3a92c22017-12-07 10:27:41 -08002250 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002251 ASSERT_TRUE(answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002252 cricket::ContentInfo* data_info =
Steve Anton36da6ff2018-02-16 16:04:20 -08002253 cricket::GetFirstDataContent(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002254 data_info->rejected = true;
2255
Steve Antondb45ca82017-09-11 18:27:34 -07002256 DoSetRemoteDescription(std::move(answer));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002257 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2258}
2259
Zhi Huang644fde42018-04-02 19:16:26 -07002260#ifdef HAVE_SCTP
2261// This tests that SCTP data channels can be rejected in an answer.
2262TEST_P(PeerConnectionInterfaceTest, TestRejectSctpDataChannelInAnswer)
2263#else
2264TEST_P(PeerConnectionInterfaceTest, DISABLED_TestRejectSctpDataChannelInAnswer)
2265#endif
2266{
Niels Möllerf06f9232018-08-07 12:32:18 +02002267 RTCConfiguration rtc_config;
2268 CreatePeerConnection(rtc_config);
Zhi Huang644fde42018-04-02 19:16:26 -07002269
2270 rtc::scoped_refptr<DataChannelInterface> offer_channel(
2271 pc_->CreateDataChannel("offer_channel", NULL));
2272
2273 CreateOfferAsLocalDescription();
2274
2275 // Create an answer where the m-line for data channels are rejected.
2276 std::string sdp;
2277 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2278 std::unique_ptr<SessionDescriptionInterface> answer(
2279 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
2280 ASSERT_TRUE(answer);
2281 cricket::ContentInfo* data_info =
2282 cricket::GetFirstDataContent(answer->description());
2283 data_info->rejected = true;
2284
2285 DoSetRemoteDescription(std::move(answer));
2286 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2287}
2288
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002289// Test that we can create a session description from an SDP string from
2290// FireFox, use it as a remote session description, generate an answer and use
2291// the answer as a local description.
Steve Anton36da6ff2018-02-16 16:04:20 -08002292TEST_P(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002293 RTCConfiguration rtc_config;
2294 rtc_config.enable_dtls_srtp = true;
2295 CreatePeerConnection(rtc_config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002296 AddAudioTrack("audio_label");
2297 AddVideoTrack("video_label");
Steve Antondb45ca82017-09-11 18:27:34 -07002298 std::unique_ptr<SessionDescriptionInterface> desc(
Steve Antona3a92c22017-12-07 10:27:41 -08002299 webrtc::CreateSessionDescription(SdpType::kOffer,
Steve Antondb45ca82017-09-11 18:27:34 -07002300 webrtc::kFireFoxSdpOffer, nullptr));
2301 EXPECT_TRUE(DoSetSessionDescription(std::move(desc), false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002302 CreateAnswerAsLocalDescription();
2303 ASSERT_TRUE(pc_->local_description() != NULL);
2304 ASSERT_TRUE(pc_->remote_description() != NULL);
2305
2306 const cricket::ContentInfo* content =
2307 cricket::GetFirstAudioContent(pc_->local_description()->description());
2308 ASSERT_TRUE(content != NULL);
2309 EXPECT_FALSE(content->rejected);
2310
2311 content =
2312 cricket::GetFirstVideoContent(pc_->local_description()->description());
2313 ASSERT_TRUE(content != NULL);
2314 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002315#ifdef HAVE_SCTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002316 content =
2317 cricket::GetFirstDataContent(pc_->local_description()->description());
2318 ASSERT_TRUE(content != NULL);
Zhi Huange830e682018-03-30 10:48:35 -07002319 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002320#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321}
2322
zhihuangb19012e2017-09-19 13:47:59 -07002323// Test that fallback from DTLS to SDES is not supported.
2324// The fallback was previously supported but was removed to simplify the code
2325// and because it's non-standard.
Steve Anton36da6ff2018-02-16 16:04:20 -08002326TEST_P(PeerConnectionInterfaceTest, DtlsSdesFallbackNotSupported) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002327 RTCConfiguration rtc_config;
2328 rtc_config.enable_dtls_srtp = true;
2329 CreatePeerConnection(rtc_config);
deadbeef8662f942017-01-20 21:20:51 -08002330 // Wait for fake certificate to be generated. Previously, this is what caused
2331 // the "a=crypto" lines to be rejected.
Steve Anton36da6ff2018-02-16 16:04:20 -08002332 AddAudioTrack("audio_label");
2333 AddVideoTrack("video_label");
deadbeef8662f942017-01-20 21:20:51 -08002334 ASSERT_NE(nullptr, fake_certificate_generator_);
2335 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2336 kTimeout);
Steve Antondb45ca82017-09-11 18:27:34 -07002337 std::unique_ptr<SessionDescriptionInterface> desc(
Steve Antona3a92c22017-12-07 10:27:41 -08002338 webrtc::CreateSessionDescription(SdpType::kOffer, kDtlsSdesFallbackSdp,
2339 nullptr));
Zhi Huange830e682018-03-30 10:48:35 -07002340 EXPECT_FALSE(DoSetSessionDescription(std::move(desc), /*local=*/false));
deadbeef8662f942017-01-20 21:20:51 -08002341}
2342
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002343// Test that we can create an audio only offer and receive an answer with a
2344// limited set of audio codecs and receive an updated offer with more audio
2345// codecs, where the added codecs are not supported.
Steve Anton36da6ff2018-02-16 16:04:20 -08002346TEST_P(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
deadbeef293e9262017-01-11 12:28:30 -08002347 CreatePeerConnectionWithoutDtls();
Steve Anton36da6ff2018-02-16 16:04:20 -08002348 AddAudioTrack("audio_label");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349 CreateOfferAsLocalDescription();
2350
Steve Anton36da6ff2018-02-16 16:04:20 -08002351 const char* answer_sdp =
2352 (sdp_semantics_ == SdpSemantics::kPlanB ? webrtc::kAudioSdpPlanB
2353 : webrtc::kAudioSdpUnifiedPlan);
Steve Antondb45ca82017-09-11 18:27:34 -07002354 std::unique_ptr<SessionDescriptionInterface> answer(
Steve Anton36da6ff2018-02-16 16:04:20 -08002355 webrtc::CreateSessionDescription(SdpType::kAnswer, answer_sdp, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07002356 EXPECT_TRUE(DoSetSessionDescription(std::move(answer), false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002357
Steve Anton36da6ff2018-02-16 16:04:20 -08002358 const char* reoffer_sdp =
2359 (sdp_semantics_ == SdpSemantics::kPlanB
2360 ? webrtc::kAudioSdpWithUnsupportedCodecsPlanB
2361 : webrtc::kAudioSdpWithUnsupportedCodecsUnifiedPlan);
Steve Antondb45ca82017-09-11 18:27:34 -07002362 std::unique_ptr<SessionDescriptionInterface> updated_offer(
Steve Anton36da6ff2018-02-16 16:04:20 -08002363 webrtc::CreateSessionDescription(SdpType::kOffer, reoffer_sdp, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07002364 EXPECT_TRUE(DoSetSessionDescription(std::move(updated_offer), false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365 CreateAnswerAsLocalDescription();
2366}
2367
deadbeefc80741f2015-10-22 13:14:45 -07002368// Test that if we're receiving (but not sending) a track, subsequent offers
2369// will have m-lines with a=recvonly.
Steve Anton36da6ff2018-02-16 16:04:20 -08002370TEST_P(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002371 RTCConfiguration rtc_config;
2372 rtc_config.enable_dtls_srtp = true;
2373 CreatePeerConnection(rtc_config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002374 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
deadbeefc80741f2015-10-22 13:14:45 -07002375 CreateAnswerAsLocalDescription();
2376
2377 // At this point we should be receiving stream 1, but not sending anything.
2378 // A new offer should be recvonly.
kwibergd1fe2812016-04-27 06:47:29 -07002379 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002380 DoCreateOffer(&offer, nullptr);
2381
2382 const cricket::ContentInfo* video_content =
2383 cricket::GetFirstVideoContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08002384 ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
2385 video_content->media_description()->direction());
deadbeefc80741f2015-10-22 13:14:45 -07002386
2387 const cricket::ContentInfo* audio_content =
2388 cricket::GetFirstAudioContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08002389 ASSERT_EQ(RtpTransceiverDirection::kRecvOnly,
2390 audio_content->media_description()->direction());
deadbeefc80741f2015-10-22 13:14:45 -07002391}
2392
2393// Test that if we're receiving (but not sending) a track, and the
2394// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2395// false, the generated m-lines will be a=inactive.
Steve Anton36da6ff2018-02-16 16:04:20 -08002396TEST_P(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002397 RTCConfiguration rtc_config;
2398 rtc_config.enable_dtls_srtp = true;
2399 CreatePeerConnection(rtc_config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002400 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
deadbeefc80741f2015-10-22 13:14:45 -07002401 CreateAnswerAsLocalDescription();
2402
2403 // At this point we should be receiving stream 1, but not sending anything.
2404 // A new offer would be recvonly, but we'll set the "no receive" constraints
2405 // to make it inactive.
kwibergd1fe2812016-04-27 06:47:29 -07002406 std::unique_ptr<SessionDescriptionInterface> offer;
Niels Möllerf06f9232018-08-07 12:32:18 +02002407 RTCOfferAnswerOptions options;
2408 options.offer_to_receive_audio = 0;
2409 options.offer_to_receive_video = 0;
2410 DoCreateOffer(&offer, &options);
deadbeefc80741f2015-10-22 13:14:45 -07002411
2412 const cricket::ContentInfo* video_content =
2413 cricket::GetFirstVideoContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08002414 ASSERT_EQ(RtpTransceiverDirection::kInactive,
2415 video_content->media_description()->direction());
deadbeefc80741f2015-10-22 13:14:45 -07002416
2417 const cricket::ContentInfo* audio_content =
2418 cricket::GetFirstAudioContent(offer->description());
Steve Antonb1c1de12017-12-21 15:14:30 -08002419 ASSERT_EQ(RtpTransceiverDirection::kInactive,
2420 audio_content->media_description()->direction());
deadbeefc80741f2015-10-22 13:14:45 -07002421}
2422
deadbeef653b8e02015-11-11 12:55:10 -08002423// Test that we can use SetConfiguration to change the ICE servers of the
2424// PortAllocator.
Steve Anton36da6ff2018-02-16 16:04:20 -08002425TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
deadbeef653b8e02015-11-11 12:55:10 -08002426 CreatePeerConnection();
2427
Steve Anton36da6ff2018-02-16 16:04:20 -08002428 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
deadbeef653b8e02015-11-11 12:55:10 -08002429 PeerConnectionInterface::IceServer server;
2430 server.uri = "stun:test_hostname";
2431 config.servers.push_back(server);
2432 EXPECT_TRUE(pc_->SetConfiguration(config));
2433
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08002434 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2435 EXPECT_EQ("test_hostname",
2436 port_allocator_->stun_servers().begin()->hostname());
deadbeef653b8e02015-11-11 12:55:10 -08002437}
2438
Steve Anton36da6ff2018-02-16 16:04:20 -08002439TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002440 CreatePeerConnection();
Steve Anton36da6ff2018-02-16 16:04:20 -08002441 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002442 config.type = PeerConnectionInterface::kRelay;
2443 EXPECT_TRUE(pc_->SetConfiguration(config));
2444 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2445}
2446
Steve Anton36da6ff2018-02-16 16:04:20 -08002447TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
deadbeef293e9262017-01-11 12:28:30 -08002448 PeerConnectionInterface::RTCConfiguration config;
2449 config.prune_turn_ports = false;
Niels Möllerf06f9232018-08-07 12:32:18 +02002450 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002451 config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002452 EXPECT_FALSE(port_allocator_->prune_turn_ports());
2453
2454 config.prune_turn_ports = true;
2455 EXPECT_TRUE(pc_->SetConfiguration(config));
2456 EXPECT_TRUE(port_allocator_->prune_turn_ports());
2457}
2458
skvladd1f5fda2017-02-03 16:54:05 -08002459// Test that the ice check interval can be changed. This does not verify that
2460// the setting makes it all the way to P2PTransportChannel, as that would
2461// require a very complex set of mocks.
Steve Anton36da6ff2018-02-16 16:04:20 -08002462TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
skvladd1f5fda2017-02-03 16:54:05 -08002463 PeerConnectionInterface::RTCConfiguration config;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02002464 config.ice_check_min_interval = absl::nullopt;
Niels Möllerf06f9232018-08-07 12:32:18 +02002465 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002466 config = pc_->GetConfiguration();
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01002467 config.ice_check_min_interval = 100;
skvladd1f5fda2017-02-03 16:54:05 -08002468 EXPECT_TRUE(pc_->SetConfiguration(config));
2469 PeerConnectionInterface::RTCConfiguration new_config =
2470 pc_->GetConfiguration();
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01002471 EXPECT_EQ(new_config.ice_check_min_interval, 100);
skvladd1f5fda2017-02-03 16:54:05 -08002472}
2473
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002474// Test that when SetConfiguration changes both the pool size and other
2475// attributes, the pooled session is created with the updated attributes.
Steve Anton36da6ff2018-02-16 16:04:20 -08002476TEST_P(PeerConnectionInterfaceTest,
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002477 SetConfigurationCreatesPooledSessionCorrectly) {
2478 CreatePeerConnection();
Steve Anton36da6ff2018-02-16 16:04:20 -08002479 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002480 config.ice_candidate_pool_size = 1;
2481 PeerConnectionInterface::IceServer server;
2482 server.uri = kStunAddressOnly;
2483 config.servers.push_back(server);
2484 config.type = PeerConnectionInterface::kRelay;
Taylor Brandstetter417eebe2016-05-23 16:02:19 -07002485 EXPECT_TRUE(pc_->SetConfiguration(config));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002486
2487 const cricket::FakePortAllocatorSession* session =
2488 static_cast<const cricket::FakePortAllocatorSession*>(
2489 port_allocator_->GetPooledSession());
2490 ASSERT_NE(nullptr, session);
2491 EXPECT_EQ(1UL, session->stun_servers().size());
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002492}
2493
deadbeef293e9262017-01-11 12:28:30 -08002494// Test that after SetLocalDescription, changing the pool size is not allowed,
2495// and an invalid modification error is returned.
Steve Anton36da6ff2018-02-16 16:04:20 -08002496TEST_P(PeerConnectionInterfaceTest,
deadbeef6de92f92016-12-12 18:49:32 -08002497 CantChangePoolSizeAfterSetLocalDescription) {
2498 CreatePeerConnection();
2499 // Start by setting a size of 1.
Steve Anton36da6ff2018-02-16 16:04:20 -08002500 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
deadbeef6de92f92016-12-12 18:49:32 -08002501 config.ice_candidate_pool_size = 1;
2502 EXPECT_TRUE(pc_->SetConfiguration(config));
2503
2504 // Set remote offer; can still change pool size at this point.
2505 CreateOfferAsRemoteDescription();
2506 config.ice_candidate_pool_size = 2;
2507 EXPECT_TRUE(pc_->SetConfiguration(config));
2508
2509 // Set local answer; now it's too late.
2510 CreateAnswerAsLocalDescription();
2511 config.ice_candidate_pool_size = 3;
deadbeef293e9262017-01-11 12:28:30 -08002512 RTCError error;
2513 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2514 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2515}
2516
deadbeef42a42632017-03-10 15:18:00 -08002517// Test that after setting an answer, extra pooled sessions are discarded. The
2518// ICE candidate pool is only intended to be used for the first offer/answer.
Steve Anton36da6ff2018-02-16 16:04:20 -08002519TEST_P(PeerConnectionInterfaceTest,
deadbeef42a42632017-03-10 15:18:00 -08002520 ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
2521 CreatePeerConnection();
2522
2523 // Set a larger-than-necessary size.
Steve Anton36da6ff2018-02-16 16:04:20 -08002524 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
deadbeef42a42632017-03-10 15:18:00 -08002525 config.ice_candidate_pool_size = 4;
2526 EXPECT_TRUE(pc_->SetConfiguration(config));
2527
2528 // Do offer/answer.
2529 CreateOfferAsRemoteDescription();
2530 CreateAnswerAsLocalDescription();
2531
2532 // Expect no pooled sessions to be left.
2533 const cricket::PortAllocatorSession* session =
2534 port_allocator_->GetPooledSession();
2535 EXPECT_EQ(nullptr, session);
2536}
2537
2538// After Close is called, pooled candidates should be discarded so as to not
2539// waste network resources.
Steve Anton36da6ff2018-02-16 16:04:20 -08002540TEST_P(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
deadbeef42a42632017-03-10 15:18:00 -08002541 CreatePeerConnection();
2542
Steve Anton36da6ff2018-02-16 16:04:20 -08002543 PeerConnectionInterface::RTCConfiguration config = pc_->GetConfiguration();
deadbeef42a42632017-03-10 15:18:00 -08002544 config.ice_candidate_pool_size = 3;
2545 EXPECT_TRUE(pc_->SetConfiguration(config));
2546 pc_->Close();
2547
2548 // Expect no pooled sessions to be left.
2549 const cricket::PortAllocatorSession* session =
2550 port_allocator_->GetPooledSession();
2551 EXPECT_EQ(nullptr, session);
2552}
2553
deadbeef293e9262017-01-11 12:28:30 -08002554// Test that SetConfiguration returns an invalid modification error if
2555// modifying a field in the configuration that isn't allowed to be modified.
Steve Anton36da6ff2018-02-16 16:04:20 -08002556TEST_P(PeerConnectionInterfaceTest,
deadbeef293e9262017-01-11 12:28:30 -08002557 SetConfigurationReturnsInvalidModificationError) {
2558 PeerConnectionInterface::RTCConfiguration config;
2559 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2560 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2561 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
Niels Möllerf06f9232018-08-07 12:32:18 +02002562 CreatePeerConnection(config);
deadbeef293e9262017-01-11 12:28:30 -08002563
Steve Anton36da6ff2018-02-16 16:04:20 -08002564 PeerConnectionInterface::RTCConfiguration modified_config =
2565 pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002566 modified_config.bundle_policy =
2567 PeerConnectionInterface::kBundlePolicyMaxBundle;
2568 RTCError error;
2569 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2570 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2571
Steve Anton36da6ff2018-02-16 16:04:20 -08002572 modified_config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002573 modified_config.rtcp_mux_policy =
2574 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2575 error.set_type(RTCErrorType::NONE);
2576 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2577 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2578
Steve Anton36da6ff2018-02-16 16:04:20 -08002579 modified_config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002580 modified_config.continual_gathering_policy =
2581 PeerConnectionInterface::GATHER_CONTINUALLY;
2582 error.set_type(RTCErrorType::NONE);
2583 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2584 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2585}
2586
2587// Test that SetConfiguration returns a range error if the candidate pool size
2588// is negative or larger than allowed by the spec.
Steve Anton36da6ff2018-02-16 16:04:20 -08002589TEST_P(PeerConnectionInterfaceTest,
deadbeef293e9262017-01-11 12:28:30 -08002590 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2591 PeerConnectionInterface::RTCConfiguration config;
Niels Möllerf06f9232018-08-07 12:32:18 +02002592 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002593 config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002594
2595 config.ice_candidate_pool_size = -1;
2596 RTCError error;
2597 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2598 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2599
2600 config.ice_candidate_pool_size = INT_MAX;
2601 error.set_type(RTCErrorType::NONE);
2602 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2603 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2604}
2605
2606// Test that SetConfiguration returns a syntax error if parsing an ICE server
2607// URL failed.
Steve Anton36da6ff2018-02-16 16:04:20 -08002608TEST_P(PeerConnectionInterfaceTest,
deadbeef293e9262017-01-11 12:28:30 -08002609 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2610 PeerConnectionInterface::RTCConfiguration config;
Niels Möllerf06f9232018-08-07 12:32:18 +02002611 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002612 config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002613
2614 PeerConnectionInterface::IceServer bad_server;
2615 bad_server.uri = "stunn:www.example.com";
2616 config.servers.push_back(bad_server);
2617 RTCError error;
2618 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2619 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2620}
2621
2622// Test that SetConfiguration returns an invalid parameter error if a TURN
2623// IceServer is missing a username or password.
Steve Anton36da6ff2018-02-16 16:04:20 -08002624TEST_P(PeerConnectionInterfaceTest,
deadbeef293e9262017-01-11 12:28:30 -08002625 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2626 PeerConnectionInterface::RTCConfiguration config;
Niels Möllerf06f9232018-08-07 12:32:18 +02002627 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002628 config = pc_->GetConfiguration();
deadbeef293e9262017-01-11 12:28:30 -08002629
2630 PeerConnectionInterface::IceServer bad_server;
2631 bad_server.uri = "turn:www.example.com";
2632 // Missing password.
2633 bad_server.username = "foo";
2634 config.servers.push_back(bad_server);
2635 RTCError error;
2636 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2637 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
deadbeef6de92f92016-12-12 18:49:32 -08002638}
2639
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002640// Test that PeerConnection::Close changes the states to closed and all remote
2641// tracks change state to ended.
Steve Anton36da6ff2018-02-16 16:04:20 -08002642TEST_P(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002643 // Initialize a PeerConnection and negotiate local and remote session
2644 // description.
2645 InitiateCall();
Steve Anton36da6ff2018-02-16 16:04:20 -08002646
2647 // With Plan B, verify the stream count. The analog with Unified Plan is the
2648 // RtpTransceiver count.
2649 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2650 ASSERT_EQ(1u, pc_->local_streams()->count());
2651 ASSERT_EQ(1u, pc_->remote_streams()->count());
2652 } else {
2653 ASSERT_EQ(2u, pc_->GetTransceivers().size());
2654 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655
2656 pc_->Close();
2657
2658 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2659 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2660 pc_->ice_connection_state());
2661 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2662 pc_->ice_gathering_state());
2663
Steve Anton36da6ff2018-02-16 16:04:20 -08002664 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2665 EXPECT_EQ(1u, pc_->local_streams()->count());
2666 EXPECT_EQ(1u, pc_->remote_streams()->count());
2667 } else {
2668 // Verify that the RtpTransceivers are still present but all stopped.
2669 EXPECT_EQ(2u, pc_->GetTransceivers().size());
2670 for (auto transceiver : pc_->GetTransceivers()) {
2671 EXPECT_TRUE(transceiver->stopped());
2672 }
2673 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002674
Steve Anton36da6ff2018-02-16 16:04:20 -08002675 auto audio_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_AUDIO);
2676 ASSERT_TRUE(audio_receiver);
2677 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
2678 ASSERT_TRUE(video_receiver);
2679
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002680 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002681 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Steve Anton36da6ff2018-02-16 16:04:20 -08002682 audio_receiver->track()->state(), kTimeout);
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002683 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Steve Anton36da6ff2018-02-16 16:04:20 -08002684 video_receiver->track()->state(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685}
2686
2687// Test that PeerConnection methods fails gracefully after
2688// PeerConnection::Close has been called.
Steve Anton36da6ff2018-02-16 16:04:20 -08002689// Don't run under Unified Plan since the stream API is not available.
2690TEST_F(PeerConnectionInterfaceTestPlanB, CloseAndTestMethods) {
deadbeef293e9262017-01-11 12:28:30 -08002691 CreatePeerConnectionWithoutDtls();
Seth Hampson845e8782018-03-02 11:34:10 -08002692 AddAudioVideoStream(kStreamId1, "audio_label", "video_label");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693 CreateOfferAsRemoteDescription();
2694 CreateAnswerAsLocalDescription();
2695
2696 ASSERT_EQ(1u, pc_->local_streams()->count());
zhihuang9763d562016-08-05 11:14:50 -07002697 rtc::scoped_refptr<MediaStreamInterface> local_stream =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002698 pc_->local_streams()->at(0);
2699
2700 pc_->Close();
2701
2702 pc_->RemoveStream(local_stream);
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00002703 EXPECT_FALSE(pc_->AddStream(local_stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002705 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL);
2706
2707 EXPECT_TRUE(pc_->local_description() != NULL);
2708 EXPECT_TRUE(pc_->remote_description() != NULL);
2709
kwibergd1fe2812016-04-27 06:47:29 -07002710 std::unique_ptr<SessionDescriptionInterface> offer;
Steve Anton8d3444d2017-10-20 15:30:51 -07002711 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
kwibergd1fe2812016-04-27 06:47:29 -07002712 std::unique_ptr<SessionDescriptionInterface> answer;
Steve Anton8d3444d2017-10-20 15:30:51 -07002713 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002714
2715 std::string sdp;
2716 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002717 std::unique_ptr<SessionDescriptionInterface> remote_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08002718 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002719 EXPECT_FALSE(DoSetRemoteDescription(std::move(remote_offer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002720
2721 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002722 std::unique_ptr<SessionDescriptionInterface> local_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08002723 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07002724 EXPECT_FALSE(DoSetLocalDescription(std::move(local_offer)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002725}
2726
2727// Test that GetStats can still be called after PeerConnection::Close.
Steve Anton36da6ff2018-02-16 16:04:20 -08002728TEST_P(PeerConnectionInterfaceTest, CloseAndGetStats) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002729 InitiateCall();
2730 pc_->Close();
2731 DoGetStats(NULL);
2732}
deadbeefab9b2d12015-10-14 11:33:11 -07002733
2734// NOTE: The series of tests below come from what used to be
2735// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2736// setting a remote or local description has the expected effects.
2737
2738// This test verifies that the remote MediaStreams corresponding to a received
2739// SDP string is created. In this test the two separate MediaStreams are
2740// signaled.
Steve Anton36da6ff2018-02-16 16:04:20 -08002741TEST_P(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002742 RTCConfiguration config;
2743 config.enable_dtls_srtp = true;
2744 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002745 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
deadbeefab9b2d12015-10-14 11:33:11 -07002746
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002747 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002748 EXPECT_TRUE(
2749 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2750 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2751 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2752
2753 // Create a session description based on another SDP with another
2754 // MediaStream.
Steve Anton36da6ff2018-02-16 16:04:20 -08002755 CreateAndSetRemoteOffer(GetSdpStringWithStream1And2());
deadbeefab9b2d12015-10-14 11:33:11 -07002756
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002757 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002758 EXPECT_TRUE(
2759 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2760}
2761
2762// This test verifies that when remote tracks are added/removed from SDP, the
2763// created remote streams are updated appropriately.
Steve Anton36da6ff2018-02-16 16:04:20 -08002764// Don't run under Unified Plan since this test uses Plan B SDP to test Plan B
2765// specific behavior.
2766TEST_F(PeerConnectionInterfaceTestPlanB,
deadbeefab9b2d12015-10-14 11:33:11 -07002767 AddRemoveTrackFromExistingRemoteMediaStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002768 RTCConfiguration config;
2769 config.enable_dtls_srtp = true;
2770 CreatePeerConnection(config);
kwibergd1fe2812016-04-27 06:47:29 -07002771 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
kwiberg2bbff992016-03-16 11:03:04 -07002772 CreateSessionDescriptionAndReference(1, 1);
Steve Antondb45ca82017-09-11 18:27:34 -07002773 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1)));
deadbeefab9b2d12015-10-14 11:33:11 -07002774 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2775 reference_collection_));
2776
2777 // Add extra audio and video tracks to the same MediaStream.
kwibergd1fe2812016-04-27 06:47:29 -07002778 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
kwiberg2bbff992016-03-16 11:03:04 -07002779 CreateSessionDescriptionAndReference(2, 2);
Steve Antondb45ca82017-09-11 18:27:34 -07002780 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms1_two_tracks)));
deadbeefab9b2d12015-10-14 11:33:11 -07002781 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2782 reference_collection_));
zhihuang9763d562016-08-05 11:14:50 -07002783 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
perkjd61bf802016-03-24 03:16:19 -07002784 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2785 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
zhihuang9763d562016-08-05 11:14:50 -07002786 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
perkjd61bf802016-03-24 03:16:19 -07002787 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2788 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002789
2790 // Remove the extra audio and video tracks.
kwibergd1fe2812016-04-27 06:47:29 -07002791 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
kwiberg2bbff992016-03-16 11:03:04 -07002792 CreateSessionDescriptionAndReference(1, 1);
perkjd61bf802016-03-24 03:16:19 -07002793 MockTrackObserver audio_track_observer(audio_track2);
2794 MockTrackObserver video_track_observer(video_track2);
2795
2796 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2797 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
Steve Antondb45ca82017-09-11 18:27:34 -07002798 EXPECT_TRUE(DoSetRemoteDescription(std::move(desc_ms2)));
deadbeefab9b2d12015-10-14 11:33:11 -07002799 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2800 reference_collection_));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002801 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002802 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002803 audio_track2->state(), kTimeout);
2804 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2805 video_track2->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002806}
2807
2808// This tests that remote tracks are ended if a local session description is set
2809// that rejects the media content type.
Steve Anton36da6ff2018-02-16 16:04:20 -08002810TEST_P(PeerConnectionInterfaceTest, RejectMediaContent) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002811 RTCConfiguration config;
2812 config.enable_dtls_srtp = true;
2813 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002814 // First create and set a remote offer, then reject its video content in our
2815 // answer.
Steve Anton36da6ff2018-02-16 16:04:20 -08002816 CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
2817 auto audio_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_AUDIO);
2818 ASSERT_TRUE(audio_receiver);
2819 auto video_receiver = GetFirstReceiverOfType(cricket::MEDIA_TYPE_VIDEO);
2820 ASSERT_TRUE(video_receiver);
deadbeefab9b2d12015-10-14 11:33:11 -07002821
Steve Anton36da6ff2018-02-16 16:04:20 -08002822 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
2823 audio_receiver->track();
deadbeefab9b2d12015-10-14 11:33:11 -07002824 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
Steve Anton36da6ff2018-02-16 16:04:20 -08002825 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
2826 video_receiver->track();
2827 EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_video->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002828
kwibergd1fe2812016-04-27 06:47:29 -07002829 std::unique_ptr<SessionDescriptionInterface> local_answer;
kwiberg2bbff992016-03-16 11:03:04 -07002830 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002831 cricket::ContentInfo* video_info =
2832 local_answer->description()->GetContentByName("video");
2833 video_info->rejected = true;
Steve Antondb45ca82017-09-11 18:27:34 -07002834 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
Steve Anton36da6ff2018-02-16 16:04:20 -08002835 EXPECT_EQ(MediaStreamTrackInterface::kEnded, remote_video->state());
2836 EXPECT_EQ(MediaStreamTrackInterface::kLive, remote_audio->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002837
2838 // Now create an offer where we reject both video and audio.
kwibergd1fe2812016-04-27 06:47:29 -07002839 std::unique_ptr<SessionDescriptionInterface> local_offer;
kwiberg2bbff992016-03-16 11:03:04 -07002840 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002841 video_info = local_offer->description()->GetContentByName("video");
2842 ASSERT_TRUE(video_info != nullptr);
2843 video_info->rejected = true;
2844 cricket::ContentInfo* audio_info =
2845 local_offer->description()->GetContentByName("audio");
2846 ASSERT_TRUE(audio_info != nullptr);
2847 audio_info->rejected = true;
Steve Antondb45ca82017-09-11 18:27:34 -07002848 EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002849 // Track state may be updated asynchronously.
Steve Anton36da6ff2018-02-16 16:04:20 -08002850 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, remote_audio->state(),
2851 kTimeout);
2852 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, remote_video->state(),
2853 kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002854}
2855
2856// This tests that we won't crash if the remote track has been removed outside
2857// of PeerConnection and then PeerConnection tries to reject the track.
Steve Anton36da6ff2018-02-16 16:04:20 -08002858// Don't run under Unified Plan since the stream API is not available.
2859TEST_F(PeerConnectionInterfaceTestPlanB, RemoveTrackThenRejectMediaContent) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002860 RTCConfiguration config;
2861 config.enable_dtls_srtp = true;
2862 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002863 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
deadbeefab9b2d12015-10-14 11:33:11 -07002864 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2865 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2866 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2867
kwibergd1fe2812016-04-27 06:47:29 -07002868 std::unique_ptr<SessionDescriptionInterface> local_answer(
Steve Anton36da6ff2018-02-16 16:04:20 -08002869 webrtc::CreateSessionDescription(SdpType::kAnswer,
2870 GetSdpStringWithStream1(), nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002871 cricket::ContentInfo* video_info =
2872 local_answer->description()->GetContentByName("video");
2873 video_info->rejected = true;
2874 cricket::ContentInfo* audio_info =
2875 local_answer->description()->GetContentByName("audio");
2876 audio_info->rejected = true;
Steve Antondb45ca82017-09-11 18:27:34 -07002877 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
deadbeefab9b2d12015-10-14 11:33:11 -07002878
2879 // No crash is a pass.
2880}
2881
deadbeef5e97fb52015-10-15 12:49:08 -07002882// This tests that if a recvonly remote description is set, no remote streams
2883// will be created, even if the description contains SSRCs/MSIDs.
2884// See: https://code.google.com/p/webrtc/issues/detail?id=5054
Steve Anton36da6ff2018-02-16 16:04:20 -08002885TEST_P(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002886 RTCConfiguration config;
2887 config.enable_dtls_srtp = true;
2888 CreatePeerConnection(config);
deadbeef5e97fb52015-10-15 12:49:08 -07002889
Steve Anton36da6ff2018-02-16 16:04:20 -08002890 std::string recvonly_offer = GetSdpStringWithStream1();
deadbeef5e97fb52015-10-15 12:49:08 -07002891 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly,
2892 strlen(kRecvonly), &recvonly_offer);
2893 CreateAndSetRemoteOffer(recvonly_offer);
2894
2895 EXPECT_EQ(0u, observer_.remote_streams()->count());
2896}
2897
deadbeefab9b2d12015-10-14 11:33:11 -07002898// This tests that a default MediaStream is created if a remote session
2899// description doesn't contain any streams and no MSID support.
2900// It also tests that the default stream is updated if a video m-line is added
2901// in a subsequent session description.
Steve Anton36da6ff2018-02-16 16:04:20 -08002902// Don't run under Unified Plan since this behavior is Plan B specific.
2903TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithoutMsidCreatesDefaultStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002904 RTCConfiguration config;
2905 config.enable_dtls_srtp = true;
2906 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002907 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2908
2909 ASSERT_EQ(1u, observer_.remote_streams()->count());
2910 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2911
2912 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2913 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
Seth Hampson13b8bad2018-03-13 16:05:28 -07002914 EXPECT_EQ("default", remote_stream->id());
deadbeefab9b2d12015-10-14 11:33:11 -07002915
2916 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2917 ASSERT_EQ(1u, observer_.remote_streams()->count());
2918 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2919 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002920 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2921 remote_stream->GetAudioTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002922 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2923 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002924 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2925 remote_stream->GetVideoTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002926}
2927
2928// This tests that a default MediaStream is created if a remote session
2929// description doesn't contain any streams and media direction is send only.
Steve Anton36da6ff2018-02-16 16:04:20 -08002930// Don't run under Unified Plan since this behavior is Plan B specific.
2931TEST_F(PeerConnectionInterfaceTestPlanB,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002932 SendOnlySdpWithoutMsidCreatesDefaultStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002933 RTCConfiguration config;
2934 config.enable_dtls_srtp = true;
2935 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002936 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2937
2938 ASSERT_EQ(1u, observer_.remote_streams()->count());
2939 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2940
2941 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2942 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
Seth Hampson13b8bad2018-03-13 16:05:28 -07002943 EXPECT_EQ("default", remote_stream->id());
deadbeefab9b2d12015-10-14 11:33:11 -07002944}
2945
2946// This tests that it won't crash when PeerConnection tries to remove
2947// a remote track that as already been removed from the MediaStream.
Steve Anton36da6ff2018-02-16 16:04:20 -08002948// Don't run under Unified Plan since this behavior is Plan B specific.
2949TEST_F(PeerConnectionInterfaceTestPlanB, RemoveAlreadyGoneRemoteStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002950 RTCConfiguration config;
2951 config.enable_dtls_srtp = true;
2952 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08002953 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
deadbeefab9b2d12015-10-14 11:33:11 -07002954 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2955 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2956 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2957
2958 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2959
2960 // No crash is a pass.
2961}
2962
2963// This tests that a default MediaStream is created if the remote session
2964// description doesn't contain any streams and don't contain an indication if
2965// MSID is supported.
Steve Anton36da6ff2018-02-16 16:04:20 -08002966// Don't run under Unified Plan since this behavior is Plan B specific.
2967TEST_F(PeerConnectionInterfaceTestPlanB,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002968 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002969 RTCConfiguration config;
2970 config.enable_dtls_srtp = true;
2971 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002972 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2973
2974 ASSERT_EQ(1u, observer_.remote_streams()->count());
2975 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2976 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2977 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2978}
2979
2980// This tests that a default MediaStream is not created if the remote session
2981// description doesn't contain any streams but does support MSID.
Steve Anton36da6ff2018-02-16 16:04:20 -08002982// Don't run under Unified Plan since this behavior is Plan B specific.
2983TEST_F(PeerConnectionInterfaceTestPlanB, SdpWithMsidDontCreatesDefaultStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002984 RTCConfiguration config;
2985 config.enable_dtls_srtp = true;
2986 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07002987 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2988 EXPECT_EQ(0u, observer_.remote_streams()->count());
2989}
2990
deadbeefbda7e0b2015-12-08 17:13:40 -08002991// This tests that when setting a new description, the old default tracks are
2992// not destroyed and recreated.
2993// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
Steve Anton36da6ff2018-02-16 16:04:20 -08002994// Don't run under Unified Plan since this behavior is Plan B specific.
2995TEST_F(PeerConnectionInterfaceTestPlanB,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002996 DefaultTracksNotDestroyedAndRecreated) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002997 RTCConfiguration config;
2998 config.enable_dtls_srtp = true;
2999 CreatePeerConnection(config);
deadbeefbda7e0b2015-12-08 17:13:40 -08003000 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
3001
3002 ASSERT_EQ(1u, observer_.remote_streams()->count());
3003 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
3004 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
3005
3006 // Set the track to "disabled", then set a new description and ensure the
3007 // track is still disabled, which ensures it hasn't been recreated.
3008 remote_stream->GetAudioTracks()[0]->set_enabled(false);
3009 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
3010 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
3011 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
3012}
3013
deadbeefab9b2d12015-10-14 11:33:11 -07003014// This tests that a default MediaStream is not created if a remote session
3015// description is updated to not have any MediaStreams.
Steve Anton36da6ff2018-02-16 16:04:20 -08003016// Don't run under Unified Plan since this behavior is Plan B specific.
3017TEST_F(PeerConnectionInterfaceTestPlanB, VerifyDefaultStreamIsNotCreated) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003018 RTCConfiguration config;
3019 config.enable_dtls_srtp = true;
3020 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003021 CreateAndSetRemoteOffer(GetSdpStringWithStream1());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003022 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07003023 EXPECT_TRUE(
3024 CompareStreamCollections(observer_.remote_streams(), reference.get()));
3025
3026 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
3027 EXPECT_EQ(0u, observer_.remote_streams()->count());
3028}
3029
Seth Hampson5897a6e2018-04-03 11:16:33 -07003030// This tests that a default MediaStream is created if a remote SDP comes from
3031// an endpoint that doesn't signal SSRCs, but signals media stream IDs.
3032TEST_F(PeerConnectionInterfaceTestPlanB,
3033 SdpWithMsidWithoutSsrcCreatesDefaultStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003034 RTCConfiguration config;
3035 config.enable_dtls_srtp = true;
3036 CreatePeerConnection(config);
Seth Hampson5897a6e2018-04-03 11:16:33 -07003037 std::string sdp_string = kSdpStringWithoutStreamsAudioOnly;
3038 // Add a=msid lines to simulate a Unified Plan endpoint that only
3039 // signals stream IDs with a=msid lines.
3040 sdp_string.append("a=msid:audio_stream_id audio_track_id\n");
3041
3042 CreateAndSetRemoteOffer(sdp_string);
3043
3044 ASSERT_EQ(1u, observer_.remote_streams()->count());
3045 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
3046 EXPECT_EQ("default", remote_stream->id());
3047 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
3048}
3049
Seth Hampson5b4f0752018-04-02 16:31:36 -07003050// This tests that when a Plan B endpoint receives an SDP that signals no media
3051// stream IDs indicated by the special character "-" in the a=msid line, that
3052// a default stream ID will be used for the MediaStream ID. This can occur
3053// when a Unified Plan endpoint signals no media stream IDs, but signals both
3054// a=ssrc msid and a=msid lines for interop signaling with Plan B.
3055TEST_F(PeerConnectionInterfaceTestPlanB,
3056 SdpWithEmptyMsidAndSsrcCreatesDefaultStreamId) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003057 RTCConfiguration config;
3058 config.enable_dtls_srtp = true;
3059 CreatePeerConnection(config);
Seth Hampson5b4f0752018-04-02 16:31:36 -07003060 // Add a a=msid line to the SDP. This is prioritized when parsing the SDP, so
3061 // the sender's stream ID will be interpreted as no stream IDs.
3062 std::string sdp_string = kSdpStringWithStream1AudioTrackOnly;
3063 sdp_string.append("a=msid:- audiotrack0\n");
3064
3065 CreateAndSetRemoteOffer(sdp_string);
3066
3067 ASSERT_EQ(1u, observer_.remote_streams()->count());
3068 // Because SSRCs are signaled the track ID will be what was signaled in the
3069 // a=msid line.
3070 EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
3071 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
3072 EXPECT_EQ("default", remote_stream->id());
3073 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
Seth Hampson83d676b2018-04-05 18:12:09 -07003074
3075 // Previously a bug ocurred when setting the remote description a second time.
3076 // This is because we checked equality of the remote StreamParams stream ID
3077 // (empty), and the previously set stream ID for the remote sender
3078 // ("default"). This cause a track to be removed, then added, when really
3079 // nothing should occur because it is the same track.
3080 CreateAndSetRemoteOffer(sdp_string);
3081 EXPECT_EQ(0u, observer_.remove_track_events_.size());
3082 EXPECT_EQ(1u, observer_.add_track_events_.size());
3083 EXPECT_EQ("audiotrack0", observer_.last_added_track_label_);
3084 remote_stream = observer_.remote_streams()->at(0);
3085 EXPECT_EQ("default", remote_stream->id());
3086 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
Seth Hampson5b4f0752018-04-02 16:31:36 -07003087}
3088
deadbeefab9b2d12015-10-14 11:33:11 -07003089// This tests that an RtpSender is created when the local description is set
3090// after adding a local stream.
3091// TODO(deadbeef): This test and the one below it need to be updated when
3092// an RtpSender's lifetime isn't determined by when a local description is set.
Steve Anton36da6ff2018-02-16 16:04:20 -08003093// Don't run under Unified Plan since this behavior is Plan B specific.
3094TEST_F(PeerConnectionInterfaceTestPlanB, LocalDescriptionChanged) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003095 RTCConfiguration config;
3096 config.enable_dtls_srtp = true;
3097 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07003098
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003099 // Create an offer with 1 stream with 2 tracks of each type.
3100 rtc::scoped_refptr<StreamCollection> stream_collection =
3101 CreateStreamCollection(1, 2);
3102 pc_->AddStream(stream_collection->at(0));
3103 std::unique_ptr<SessionDescriptionInterface> offer;
3104 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003105 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003106
deadbeefab9b2d12015-10-14 11:33:11 -07003107 auto senders = pc_->GetSenders();
3108 EXPECT_EQ(4u, senders.size());
3109 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3110 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3111 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
3112 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
3113
3114 // Remove an audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003115 pc_->RemoveStream(stream_collection->at(0));
3116 stream_collection = CreateStreamCollection(1, 1);
3117 pc_->AddStream(stream_collection->at(0));
3118 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003119 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003120
deadbeefab9b2d12015-10-14 11:33:11 -07003121 senders = pc_->GetSenders();
3122 EXPECT_EQ(2u, senders.size());
3123 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3124 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3125 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
3126 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
3127}
3128
3129// This tests that an RtpSender is created when the local description is set
3130// before adding a local stream.
Steve Anton36da6ff2018-02-16 16:04:20 -08003131// Don't run under Unified Plan since this behavior is Plan B specific.
3132TEST_F(PeerConnectionInterfaceTestPlanB,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07003133 AddLocalStreamAfterLocalDescriptionChanged) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003134 RTCConfiguration config;
3135 config.enable_dtls_srtp = true;
3136 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07003137
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003138 rtc::scoped_refptr<StreamCollection> stream_collection =
3139 CreateStreamCollection(1, 2);
3140 // Add a stream to create the offer, but remove it afterwards.
3141 pc_->AddStream(stream_collection->at(0));
3142 std::unique_ptr<SessionDescriptionInterface> offer;
3143 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3144 pc_->RemoveStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07003145
Steve Antondb45ca82017-09-11 18:27:34 -07003146 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003147 auto senders = pc_->GetSenders();
3148 EXPECT_EQ(0u, senders.size());
3149
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003150 pc_->AddStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07003151 senders = pc_->GetSenders();
3152 EXPECT_EQ(4u, senders.size());
3153 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3154 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3155 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
3156 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
3157}
3158
3159// This tests that the expected behavior occurs if the SSRC on a local track is
3160// changed when SetLocalDescription is called.
Steve Anton36da6ff2018-02-16 16:04:20 -08003161TEST_P(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07003162 ChangeSsrcOnTrackInLocalSessionDescription) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003163 RTCConfiguration config;
3164 config.enable_dtls_srtp = true;
3165 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07003166
Steve Anton36da6ff2018-02-16 16:04:20 -08003167 AddAudioTrack(kAudioTracks[0]);
3168 AddVideoTrack(kVideoTracks[0]);
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003169 std::unique_ptr<SessionDescriptionInterface> offer;
3170 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3171 // Grab a copy of the offer before it gets passed into the PC.
Steve Antond9e4a062018-07-24 18:23:33 -07003172 std::unique_ptr<SessionDescriptionInterface> modified_offer =
3173 webrtc::CreateSessionDescription(
3174 webrtc::SdpType::kOffer, offer->session_id(),
3175 offer->session_version(),
3176 absl::WrapUnique(offer->description()->Copy()));
Steve Antondb45ca82017-09-11 18:27:34 -07003177 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003178
deadbeefab9b2d12015-10-14 11:33:11 -07003179 auto senders = pc_->GetSenders();
3180 EXPECT_EQ(2u, senders.size());
3181 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3182 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3183
3184 // Change the ssrc of the audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003185 cricket::MediaContentDescription* desc =
3186 cricket::GetFirstAudioContentDescription(modified_offer->description());
3187 ASSERT_TRUE(desc != NULL);
3188 for (StreamParams& stream : desc->mutable_streams()) {
3189 for (unsigned int& ssrc : stream.ssrcs) {
3190 ++ssrc;
3191 }
3192 }
deadbeefab9b2d12015-10-14 11:33:11 -07003193
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003194 desc =
3195 cricket::GetFirstVideoContentDescription(modified_offer->description());
3196 ASSERT_TRUE(desc != NULL);
3197 for (StreamParams& stream : desc->mutable_streams()) {
3198 for (unsigned int& ssrc : stream.ssrcs) {
3199 ++ssrc;
3200 }
3201 }
3202
Steve Antondb45ca82017-09-11 18:27:34 -07003203 EXPECT_TRUE(DoSetLocalDescription(std::move(modified_offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003204 senders = pc_->GetSenders();
3205 EXPECT_EQ(2u, senders.size());
3206 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3207 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3208 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
3209 // changed.
3210}
3211
3212// This tests that the expected behavior occurs if a new session description is
3213// set with the same tracks, but on a different MediaStream.
Steve Anton36da6ff2018-02-16 16:04:20 -08003214// Don't run under Unified Plan since the stream API is not available.
3215TEST_F(PeerConnectionInterfaceTestPlanB,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07003216 SignalSameTracksInSeparateMediaStream) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003217 RTCConfiguration config;
3218 config.enable_dtls_srtp = true;
3219 CreatePeerConnection(config);
deadbeefab9b2d12015-10-14 11:33:11 -07003220
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003221 rtc::scoped_refptr<StreamCollection> stream_collection =
3222 CreateStreamCollection(2, 1);
3223 pc_->AddStream(stream_collection->at(0));
3224 std::unique_ptr<SessionDescriptionInterface> offer;
3225 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003226 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003227
deadbeefab9b2d12015-10-14 11:33:11 -07003228 auto senders = pc_->GetSenders();
3229 EXPECT_EQ(2u, senders.size());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003230 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
3231 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
deadbeefab9b2d12015-10-14 11:33:11 -07003232
3233 // Add a new MediaStream but with the same tracks as in the first stream.
3234 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
3235 webrtc::MediaStream::Create(kStreams[1]));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003236 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
3237 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
deadbeefab9b2d12015-10-14 11:33:11 -07003238 pc_->AddStream(stream_1);
3239
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003240 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003241 EXPECT_TRUE(DoSetLocalDescription(std::move(offer)));
deadbeefab9b2d12015-10-14 11:33:11 -07003242
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003243 auto new_senders = pc_->GetSenders();
3244 // Should be the same senders as before, but with updated stream id.
3245 // Note that this behavior is subject to change in the future.
3246 // We may decide the PC should ignore existing tracks in AddStream.
3247 EXPECT_EQ(senders, new_senders);
3248 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
3249 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
deadbeefab9b2d12015-10-14 11:33:11 -07003250}
3251
zhihuang81c3a032016-11-17 12:06:24 -08003252// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
Steve Anton36da6ff2018-02-16 16:04:20 -08003253TEST_P(PeerConnectionInterfaceTest, OnAddTrackCallback) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003254 RTCConfiguration config;
3255 config.enable_dtls_srtp = true;
3256 CreatePeerConnection(config);
zhihuang81c3a032016-11-17 12:06:24 -08003257 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
3258 EXPECT_EQ(observer_.num_added_tracks_, 1);
3259 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
3260
3261 // Create and set the updated remote SDP.
Steve Anton36da6ff2018-02-16 16:04:20 -08003262 CreateAndSetRemoteOffer(kSdpStringWithStream1PlanB);
Steve Anton0f5400a2018-07-17 14:25:36 -07003263 EXPECT_EQ(observer_.num_added_tracks_, 2);
zhihuang81c3a032016-11-17 12:06:24 -08003264 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
3265}
3266
deadbeefd1a38b52016-12-10 13:15:33 -08003267// Test that when SetConfiguration is called and the configuration is
3268// changing, the next offer causes an ICE restart.
Steve Anton36da6ff2018-02-16 16:04:20 -08003269TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingIceRestart) {
deadbeefd1a38b52016-12-10 13:15:33 -08003270 PeerConnectionInterface::RTCConfiguration config;
3271 config.type = PeerConnectionInterface::kRelay;
Niels Möllerf06f9232018-08-07 12:32:18 +02003272 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003273 config = pc_->GetConfiguration();
Seth Hampson845e8782018-03-02 11:34:10 -08003274 AddAudioTrack(kAudioTracks[0], {kStreamId1});
3275 AddVideoTrack(kVideoTracks[0], {kStreamId1});
deadbeefd1a38b52016-12-10 13:15:33 -08003276
3277 // Do initial offer/answer so there's something to restart.
3278 CreateOfferAsLocalDescription();
Steve Anton36da6ff2018-02-16 16:04:20 -08003279 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
deadbeefd1a38b52016-12-10 13:15:33 -08003280
3281 // Grab the ufrags.
3282 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3283
3284 // Change ICE policy, which should trigger an ICE restart on the next offer.
3285 config.type = PeerConnectionInterface::kAll;
3286 EXPECT_TRUE(pc_->SetConfiguration(config));
3287 CreateOfferAsLocalDescription();
3288
3289 // Grab the new ufrags.
3290 std::vector<std::string> subsequent_ufrags =
3291 GetUfrags(pc_->local_description());
3292
3293 // Sanity check.
3294 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
3295 // Check that each ufrag is different.
3296 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
3297 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
3298 }
3299}
3300
3301// Test that when SetConfiguration is called and the configuration *isn't*
3302// changing, the next offer does *not* cause an ICE restart.
Steve Anton36da6ff2018-02-16 16:04:20 -08003303TEST_P(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRestart) {
deadbeefd1a38b52016-12-10 13:15:33 -08003304 PeerConnectionInterface::RTCConfiguration config;
3305 config.type = PeerConnectionInterface::kRelay;
Niels Möllerf06f9232018-08-07 12:32:18 +02003306 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003307 config = pc_->GetConfiguration();
3308 AddAudioTrack(kAudioTracks[0]);
3309 AddVideoTrack(kVideoTracks[0]);
deadbeefd1a38b52016-12-10 13:15:33 -08003310
3311 // Do initial offer/answer so there's something to restart.
3312 CreateOfferAsLocalDescription();
Steve Anton36da6ff2018-02-16 16:04:20 -08003313 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
deadbeefd1a38b52016-12-10 13:15:33 -08003314
3315 // Grab the ufrags.
3316 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3317
3318 // Call SetConfiguration with a config identical to what the PC was
3319 // constructed with.
3320 EXPECT_TRUE(pc_->SetConfiguration(config));
3321 CreateOfferAsLocalDescription();
3322
3323 // Grab the new ufrags.
3324 std::vector<std::string> subsequent_ufrags =
3325 GetUfrags(pc_->local_description());
3326
3327 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
3328}
3329
3330// Test for a weird corner case scenario:
3331// 1. Audio/video session established.
3332// 2. SetConfiguration changes ICE config; ICE restart needed.
3333// 3. ICE restart initiated by remote peer, but only for one m= section.
3334// 4. Next createOffer should initiate an ICE restart, but only for the other
3335// m= section; it would be pointless to do an ICE restart for the m= section
3336// that was already restarted.
Steve Anton36da6ff2018-02-16 16:04:20 -08003337TEST_P(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
deadbeefd1a38b52016-12-10 13:15:33 -08003338 PeerConnectionInterface::RTCConfiguration config;
3339 config.type = PeerConnectionInterface::kRelay;
Niels Möllerf06f9232018-08-07 12:32:18 +02003340 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003341 config = pc_->GetConfiguration();
Seth Hampson845e8782018-03-02 11:34:10 -08003342 AddAudioTrack(kAudioTracks[0], {kStreamId1});
3343 AddVideoTrack(kVideoTracks[0], {kStreamId1});
deadbeefd1a38b52016-12-10 13:15:33 -08003344
3345 // Do initial offer/answer so there's something to restart.
3346 CreateOfferAsLocalDescription();
Steve Anton36da6ff2018-02-16 16:04:20 -08003347 CreateAnswerAsRemoteDescription(GetSdpStringWithStream1());
deadbeefd1a38b52016-12-10 13:15:33 -08003348
3349 // Change ICE policy, which should set the "needs-ice-restart" flag.
3350 config.type = PeerConnectionInterface::kAll;
3351 EXPECT_TRUE(pc_->SetConfiguration(config));
3352
3353 // Do ICE restart for the first m= section, initiated by remote peer.
Steve Antondb45ca82017-09-11 18:27:34 -07003354 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_offer(
Steve Anton36da6ff2018-02-16 16:04:20 -08003355 webrtc::CreateSessionDescription(SdpType::kOffer,
3356 GetSdpStringWithStream1(), nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003357 ASSERT_TRUE(remote_offer);
deadbeefd1a38b52016-12-10 13:15:33 -08003358 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3359 "modified";
Steve Antondb45ca82017-09-11 18:27:34 -07003360 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
deadbeefd1a38b52016-12-10 13:15:33 -08003361 CreateAnswerAsLocalDescription();
3362
3363 // Grab the ufrags.
3364 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003365 ASSERT_EQ(2U, initial_ufrags.size());
deadbeefd1a38b52016-12-10 13:15:33 -08003366
3367 // Create offer and grab the new ufrags.
3368 CreateOfferAsLocalDescription();
3369 std::vector<std::string> subsequent_ufrags =
3370 GetUfrags(pc_->local_description());
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003371 ASSERT_EQ(2U, subsequent_ufrags.size());
deadbeefd1a38b52016-12-10 13:15:33 -08003372
3373 // Ensure that only the ufrag for the second m= section changed.
3374 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3375 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3376}
3377
deadbeeffe4a8a42016-12-20 17:56:17 -08003378// Tests that the methods to return current/pending descriptions work as
3379// expected at different points in the offer/answer exchange. This test does
3380// one offer/answer exchange as the offerer, then another as the answerer.
Steve Anton36da6ff2018-02-16 16:04:20 -08003381TEST_P(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
deadbeeffe4a8a42016-12-20 17:56:17 -08003382 // This disables DTLS so we can apply an answer to ourselves.
3383 CreatePeerConnection();
3384
3385 // Create initial local offer and get SDP (which will also be used as
3386 // answer/pranswer);
Steve Antondb45ca82017-09-11 18:27:34 -07003387 std::unique_ptr<SessionDescriptionInterface> local_offer;
3388 ASSERT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeeffe4a8a42016-12-20 17:56:17 -08003389 std::string sdp;
Steve Antondb45ca82017-09-11 18:27:34 -07003390 EXPECT_TRUE(local_offer->ToString(&sdp));
deadbeeffe4a8a42016-12-20 17:56:17 -08003391
3392 // Set local offer.
Steve Antondb45ca82017-09-11 18:27:34 -07003393 SessionDescriptionInterface* local_offer_ptr = local_offer.get();
3394 EXPECT_TRUE(DoSetLocalDescription(std::move(local_offer)));
3395 EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003396 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3397 EXPECT_EQ(nullptr, pc_->current_local_description());
3398 EXPECT_EQ(nullptr, pc_->current_remote_description());
3399
3400 // Set remote pranswer.
Steve Antondb45ca82017-09-11 18:27:34 -07003401 std::unique_ptr<SessionDescriptionInterface> remote_pranswer(
Steve Antona3a92c22017-12-07 10:27:41 -08003402 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07003403 SessionDescriptionInterface* remote_pranswer_ptr = remote_pranswer.get();
3404 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_pranswer)));
3405 EXPECT_EQ(local_offer_ptr, pc_->pending_local_description());
3406 EXPECT_EQ(remote_pranswer_ptr, pc_->pending_remote_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003407 EXPECT_EQ(nullptr, pc_->current_local_description());
3408 EXPECT_EQ(nullptr, pc_->current_remote_description());
3409
3410 // Set remote answer.
Steve Antondb45ca82017-09-11 18:27:34 -07003411 std::unique_ptr<SessionDescriptionInterface> remote_answer(
Steve Antona3a92c22017-12-07 10:27:41 -08003412 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07003413 SessionDescriptionInterface* remote_answer_ptr = remote_answer.get();
3414 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_answer)));
deadbeeffe4a8a42016-12-20 17:56:17 -08003415 EXPECT_EQ(nullptr, pc_->pending_local_description());
3416 EXPECT_EQ(nullptr, pc_->pending_remote_description());
Steve Antondb45ca82017-09-11 18:27:34 -07003417 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3418 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003419
3420 // Set remote offer.
Steve Antondb45ca82017-09-11 18:27:34 -07003421 std::unique_ptr<SessionDescriptionInterface> remote_offer(
Steve Antona3a92c22017-12-07 10:27:41 -08003422 webrtc::CreateSessionDescription(SdpType::kOffer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07003423 SessionDescriptionInterface* remote_offer_ptr = remote_offer.get();
3424 EXPECT_TRUE(DoSetRemoteDescription(std::move(remote_offer)));
3425 EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003426 EXPECT_EQ(nullptr, pc_->pending_local_description());
Steve Antondb45ca82017-09-11 18:27:34 -07003427 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3428 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003429
3430 // Set local pranswer.
Steve Antondb45ca82017-09-11 18:27:34 -07003431 std::unique_ptr<SessionDescriptionInterface> local_pranswer(
Steve Antona3a92c22017-12-07 10:27:41 -08003432 webrtc::CreateSessionDescription(SdpType::kPrAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07003433 SessionDescriptionInterface* local_pranswer_ptr = local_pranswer.get();
3434 EXPECT_TRUE(DoSetLocalDescription(std::move(local_pranswer)));
3435 EXPECT_EQ(remote_offer_ptr, pc_->pending_remote_description());
3436 EXPECT_EQ(local_pranswer_ptr, pc_->pending_local_description());
3437 EXPECT_EQ(local_offer_ptr, pc_->current_local_description());
3438 EXPECT_EQ(remote_answer_ptr, pc_->current_remote_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003439
3440 // Set local answer.
Steve Antondb45ca82017-09-11 18:27:34 -07003441 std::unique_ptr<SessionDescriptionInterface> local_answer(
Steve Antona3a92c22017-12-07 10:27:41 -08003442 webrtc::CreateSessionDescription(SdpType::kAnswer, sdp));
Steve Antondb45ca82017-09-11 18:27:34 -07003443 SessionDescriptionInterface* local_answer_ptr = local_answer.get();
3444 EXPECT_TRUE(DoSetLocalDescription(std::move(local_answer)));
deadbeeffe4a8a42016-12-20 17:56:17 -08003445 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3446 EXPECT_EQ(nullptr, pc_->pending_local_description());
Steve Antondb45ca82017-09-11 18:27:34 -07003447 EXPECT_EQ(remote_offer_ptr, pc_->current_remote_description());
3448 EXPECT_EQ(local_answer_ptr, pc_->current_local_description());
deadbeeffe4a8a42016-12-20 17:56:17 -08003449}
3450
zhihuang77985012017-02-07 15:45:16 -08003451// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3452// after the PeerConnection is closed.
Elad Alon99c3fe52017-10-13 16:29:40 +02003453// This version tests the StartRtcEventLog version that receives a file.
Steve Anton36da6ff2018-02-16 16:04:20 -08003454TEST_P(PeerConnectionInterfaceTest,
Elad Alon99c3fe52017-10-13 16:29:40 +02003455 StartAndStopLoggingToFileAfterPeerConnectionClosed) {
zhihuang77985012017-02-07 15:45:16 -08003456 CreatePeerConnection();
3457 // The RtcEventLog will be reset when the PeerConnection is closed.
3458 pc_->Close();
3459
Elad Alon9e6565b2017-10-11 16:04:13 +02003460 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
3461 std::string filename = webrtc::test::OutputPath() +
3462 test_info->test_case_name() + test_info->name();
3463 rtc::PlatformFile file = rtc::CreatePlatformFile(filename);
3464
3465 constexpr int64_t max_size_bytes = 1024;
3466
zhihuang77985012017-02-07 15:45:16 -08003467 EXPECT_FALSE(pc_->StartRtcEventLog(file, max_size_bytes));
3468 pc_->StopRtcEventLog();
Elad Alon9e6565b2017-10-11 16:04:13 +02003469
3470 // Cleanup.
3471 rtc::ClosePlatformFile(file);
3472 rtc::RemoveFile(filename);
zhihuang77985012017-02-07 15:45:16 -08003473}
3474
Elad Alon99c3fe52017-10-13 16:29:40 +02003475// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3476// after the PeerConnection is closed.
3477// This version tests the StartRtcEventLog version that receives an object
3478// of type |RtcEventLogOutput|.
Steve Anton36da6ff2018-02-16 16:04:20 -08003479TEST_P(PeerConnectionInterfaceTest,
Elad Alon99c3fe52017-10-13 16:29:40 +02003480 StartAndStopLoggingToOutputAfterPeerConnectionClosed) {
3481 CreatePeerConnection();
3482 // The RtcEventLog will be reset when the PeerConnection is closed.
3483 pc_->Close();
3484
3485 rtc::PlatformFile file = 0;
3486 int64_t max_size_bytes = 1024;
3487 EXPECT_FALSE(pc_->StartRtcEventLog(
Karl Wiberg918f50c2018-07-05 11:40:33 +02003488 absl::make_unique<webrtc::RtcEventLogOutputFile>(file, max_size_bytes),
Bjorn Tereliusde939432017-11-20 17:38:14 +01003489 webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02003490 pc_->StopRtcEventLog();
3491}
3492
deadbeef30952b42017-04-21 02:41:29 -07003493// Test that generated offers/answers include "ice-option:trickle".
Steve Anton36da6ff2018-02-16 16:04:20 -08003494TEST_P(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
deadbeef30952b42017-04-21 02:41:29 -07003495 CreatePeerConnection();
3496
3497 // First, create an offer with audio/video.
Niels Möllerf06f9232018-08-07 12:32:18 +02003498 RTCOfferAnswerOptions options;
3499 options.offer_to_receive_audio = 1;
3500 options.offer_to_receive_video = 1;
deadbeef30952b42017-04-21 02:41:29 -07003501 std::unique_ptr<SessionDescriptionInterface> offer;
Niels Möllerf06f9232018-08-07 12:32:18 +02003502 ASSERT_TRUE(DoCreateOffer(&offer, &options));
deadbeef30952b42017-04-21 02:41:29 -07003503 cricket::SessionDescription* desc = offer->description();
3504 ASSERT_EQ(2u, desc->transport_infos().size());
3505 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3506 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3507
3508 // Apply the offer as a remote description, then create an answer.
Steve Antondb45ca82017-09-11 18:27:34 -07003509 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
deadbeef30952b42017-04-21 02:41:29 -07003510 std::unique_ptr<SessionDescriptionInterface> answer;
Niels Möllerf06f9232018-08-07 12:32:18 +02003511 ASSERT_TRUE(DoCreateAnswer(&answer, &options));
deadbeef30952b42017-04-21 02:41:29 -07003512 desc = answer->description();
3513 ASSERT_EQ(2u, desc->transport_infos().size());
3514 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3515 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3516}
3517
deadbeef1dcb1642017-03-29 21:08:16 -07003518// Test that ICE renomination isn't offered if it's not enabled in the PC's
3519// RTCConfiguration.
Steve Anton36da6ff2018-02-16 16:04:20 -08003520TEST_P(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003521 PeerConnectionInterface::RTCConfiguration config;
3522 config.enable_ice_renomination = false;
Niels Möllerf06f9232018-08-07 12:32:18 +02003523 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003524 AddAudioTrack("foo");
deadbeef1dcb1642017-03-29 21:08:16 -07003525
3526 std::unique_ptr<SessionDescriptionInterface> offer;
3527 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3528 cricket::SessionDescription* desc = offer->description();
3529 EXPECT_EQ(1u, desc->transport_infos().size());
3530 EXPECT_FALSE(
3531 desc->transport_infos()[0].description.GetIceParameters().renomination);
3532}
3533
3534// Test that the ICE renomination option is present in generated offers/answers
3535// if it's enabled in the PC's RTCConfiguration.
Steve Anton36da6ff2018-02-16 16:04:20 -08003536TEST_P(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003537 PeerConnectionInterface::RTCConfiguration config;
3538 config.enable_ice_renomination = true;
Niels Möllerf06f9232018-08-07 12:32:18 +02003539 CreatePeerConnection(config);
Steve Anton36da6ff2018-02-16 16:04:20 -08003540 AddAudioTrack("foo");
deadbeef1dcb1642017-03-29 21:08:16 -07003541
3542 std::unique_ptr<SessionDescriptionInterface> offer;
3543 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3544 cricket::SessionDescription* desc = offer->description();
3545 EXPECT_EQ(1u, desc->transport_infos().size());
3546 EXPECT_TRUE(
3547 desc->transport_infos()[0].description.GetIceParameters().renomination);
3548
3549 // Set the offer as a remote description, then create an answer and ensure it
3550 // has the renomination flag too.
Steve Antondb45ca82017-09-11 18:27:34 -07003551 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
deadbeef1dcb1642017-03-29 21:08:16 -07003552 std::unique_ptr<SessionDescriptionInterface> answer;
3553 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3554 desc = answer->description();
3555 EXPECT_EQ(1u, desc->transport_infos().size());
3556 EXPECT_TRUE(
3557 desc->transport_infos()[0].description.GetIceParameters().renomination);
3558}
3559
3560// Test that if CreateOffer is called with the deprecated "offer to receive
3561// audio/video" constraints, they're processed and result in an offer with
3562// audio/video sections just as if RTCOfferAnswerOptions had been used.
Steve Anton36da6ff2018-02-16 16:04:20 -08003563TEST_P(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
deadbeef1dcb1642017-03-29 21:08:16 -07003564 CreatePeerConnection();
3565
Niels Möllerf06f9232018-08-07 12:32:18 +02003566 RTCOfferAnswerOptions options;
3567 options.offer_to_receive_audio = 1;
3568 options.offer_to_receive_video = 1;
deadbeef1dcb1642017-03-29 21:08:16 -07003569 std::unique_ptr<SessionDescriptionInterface> offer;
Niels Möllerf06f9232018-08-07 12:32:18 +02003570 ASSERT_TRUE(DoCreateOffer(&offer, &options));
deadbeef1dcb1642017-03-29 21:08:16 -07003571
3572 cricket::SessionDescription* desc = offer->description();
3573 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3574 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3575 ASSERT_NE(nullptr, audio);
3576 ASSERT_NE(nullptr, video);
3577 EXPECT_FALSE(audio->rejected);
3578 EXPECT_FALSE(video->rejected);
3579}
3580
3581// Test that if CreateAnswer is called with the deprecated "offer to receive
3582// audio/video" constraints, they're processed and can be used to reject an
3583// offered m= section just as can be done with RTCOfferAnswerOptions;
Steve Anton36da6ff2018-02-16 16:04:20 -08003584// Don't run under Unified Plan since this behavior is not supported.
3585TEST_F(PeerConnectionInterfaceTestPlanB,
3586 CreateAnswerWithOfferToReceiveConstraints) {
deadbeef1dcb1642017-03-29 21:08:16 -07003587 CreatePeerConnection();
3588
3589 // First, create an offer with audio/video and apply it as a remote
3590 // description.
Niels Möllerf06f9232018-08-07 12:32:18 +02003591 RTCOfferAnswerOptions options;
3592 options.offer_to_receive_audio = 1;
3593 options.offer_to_receive_video = 1;
deadbeef1dcb1642017-03-29 21:08:16 -07003594 std::unique_ptr<SessionDescriptionInterface> offer;
Niels Möllerf06f9232018-08-07 12:32:18 +02003595 ASSERT_TRUE(DoCreateOffer(&offer, &options));
Steve Antondb45ca82017-09-11 18:27:34 -07003596 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
deadbeef1dcb1642017-03-29 21:08:16 -07003597
3598 // Now create answer that rejects audio/video.
Niels Möllerf06f9232018-08-07 12:32:18 +02003599 options.offer_to_receive_audio = 0;
3600 options.offer_to_receive_video = 0;
deadbeef1dcb1642017-03-29 21:08:16 -07003601 std::unique_ptr<SessionDescriptionInterface> answer;
Niels Möllerf06f9232018-08-07 12:32:18 +02003602 ASSERT_TRUE(DoCreateAnswer(&answer, &options));
deadbeef1dcb1642017-03-29 21:08:16 -07003603
3604 cricket::SessionDescription* desc = answer->description();
3605 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3606 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3607 ASSERT_NE(nullptr, audio);
3608 ASSERT_NE(nullptr, video);
3609 EXPECT_TRUE(audio->rejected);
3610 EXPECT_TRUE(video->rejected);
3611}
3612
deadbeef1dcb1642017-03-29 21:08:16 -07003613// Test that negotiation can succeed with a data channel only, and with the max
3614// bundle policy. Previously there was a bug that prevented this.
Steve Anton36da6ff2018-02-16 16:04:20 -08003615#ifdef HAVE_SCTP
3616TEST_P(PeerConnectionInterfaceTest, DataChannelOnlyOfferWithMaxBundlePolicy) {
3617#else
3618TEST_P(PeerConnectionInterfaceTest,
3619 DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy) {
3620#endif // HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003621 PeerConnectionInterface::RTCConfiguration config;
3622 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
Niels Möllerf06f9232018-08-07 12:32:18 +02003623 CreatePeerConnection(config);
deadbeef1dcb1642017-03-29 21:08:16 -07003624
3625 // First, create an offer with only a data channel and apply it as a remote
3626 // description.
3627 pc_->CreateDataChannel("test", nullptr);
3628 std::unique_ptr<SessionDescriptionInterface> offer;
3629 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003630 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
deadbeef1dcb1642017-03-29 21:08:16 -07003631
3632 // Create and set answer as well.
3633 std::unique_ptr<SessionDescriptionInterface> answer;
3634 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
Steve Antondb45ca82017-09-11 18:27:34 -07003635 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
deadbeef1dcb1642017-03-29 21:08:16 -07003636}
3637
Steve Anton36da6ff2018-02-16 16:04:20 -08003638TEST_P(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
zstein4b979802017-06-02 14:37:37 -07003639 CreatePeerConnection();
3640 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003641 bitrate.current_bitrate_bps = 100000;
zstein4b979802017-06-02 14:37:37 -07003642 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3643}
3644
Steve Anton36da6ff2018-02-16 16:04:20 -08003645TEST_P(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
zstein4b979802017-06-02 14:37:37 -07003646 CreatePeerConnection();
3647 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003648 bitrate.min_bitrate_bps = -1;
zstein4b979802017-06-02 14:37:37 -07003649 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3650}
3651
Steve Anton36da6ff2018-02-16 16:04:20 -08003652TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
zstein4b979802017-06-02 14:37:37 -07003653 CreatePeerConnection();
3654 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003655 bitrate.min_bitrate_bps = 5;
3656 bitrate.current_bitrate_bps = 3;
zstein4b979802017-06-02 14:37:37 -07003657 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3658}
3659
Steve Anton36da6ff2018-02-16 16:04:20 -08003660TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
zstein4b979802017-06-02 14:37:37 -07003661 CreatePeerConnection();
3662 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003663 bitrate.current_bitrate_bps = -1;
zstein4b979802017-06-02 14:37:37 -07003664 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3665}
3666
Steve Anton36da6ff2018-02-16 16:04:20 -08003667TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
zstein4b979802017-06-02 14:37:37 -07003668 CreatePeerConnection();
3669 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003670 bitrate.current_bitrate_bps = 10;
3671 bitrate.max_bitrate_bps = 8;
zstein4b979802017-06-02 14:37:37 -07003672 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3673}
3674
Steve Anton36da6ff2018-02-16 16:04:20 -08003675TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
zstein4b979802017-06-02 14:37:37 -07003676 CreatePeerConnection();
3677 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003678 bitrate.min_bitrate_bps = 10;
3679 bitrate.max_bitrate_bps = 8;
zstein4b979802017-06-02 14:37:37 -07003680 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3681}
3682
Steve Anton36da6ff2018-02-16 16:04:20 -08003683TEST_P(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
zstein4b979802017-06-02 14:37:37 -07003684 CreatePeerConnection();
3685 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003686 bitrate.max_bitrate_bps = -1;
zstein4b979802017-06-02 14:37:37 -07003687 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3688}
3689
Steve Anton038834f2017-07-14 15:59:59 -07003690// ice_regather_interval_range requires WebRTC to be configured for continual
3691// gathering already.
Steve Anton36da6ff2018-02-16 16:04:20 -08003692TEST_P(PeerConnectionInterfaceTest,
Steve Anton038834f2017-07-14 15:59:59 -07003693 SetIceRegatherIntervalRangeWithoutContinualGatheringFails) {
3694 PeerConnectionInterface::RTCConfiguration config;
3695 config.ice_regather_interval_range.emplace(1000, 2000);
3696 config.continual_gathering_policy =
3697 PeerConnectionInterface::ContinualGatheringPolicy::GATHER_ONCE;
3698 CreatePeerConnectionExpectFail(config);
3699}
3700
3701// Ensures that there is no error when ice_regather_interval_range is set with
3702// continual gathering enabled.
Steve Anton36da6ff2018-02-16 16:04:20 -08003703TEST_P(PeerConnectionInterfaceTest,
Steve Anton038834f2017-07-14 15:59:59 -07003704 SetIceRegatherIntervalRangeWithContinualGathering) {
3705 PeerConnectionInterface::RTCConfiguration config;
3706 config.ice_regather_interval_range.emplace(1000, 2000);
3707 config.continual_gathering_policy =
3708 PeerConnectionInterface::ContinualGatheringPolicy::GATHER_CONTINUALLY;
Niels Möllerf06f9232018-08-07 12:32:18 +02003709 CreatePeerConnection(config);
Steve Anton038834f2017-07-14 15:59:59 -07003710}
3711
Niels Möller0c4f7be2018-05-07 14:01:37 +02003712// The current bitrate from BitrateSettings is currently clamped
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003713// by Call's BitrateConstraints, which comes from the SDP or a default value.
3714// This test checks that a call to SetBitrate with a current bitrate that will
3715// be clamped succeeds.
Steve Anton36da6ff2018-02-16 16:04:20 -08003716TEST_P(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
zstein4b979802017-06-02 14:37:37 -07003717 CreatePeerConnection();
3718 PeerConnectionInterface::BitrateParameters bitrate;
Oskar Sundbomb95fd2c2017-11-16 10:54:38 +01003719 bitrate.current_bitrate_bps = 1;
zstein4b979802017-06-02 14:37:37 -07003720 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3721}
3722
zhihuang1c378ed2017-08-17 14:10:50 -07003723// The following tests verify that the offer can be created correctly.
Steve Anton36da6ff2018-02-16 16:04:20 -08003724TEST_P(PeerConnectionInterfaceTest,
zhihuang1c378ed2017-08-17 14:10:50 -07003725 CreateOfferFailsWithInvalidOfferToReceiveAudio) {
3726 RTCOfferAnswerOptions rtc_options;
3727
3728 // Setting offer_to_receive_audio to a value lower than kUndefined or greater
3729 // than kMaxOfferToReceiveMedia should be treated as invalid.
3730 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3731 CreatePeerConnection();
3732 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3733
3734 rtc_options.offer_to_receive_audio =
3735 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
3736 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3737}
3738
Steve Anton36da6ff2018-02-16 16:04:20 -08003739TEST_P(PeerConnectionInterfaceTest,
zhihuang1c378ed2017-08-17 14:10:50 -07003740 CreateOfferFailsWithInvalidOfferToReceiveVideo) {
3741 RTCOfferAnswerOptions rtc_options;
3742
3743 // Setting offer_to_receive_video to a value lower than kUndefined or greater
3744 // than kMaxOfferToReceiveMedia should be treated as invalid.
3745 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3746 CreatePeerConnection();
3747 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3748
3749 rtc_options.offer_to_receive_video =
3750 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
3751 EXPECT_FALSE(CreateOfferWithOptions(rtc_options));
3752}
3753
3754// Test that the audio and video content will be added to an offer if both
3755// |offer_to_receive_audio| and |offer_to_receive_video| options are 1.
Steve Anton36da6ff2018-02-16 16:04:20 -08003756TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioVideoOptions) {
zhihuang1c378ed2017-08-17 14:10:50 -07003757 RTCOfferAnswerOptions rtc_options;
3758 rtc_options.offer_to_receive_audio = 1;
3759 rtc_options.offer_to_receive_video = 1;
3760
3761 std::unique_ptr<SessionDescriptionInterface> offer;
3762 CreatePeerConnection();
3763 offer = CreateOfferWithOptions(rtc_options);
3764 ASSERT_TRUE(offer);
3765 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3766 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3767}
3768
3769// Test that only audio content will be added to the offer if only
3770// |offer_to_receive_audio| options is 1.
Steve Anton36da6ff2018-02-16 16:04:20 -08003771TEST_P(PeerConnectionInterfaceTest, CreateOfferWithAudioOnlyOptions) {
zhihuang1c378ed2017-08-17 14:10:50 -07003772 RTCOfferAnswerOptions rtc_options;
3773 rtc_options.offer_to_receive_audio = 1;
3774 rtc_options.offer_to_receive_video = 0;
3775
3776 std::unique_ptr<SessionDescriptionInterface> offer;
3777 CreatePeerConnection();
3778 offer = CreateOfferWithOptions(rtc_options);
3779 ASSERT_TRUE(offer);
3780 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3781 EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
3782}
3783
3784// Test that only video content will be added if only |offer_to_receive_video|
3785// options is 1.
Steve Anton36da6ff2018-02-16 16:04:20 -08003786TEST_P(PeerConnectionInterfaceTest, CreateOfferWithVideoOnlyOptions) {
zhihuang1c378ed2017-08-17 14:10:50 -07003787 RTCOfferAnswerOptions rtc_options;
3788 rtc_options.offer_to_receive_audio = 0;
3789 rtc_options.offer_to_receive_video = 1;
3790
3791 std::unique_ptr<SessionDescriptionInterface> offer;
3792 CreatePeerConnection();
3793 offer = CreateOfferWithOptions(rtc_options);
3794 ASSERT_TRUE(offer);
3795 EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
3796 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3797}
3798
zhihuang1c378ed2017-08-17 14:10:50 -07003799// Test that no media content will be added to the offer if using default
3800// RTCOfferAnswerOptions.
Steve Anton36da6ff2018-02-16 16:04:20 -08003801TEST_P(PeerConnectionInterfaceTest, CreateOfferWithDefaultOfferAnswerOptions) {
zhihuang1c378ed2017-08-17 14:10:50 -07003802 RTCOfferAnswerOptions rtc_options;
3803
3804 std::unique_ptr<SessionDescriptionInterface> offer;
3805 CreatePeerConnection();
3806 offer = CreateOfferWithOptions(rtc_options);
3807 ASSERT_TRUE(offer);
3808 EXPECT_EQ(nullptr, GetFirstAudioContent(offer->description()));
3809 EXPECT_EQ(nullptr, GetFirstVideoContent(offer->description()));
3810}
3811
3812// Test that if |ice_restart| is true, the ufrag/pwd will change, otherwise
3813// ufrag/pwd will be the same in the new offer.
Steve Anton36da6ff2018-02-16 16:04:20 -08003814TEST_P(PeerConnectionInterfaceTest, CreateOfferWithIceRestart) {
3815 CreatePeerConnection();
3816
zhihuang1c378ed2017-08-17 14:10:50 -07003817 RTCOfferAnswerOptions rtc_options;
3818 rtc_options.ice_restart = false;
3819 rtc_options.offer_to_receive_audio = 1;
3820
3821 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang1c378ed2017-08-17 14:10:50 -07003822 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
Steve Anton36da6ff2018-02-16 16:04:20 -08003823 std::string mid = cricket::GetFirstAudioContent(offer->description())->name;
3824 auto ufrag1 =
3825 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3826 auto pwd1 =
3827 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
zhihuang1c378ed2017-08-17 14:10:50 -07003828
3829 // |ice_restart| is false, the ufrag/pwd shouldn't change.
3830 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
Steve Anton36da6ff2018-02-16 16:04:20 -08003831 auto ufrag2 =
3832 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3833 auto pwd2 =
3834 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
zhihuang1c378ed2017-08-17 14:10:50 -07003835
3836 // |ice_restart| is true, the ufrag/pwd should change.
3837 rtc_options.ice_restart = true;
3838 CreateOfferWithOptionsAsLocalDescription(&offer, rtc_options);
Steve Anton36da6ff2018-02-16 16:04:20 -08003839 auto ufrag3 =
3840 offer->description()->GetTransportInfoByName(mid)->description.ice_ufrag;
3841 auto pwd3 =
3842 offer->description()->GetTransportInfoByName(mid)->description.ice_pwd;
zhihuang1c378ed2017-08-17 14:10:50 -07003843
3844 EXPECT_EQ(ufrag1, ufrag2);
3845 EXPECT_EQ(pwd1, pwd2);
3846 EXPECT_NE(ufrag2, ufrag3);
3847 EXPECT_NE(pwd2, pwd3);
3848}
3849
3850// Test that if |use_rtp_mux| is true, the bundling will be enabled in the
3851// offer; if it is false, there won't be any bundle group in the offer.
Steve Anton36da6ff2018-02-16 16:04:20 -08003852TEST_P(PeerConnectionInterfaceTest, CreateOfferWithRtpMux) {
zhihuang1c378ed2017-08-17 14:10:50 -07003853 RTCOfferAnswerOptions rtc_options;
3854 rtc_options.offer_to_receive_audio = 1;
3855 rtc_options.offer_to_receive_video = 1;
3856
3857 std::unique_ptr<SessionDescriptionInterface> offer;
3858 CreatePeerConnection();
3859
3860 rtc_options.use_rtp_mux = true;
3861 offer = CreateOfferWithOptions(rtc_options);
3862 ASSERT_TRUE(offer);
3863 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3864 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3865 EXPECT_TRUE(offer->description()->HasGroup(cricket::GROUP_TYPE_BUNDLE));
3866
3867 rtc_options.use_rtp_mux = false;
3868 offer = CreateOfferWithOptions(rtc_options);
3869 ASSERT_TRUE(offer);
3870 EXPECT_NE(nullptr, GetFirstAudioContent(offer->description()));
3871 EXPECT_NE(nullptr, GetFirstVideoContent(offer->description()));
3872 EXPECT_FALSE(offer->description()->HasGroup(cricket::GROUP_TYPE_BUNDLE));
3873}
3874
zhihuang141aacb2017-08-29 13:23:53 -07003875// This test ensures OnRenegotiationNeeded is called when we add track with
3876// MediaStream -> AddTrack in the same way it is called when we add track with
3877// PeerConnection -> AddTrack.
3878// The test can be removed once addStream is rewritten in terms of addTrack
3879// https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
Steve Anton36da6ff2018-02-16 16:04:20 -08003880// Don't run under Unified Plan since the stream API is not available.
3881TEST_F(PeerConnectionInterfaceTestPlanB,
3882 MediaStreamAddTrackRemoveTrackRenegotiate) {
zhihuang141aacb2017-08-29 13:23:53 -07003883 CreatePeerConnectionWithoutDtls();
3884 rtc::scoped_refptr<MediaStreamInterface> stream(
Seth Hampson845e8782018-03-02 11:34:10 -08003885 pc_factory_->CreateLocalMediaStream(kStreamId1));
zhihuang141aacb2017-08-29 13:23:53 -07003886 pc_->AddStream(stream);
3887 rtc::scoped_refptr<AudioTrackInterface> audio_track(
3888 pc_factory_->CreateAudioTrack("audio_track", nullptr));
3889 rtc::scoped_refptr<VideoTrackInterface> video_track(
3890 pc_factory_->CreateVideoTrack(
3891 "video_track", pc_factory_->CreateVideoSource(
3892 std::unique_ptr<cricket::VideoCapturer>(
3893 new cricket::FakeVideoCapturer()))));
3894 stream->AddTrack(audio_track);
3895 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3896 observer_.renegotiation_needed_ = false;
3897
3898 stream->AddTrack(video_track);
3899 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3900 observer_.renegotiation_needed_ = false;
3901
3902 stream->RemoveTrack(audio_track);
3903 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3904 observer_.renegotiation_needed_ = false;
3905
3906 stream->RemoveTrack(video_track);
3907 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3908 observer_.renegotiation_needed_ = false;
3909}
3910
Zhi Huangb2d355e2017-10-26 17:26:37 -07003911// Tests that an error is returned if a description is applied that has fewer
3912// media sections than the existing description.
Steve Anton36da6ff2018-02-16 16:04:20 -08003913TEST_P(PeerConnectionInterfaceTest,
Zhi Huangb2d355e2017-10-26 17:26:37 -07003914 MediaSectionCountEnforcedForSubsequentOffer) {
3915 CreatePeerConnection();
Steve Anton36da6ff2018-02-16 16:04:20 -08003916 AddAudioTrack("audio_label");
3917 AddVideoTrack("video_label");
3918
Zhi Huangb2d355e2017-10-26 17:26:37 -07003919 std::unique_ptr<SessionDescriptionInterface> offer;
Steve Anton36da6ff2018-02-16 16:04:20 -08003920 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Zhi Huangb2d355e2017-10-26 17:26:37 -07003921 EXPECT_TRUE(DoSetRemoteDescription(std::move(offer)));
3922
3923 // A remote offer with fewer media sections should be rejected.
Steve Anton36da6ff2018-02-16 16:04:20 -08003924 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Zhi Huangb2d355e2017-10-26 17:26:37 -07003925 offer->description()->contents().pop_back();
3926 offer->description()->contents().pop_back();
3927 ASSERT_TRUE(offer->description()->contents().empty());
3928 EXPECT_FALSE(DoSetRemoteDescription(std::move(offer)));
3929
3930 std::unique_ptr<SessionDescriptionInterface> answer;
3931 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3932 EXPECT_TRUE(DoSetLocalDescription(std::move(answer)));
3933
3934 // A subsequent local offer with fewer media sections should be rejected.
Steve Anton36da6ff2018-02-16 16:04:20 -08003935 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
Zhi Huangb2d355e2017-10-26 17:26:37 -07003936 offer->description()->contents().pop_back();
3937 offer->description()->contents().pop_back();
3938 ASSERT_TRUE(offer->description()->contents().empty());
3939 EXPECT_FALSE(DoSetLocalDescription(std::move(offer)));
3940}
3941
Steve Anton36da6ff2018-02-16 16:04:20 -08003942INSTANTIATE_TEST_CASE_P(PeerConnectionInterfaceTest,
3943 PeerConnectionInterfaceTest,
3944 Values(SdpSemantics::kPlanB,
3945 SdpSemantics::kUnifiedPlan));
3946
nisse51542be2016-02-12 02:27:06 -08003947class PeerConnectionMediaConfigTest : public testing::Test {
3948 protected:
3949 void SetUp() override {
zhihuang38ede132017-06-15 12:52:32 -07003950 pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
nisse51542be2016-02-12 02:27:06 -08003951 pcf_->Initialize();
3952 }
nisseeaabdf62017-05-05 02:23:02 -07003953 const cricket::MediaConfig TestCreatePeerConnection(
Niels Möllerf06f9232018-08-07 12:32:18 +02003954 const RTCConfiguration& config) {
3955 rtc::scoped_refptr<PeerConnectionInterface> pc(
3956 pcf_->CreatePeerConnection(config, nullptr, nullptr, &observer_));
nisse51542be2016-02-12 02:27:06 -08003957 EXPECT_TRUE(pc.get());
nisseeaabdf62017-05-05 02:23:02 -07003958 return pc->GetConfiguration().media_config;
nisse51542be2016-02-12 02:27:06 -08003959 }
3960
zhihuang9763d562016-08-05 11:14:50 -07003961 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
nisse51542be2016-02-12 02:27:06 -08003962 MockPeerConnectionObserver observer_;
3963};
3964
3965// This test verifies the default behaviour with no constraints and a
3966// default RTCConfiguration.
3967TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3968 PeerConnectionInterface::RTCConfiguration config;
nisse51542be2016-02-12 02:27:06 -08003969
Niels Möllerf06f9232018-08-07 12:32:18 +02003970 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
nisse51542be2016-02-12 02:27:06 -08003971
3972 EXPECT_FALSE(media_config.enable_dscp);
Niels Möller1d7ecd22018-01-18 15:25:12 +01003973 EXPECT_TRUE(media_config.video.enable_cpu_adaptation);
3974 EXPECT_TRUE(media_config.video.enable_prerenderer_smoothing);
nisse0db023a2016-03-01 04:29:59 -08003975 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
Niels Möller6539f692018-01-18 08:58:50 +01003976 EXPECT_FALSE(media_config.video.experiment_cpu_load_estimator);
nisse51542be2016-02-12 02:27:06 -08003977}
3978
Niels Möller1d7ecd22018-01-18 15:25:12 +01003979// This test verifies that the enable_prerenderer_smoothing flag is
nisse528b7932017-05-08 03:21:43 -07003980// propagated from RTCConfiguration to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003981TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3982 PeerConnectionInterface::RTCConfiguration config;
nisse51542be2016-02-12 02:27:06 -08003983
Niels Möller71bdda02016-03-31 12:59:59 +02003984 config.set_prerenderer_smoothing(false);
Niels Möllerf06f9232018-08-07 12:32:18 +02003985 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
nisse51542be2016-02-12 02:27:06 -08003986
Niels Möller1d7ecd22018-01-18 15:25:12 +01003987 EXPECT_FALSE(media_config.video.enable_prerenderer_smoothing);
nisse0db023a2016-03-01 04:29:59 -08003988}
3989
Niels Möller6539f692018-01-18 08:58:50 +01003990// This test verifies that the experiment_cpu_load_estimator flag is
3991// propagated from RTCConfiguration to the PeerConnection.
3992TEST_F(PeerConnectionMediaConfigTest, TestEnableExperimentCpuLoadEstimator) {
3993 PeerConnectionInterface::RTCConfiguration config;
Niels Möller6539f692018-01-18 08:58:50 +01003994
3995 config.set_experiment_cpu_load_estimator(true);
Niels Möllerf06f9232018-08-07 12:32:18 +02003996 const cricket::MediaConfig& media_config = TestCreatePeerConnection(config);
Niels Möller6539f692018-01-18 08:58:50 +01003997
3998 EXPECT_TRUE(media_config.video.experiment_cpu_load_estimator);
3999}
4000
deadbeef293e9262017-01-11 12:28:30 -08004001// Tests a few random fields being different.
4002TEST(RTCConfigurationTest, ComparisonOperators) {
4003 PeerConnectionInterface::RTCConfiguration a;
4004 PeerConnectionInterface::RTCConfiguration b;
4005 EXPECT_EQ(a, b);
4006
4007 PeerConnectionInterface::RTCConfiguration c;
4008 c.servers.push_back(PeerConnectionInterface::IceServer());
4009 EXPECT_NE(a, c);
4010
4011 PeerConnectionInterface::RTCConfiguration d;
4012 d.type = PeerConnectionInterface::kRelay;
4013 EXPECT_NE(a, d);
4014
4015 PeerConnectionInterface::RTCConfiguration e;
4016 e.audio_jitter_buffer_max_packets = 5;
4017 EXPECT_NE(a, e);
4018
4019 PeerConnectionInterface::RTCConfiguration f;
4020 f.ice_connection_receiving_timeout = 1337;
4021 EXPECT_NE(a, f);
4022
4023 PeerConnectionInterface::RTCConfiguration g;
4024 g.disable_ipv6 = true;
4025 EXPECT_NE(a, g);
4026
4027 PeerConnectionInterface::RTCConfiguration h(
4028 PeerConnectionInterface::RTCConfigurationType::kAggressive);
4029 EXPECT_NE(a, h);
4030}