blob: 114ffd75e215206d7df47aaf0fb14bd45565689c [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
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
deadbeef3edec7c2016-12-10 11:44:26 -080012#include <sstream>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013#include <string>
kwiberg0eb15ed2015-12-17 03:04:15 -080014#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015
kwiberg087bd342017-02-10 08:15:44 -080016#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
ossueb1fde42017-05-02 06:46:30 -070017#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010018#include "webrtc/api/jsepsessiondescription.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010019#include "webrtc/api/mediastreaminterface.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010020#include "webrtc/api/peerconnectioninterface.h"
21#include "webrtc/api/rtpreceiverinterface.h"
22#include "webrtc/api/rtpsenderinterface.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010023#include "webrtc/api/test/fakeconstraints.h"
kjellandera96e2d72016-02-04 23:52:28 -080024#include "webrtc/media/base/fakevideocapturer.h"
zhihuang38ede132017-06-15 12:52:32 -070025#include "webrtc/media/engine/webrtcmediaengine.h"
deadbeef953c2ce2017-01-09 14:53:41 -080026#include "webrtc/media/sctp/sctptransportinternal.h"
peaha9cc40b2017-06-29 08:32:09 -070027#include "webrtc/modules/audio_processing/include/audio_processing.h"
Taylor Brandstettera1c30352016-05-13 08:15:11 -070028#include "webrtc/p2p/base/fakeportallocator.h"
ossu7bb87ee2017-01-23 04:56:25 -080029#include "webrtc/pc/audiotrack.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010030#include "webrtc/pc/mediasession.h"
ossu7bb87ee2017-01-23 04:56:25 -080031#include "webrtc/pc/mediastream.h"
32#include "webrtc/pc/peerconnection.h"
33#include "webrtc/pc/streamcollection.h"
34#include "webrtc/pc/test/fakertccertificategenerator.h"
35#include "webrtc/pc/test/fakevideotracksource.h"
36#include "webrtc/pc/test/mockpeerconnectionobservers.h"
37#include "webrtc/pc/test/testsdpstrings.h"
38#include "webrtc/pc/videocapturertracksource.h"
39#include "webrtc/pc/videotrack.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020040#include "webrtc/rtc_base/gunit.h"
41#include "webrtc/rtc_base/ssladapter.h"
42#include "webrtc/rtc_base/sslstreamadapter.h"
43#include "webrtc/rtc_base/stringutils.h"
44#include "webrtc/rtc_base/thread.h"
45#include "webrtc/rtc_base/virtualsocketserver.h"
kwibergac9f8762016-09-30 22:29:43 -070046#include "webrtc/test/gmock.h"
47
48#ifdef WEBRTC_ANDROID
ossu7bb87ee2017-01-23 04:56:25 -080049#include "webrtc/pc/test/androidtestinitializer.h"
kwibergac9f8762016-09-30 22:29:43 -070050#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051
52static const char kStreamLabel1[] = "local_stream_1";
53static const char kStreamLabel2[] = "local_stream_2";
54static const char kStreamLabel3[] = "local_stream_3";
55static const int kDefaultStunPort = 3478;
56static const char kStunAddressOnly[] = "stun:address";
57static const char kStunInvalidPort[] = "stun:address:-1";
58static const char kStunAddressPortAndMore1[] = "stun:address:port:more";
59static const char kStunAddressPortAndMore2[] = "stun:address:port more";
60static const char kTurnIceServerUri[] = "turn:user@turn.example.org";
61static const char kTurnUsername[] = "user";
62static const char kTurnPassword[] = "password";
63static const char kTurnHostname[] = "turn.example.org";
Peter Boström0c4e06b2015-10-07 12:23:21 +020064static const uint32_t kTimeout = 10000U;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065
deadbeefab9b2d12015-10-14 11:33:11 -070066static const char kStreams[][8] = {"stream1", "stream2"};
67static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
68static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
69
deadbeef5e97fb52015-10-15 12:49:08 -070070static const char kRecvonly[] = "recvonly";
71static const char kSendrecv[] = "sendrecv";
72
deadbeefab9b2d12015-10-14 11:33:11 -070073// Reference SDP with a MediaStream with label "stream1" and audio track with
74// id "audio_1" and a video track with id "video_1;
75static const char kSdpStringWithStream1[] =
76 "v=0\r\n"
77 "o=- 0 0 IN IP4 127.0.0.1\r\n"
78 "s=-\r\n"
79 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080080 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070081 "a=ice-ufrag:e5785931\r\n"
82 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
83 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
84 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070085 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070086 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080087 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070088 "a=rtpmap:103 ISAC/16000\r\n"
89 "a=ssrc:1 cname:stream1\r\n"
90 "a=ssrc:1 mslabel:stream1\r\n"
91 "a=ssrc:1 label:audiotrack0\r\n"
92 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080093 "a=ice-ufrag:e5785931\r\n"
94 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
95 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
96 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070097 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070098 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080099 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700100 "a=rtpmap:120 VP8/90000\r\n"
101 "a=ssrc:2 cname:stream1\r\n"
102 "a=ssrc:2 mslabel:stream1\r\n"
103 "a=ssrc:2 label:videotrack0\r\n";
104
zhihuang81c3a032016-11-17 12:06:24 -0800105// Reference SDP with a MediaStream with label "stream1" and audio track with
106// id "audio_1";
107static const char kSdpStringWithStream1AudioTrackOnly[] =
108 "v=0\r\n"
109 "o=- 0 0 IN IP4 127.0.0.1\r\n"
110 "s=-\r\n"
111 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800112 "m=audio 1 RTP/AVPF 103\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800113 "a=ice-ufrag:e5785931\r\n"
114 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
115 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
116 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800117 "a=mid:audio\r\n"
118 "a=sendrecv\r\n"
119 "a=rtpmap:103 ISAC/16000\r\n"
120 "a=ssrc:1 cname:stream1\r\n"
121 "a=ssrc:1 mslabel:stream1\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800122 "a=ssrc:1 label:audiotrack0\r\n"
123 "a=rtcp-mux\r\n";
zhihuang81c3a032016-11-17 12:06:24 -0800124
deadbeefab9b2d12015-10-14 11:33:11 -0700125// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
126// MediaStreams have one audio track and one video track.
127// This uses MSID.
128static const char kSdpStringWithStream1And2[] =
129 "v=0\r\n"
130 "o=- 0 0 IN IP4 127.0.0.1\r\n"
131 "s=-\r\n"
132 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800133 "a=msid-semantic: WMS stream1 stream2\r\n"
134 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700135 "a=ice-ufrag:e5785931\r\n"
136 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
137 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
138 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700139 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700140 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800141 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700142 "a=rtpmap:103 ISAC/16000\r\n"
143 "a=ssrc:1 cname:stream1\r\n"
144 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
145 "a=ssrc:3 cname:stream2\r\n"
146 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
147 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800148 "a=ice-ufrag:e5785931\r\n"
149 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
150 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
151 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700152 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700153 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800154 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700155 "a=rtpmap:120 VP8/0\r\n"
156 "a=ssrc:2 cname:stream1\r\n"
157 "a=ssrc:2 msid:stream1 videotrack0\r\n"
158 "a=ssrc:4 cname:stream2\r\n"
159 "a=ssrc:4 msid:stream2 videotrack1\r\n";
160
161// Reference SDP without MediaStreams. Msid is not supported.
162static const char kSdpStringWithoutStreams[] =
163 "v=0\r\n"
164 "o=- 0 0 IN IP4 127.0.0.1\r\n"
165 "s=-\r\n"
166 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800167 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700168 "a=ice-ufrag:e5785931\r\n"
169 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
170 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
171 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700172 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700173 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800174 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700175 "a=rtpmap:103 ISAC/16000\r\n"
176 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800177 "a=ice-ufrag:e5785931\r\n"
178 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
179 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
180 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700181 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700182 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800183 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700184 "a=rtpmap:120 VP8/90000\r\n";
185
186// Reference SDP without MediaStreams. Msid is supported.
187static const char kSdpStringWithMsidWithoutStreams[] =
188 "v=0\r\n"
189 "o=- 0 0 IN IP4 127.0.0.1\r\n"
190 "s=-\r\n"
191 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800192 "a=msid-semantic: WMS\r\n"
193 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700194 "a=ice-ufrag:e5785931\r\n"
195 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
196 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
197 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700198 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700199 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800200 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700201 "a=rtpmap:103 ISAC/16000\r\n"
202 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800203 "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"
deadbeefab9b2d12015-10-14 11:33:11 -0700207 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700208 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800209 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700210 "a=rtpmap:120 VP8/90000\r\n";
211
212// Reference SDP without MediaStreams and audio only.
213static const char kSdpStringWithoutStreamsAudioOnly[] =
214 "v=0\r\n"
215 "o=- 0 0 IN IP4 127.0.0.1\r\n"
216 "s=-\r\n"
217 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800218 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700219 "a=ice-ufrag:e5785931\r\n"
220 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
221 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
222 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700223 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700224 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800225 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700226 "a=rtpmap:103 ISAC/16000\r\n";
227
228// Reference SENDONLY SDP without MediaStreams. Msid is not supported.
229static const char kSdpStringSendOnlyWithoutStreams[] =
230 "v=0\r\n"
231 "o=- 0 0 IN IP4 127.0.0.1\r\n"
232 "s=-\r\n"
233 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800234 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700235 "a=ice-ufrag:e5785931\r\n"
236 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
237 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
238 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700239 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700240 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700241 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800242 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700243 "a=rtpmap:103 ISAC/16000\r\n"
244 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800245 "a=ice-ufrag:e5785931\r\n"
246 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
247 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
248 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700249 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700250 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700251 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800252 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700253 "a=rtpmap:120 VP8/90000\r\n";
254
255static const char kSdpStringInit[] =
256 "v=0\r\n"
257 "o=- 0 0 IN IP4 127.0.0.1\r\n"
258 "s=-\r\n"
259 "t=0 0\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700260 "a=msid-semantic: WMS\r\n";
261
262static const char kSdpStringAudio[] =
263 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800264 "a=ice-ufrag:e5785931\r\n"
265 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
266 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
267 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700268 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700269 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800270 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700271 "a=rtpmap:103 ISAC/16000\r\n";
272
273static const char kSdpStringVideo[] =
274 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800275 "a=ice-ufrag:e5785931\r\n"
276 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
277 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
278 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700279 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700280 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800281 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700282 "a=rtpmap:120 VP8/90000\r\n";
283
284static const char kSdpStringMs1Audio0[] =
285 "a=ssrc:1 cname:stream1\r\n"
286 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
287
288static const char kSdpStringMs1Video0[] =
289 "a=ssrc:2 cname:stream1\r\n"
290 "a=ssrc:2 msid:stream1 videotrack0\r\n";
291
292static const char kSdpStringMs1Audio1[] =
293 "a=ssrc:3 cname:stream1\r\n"
294 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
295
296static const char kSdpStringMs1Video1[] =
297 "a=ssrc:4 cname:stream1\r\n"
298 "a=ssrc:4 msid:stream1 videotrack1\r\n";
299
deadbeef8662f942017-01-20 21:20:51 -0800300static const char kDtlsSdesFallbackSdp[] =
301 "v=0\r\n"
302 "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n"
303 "s=-\r\n"
304 "c=IN IP4 0.0.0.0\r\n"
305 "t=0 0\r\n"
306 "a=group:BUNDLE audio\r\n"
307 "a=msid-semantic: WMS\r\n"
308 "m=audio 1 RTP/SAVPF 0\r\n"
309 "a=sendrecv\r\n"
310 "a=rtcp-mux\r\n"
311 "a=mid:audio\r\n"
312 "a=ssrc:1 cname:stream1\r\n"
313 "a=ssrc:1 mslabel:stream1\r\n"
314 "a=ssrc:1 label:audiotrack0\r\n"
315 "a=ice-ufrag:e5785931\r\n"
316 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
317 "a=rtpmap:0 pcmu/8000\r\n"
318 "a=fingerprint:sha-1 "
319 "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
320 "a=setup:actpass\r\n"
321 "a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
322 "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
323 "dummy_session_params\r\n";
324
perkjd61bf802016-03-24 03:16:19 -0700325using ::testing::Exactly;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700326using cricket::StreamParams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327using webrtc::AudioSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700328using webrtc::AudioTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329using webrtc::AudioTrackInterface;
330using webrtc::DataBuffer;
331using webrtc::DataChannelInterface;
332using webrtc::FakeConstraints;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333using webrtc::IceCandidateInterface;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700334using webrtc::JsepSessionDescription;
deadbeefc80741f2015-10-22 13:14:45 -0700335using webrtc::MediaConstraintsInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700336using webrtc::MediaStream;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337using webrtc::MediaStreamInterface;
338using webrtc::MediaStreamTrackInterface;
339using webrtc::MockCreateSessionDescriptionObserver;
340using webrtc::MockDataChannelObserver;
341using webrtc::MockSetSessionDescriptionObserver;
342using webrtc::MockStatsObserver;
perkjd61bf802016-03-24 03:16:19 -0700343using webrtc::NotifierInterface;
344using webrtc::ObserverInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345using webrtc::PeerConnectionInterface;
346using webrtc::PeerConnectionObserver;
deadbeef293e9262017-01-11 12:28:30 -0800347using webrtc::RTCError;
348using webrtc::RTCErrorType;
deadbeefab9b2d12015-10-14 11:33:11 -0700349using webrtc::RtpReceiverInterface;
350using webrtc::RtpSenderInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351using webrtc::SdpParseError;
352using webrtc::SessionDescriptionInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700353using webrtc::StreamCollection;
354using webrtc::StreamCollectionInterface;
perkja3ede6c2016-03-08 01:27:48 +0100355using webrtc::VideoTrackSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700356using webrtc::VideoTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357using webrtc::VideoTrackInterface;
358
deadbeefab9b2d12015-10-14 11:33:11 -0700359typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
360
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361namespace {
362
363// Gets the first ssrc of given content type from the ContentInfo.
364bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
365 if (!content_info || !ssrc) {
366 return false;
367 }
368 const cricket::MediaContentDescription* media_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000369 static_cast<const cricket::MediaContentDescription*>(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370 content_info->description);
371 if (!media_desc || media_desc->streams().empty()) {
372 return false;
373 }
374 *ssrc = media_desc->streams().begin()->first_ssrc();
375 return true;
376}
377
deadbeefd1a38b52016-12-10 13:15:33 -0800378// Get the ufrags out of an SDP blob. Useful for testing ICE restart
379// behavior.
380std::vector<std::string> GetUfrags(
381 const webrtc::SessionDescriptionInterface* desc) {
382 std::vector<std::string> ufrags;
383 for (const cricket::TransportInfo& info :
384 desc->description()->transport_infos()) {
385 ufrags.push_back(info.description.ice_ufrag);
386 }
387 return ufrags;
388}
389
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000390void SetSsrcToZero(std::string* sdp) {
391 const char kSdpSsrcAtribute[] = "a=ssrc:";
392 const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
393 size_t ssrc_pos = 0;
394 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
395 std::string::npos) {
396 size_t end_ssrc = sdp->find(" ", ssrc_pos);
397 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
398 ssrc_pos = end_ssrc;
399 }
400}
401
deadbeefab9b2d12015-10-14 11:33:11 -0700402// Check if |streams| contains the specified track.
403bool ContainsTrack(const std::vector<cricket::StreamParams>& streams,
404 const std::string& stream_label,
405 const std::string& track_id) {
406 for (const cricket::StreamParams& params : streams) {
407 if (params.sync_label == stream_label && params.id == track_id) {
408 return true;
409 }
410 }
411 return false;
412}
413
414// Check if |senders| contains the specified sender, by id.
415bool ContainsSender(
416 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
417 const std::string& id) {
418 for (const auto& sender : senders) {
419 if (sender->id() == id) {
420 return true;
421 }
422 }
423 return false;
424}
425
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700426// Check if |senders| contains the specified sender, by id and stream id.
427bool ContainsSender(
428 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
429 const std::string& id,
430 const std::string& stream_id) {
431 for (const auto& sender : senders) {
deadbeefa601f5c2016-06-06 14:27:39 -0700432 if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700433 return true;
434 }
435 }
436 return false;
437}
438
deadbeefab9b2d12015-10-14 11:33:11 -0700439// Create a collection of streams.
440// CreateStreamCollection(1) creates a collection that
441// correspond to kSdpStringWithStream1.
442// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
443rtc::scoped_refptr<StreamCollection> CreateStreamCollection(
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700444 int number_of_streams,
445 int tracks_per_stream) {
deadbeefab9b2d12015-10-14 11:33:11 -0700446 rtc::scoped_refptr<StreamCollection> local_collection(
447 StreamCollection::Create());
448
449 for (int i = 0; i < number_of_streams; ++i) {
450 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
451 webrtc::MediaStream::Create(kStreams[i]));
452
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700453 for (int j = 0; j < tracks_per_stream; ++j) {
454 // Add a local audio track.
455 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
456 webrtc::AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j],
457 nullptr));
458 stream->AddTrack(audio_track);
deadbeefab9b2d12015-10-14 11:33:11 -0700459
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700460 // Add a local video track.
461 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
462 webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
mbonadei539d1042017-07-10 02:40:49 -0700463 webrtc::FakeVideoTrackSource::Create()));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700464 stream->AddTrack(video_track);
465 }
deadbeefab9b2d12015-10-14 11:33:11 -0700466
467 local_collection->AddStream(stream);
468 }
469 return local_collection;
470}
471
472// Check equality of StreamCollections.
473bool CompareStreamCollections(StreamCollectionInterface* s1,
474 StreamCollectionInterface* s2) {
475 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
476 return false;
477 }
478
479 for (size_t i = 0; i != s1->count(); ++i) {
480 if (s1->at(i)->label() != s2->at(i)->label()) {
481 return false;
482 }
483 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
484 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
485 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
486 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
487
488 if (audio_tracks1.size() != audio_tracks2.size()) {
489 return false;
490 }
491 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
492 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
493 return false;
494 }
495 }
496 if (video_tracks1.size() != video_tracks2.size()) {
497 return false;
498 }
499 for (size_t j = 0; j != video_tracks1.size(); ++j) {
500 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
501 return false;
502 }
503 }
504 }
505 return true;
506}
507
perkjd61bf802016-03-24 03:16:19 -0700508// Helper class to test Observer.
509class MockTrackObserver : public ObserverInterface {
510 public:
511 explicit MockTrackObserver(NotifierInterface* notifier)
512 : notifier_(notifier) {
513 notifier_->RegisterObserver(this);
514 }
515
516 ~MockTrackObserver() { Unregister(); }
517
518 void Unregister() {
519 if (notifier_) {
520 notifier_->UnregisterObserver(this);
521 notifier_ = nullptr;
522 }
523 }
524
525 MOCK_METHOD0(OnChanged, void());
526
527 private:
528 NotifierInterface* notifier_;
529};
530
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531class MockPeerConnectionObserver : public PeerConnectionObserver {
532 public:
deadbeefab9b2d12015-10-14 11:33:11 -0700533 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {}
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200534 virtual ~MockPeerConnectionObserver() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000535 }
536 void SetPeerConnectionInterface(PeerConnectionInterface* pc) {
537 pc_ = pc;
538 if (pc) {
539 state_ = pc_->signaling_state();
540 }
541 }
nisseef8b61e2016-04-29 06:09:15 -0700542 void OnSignalingChange(
543 PeerConnectionInterface::SignalingState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 EXPECT_EQ(pc_->signaling_state(), new_state);
545 state_ = new_state;
546 }
deadbeefab9b2d12015-10-14 11:33:11 -0700547
548 MediaStreamInterface* RemoteStream(const std::string& label) {
549 return remote_streams_->find(label);
550 }
551 StreamCollectionInterface* remote_streams() const { return remote_streams_; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700552 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000553 last_added_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700554 remote_streams_->AddStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700556 void OnRemoveStream(
557 rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000558 last_removed_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700559 remote_streams_->RemoveStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 }
perkjdfb769d2016-02-09 03:09:43 -0800561 void OnRenegotiationNeeded() override { renegotiation_needed_ = true; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700562 void OnDataChannel(
563 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 last_datachannel_ = data_channel;
565 }
566
perkjdfb769d2016-02-09 03:09:43 -0800567 void OnIceConnectionChange(
568 PeerConnectionInterface::IceConnectionState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569 EXPECT_EQ(pc_->ice_connection_state(), new_state);
zhihuang81c3a032016-11-17 12:06:24 -0800570 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 }
perkjdfb769d2016-02-09 03:09:43 -0800572 void OnIceGatheringChange(
573 PeerConnectionInterface::IceGatheringState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574 EXPECT_EQ(pc_->ice_gathering_state(), new_state);
perkjdfb769d2016-02-09 03:09:43 -0800575 ice_complete_ = new_state == PeerConnectionInterface::kIceGatheringComplete;
zhihuang81c3a032016-11-17 12:06:24 -0800576 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 }
perkjdfb769d2016-02-09 03:09:43 -0800578 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew,
580 pc_->ice_gathering_state());
581
582 std::string sdp;
583 EXPECT_TRUE(candidate->ToString(&sdp));
584 EXPECT_LT(0u, sdp.size());
585 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(),
586 candidate->sdp_mline_index(), sdp, NULL));
587 EXPECT_TRUE(last_candidate_.get() != NULL);
zhihuang81c3a032016-11-17 12:06:24 -0800588 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700589 }
590
591 void OnIceCandidatesRemoved(
592 const std::vector<cricket::Candidate>& candidates) override {
zhihuang81c3a032016-11-17 12:06:24 -0800593 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700594 }
595
596 void OnIceConnectionReceivingChange(bool receiving) override {
zhihuang81c3a032016-11-17 12:06:24 -0800597 callback_triggered_ = true;
598 }
599
zhihuangc63b8942016-12-02 15:41:10 -0800600 void OnAddTrack(
601 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
602 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
603 streams) override {
zhihuang81c3a032016-11-17 12:06:24 -0800604 EXPECT_TRUE(receiver != nullptr);
605 num_added_tracks_++;
606 last_added_track_label_ = receiver->id();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000607 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608
609 // Returns the label of the last added stream.
610 // Empty string if no stream have been added.
611 std::string GetLastAddedStreamLabel() {
612 if (last_added_stream_.get())
613 return last_added_stream_->label();
614 return "";
615 }
616 std::string GetLastRemovedStreamLabel() {
617 if (last_removed_stream_.get())
618 return last_removed_stream_->label();
619 return "";
620 }
621
zhihuang9763d562016-08-05 11:14:50 -0700622 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 PeerConnectionInterface::SignalingState state_;
kwibergd1fe2812016-04-27 06:47:29 -0700624 std::unique_ptr<IceCandidateInterface> last_candidate_;
zhihuang9763d562016-08-05 11:14:50 -0700625 rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
deadbeefab9b2d12015-10-14 11:33:11 -0700626 rtc::scoped_refptr<StreamCollection> remote_streams_;
627 bool renegotiation_needed_ = false;
628 bool ice_complete_ = false;
zhihuang81c3a032016-11-17 12:06:24 -0800629 bool callback_triggered_ = false;
630 int num_added_tracks_ = 0;
631 std::string last_added_track_label_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632
633 private:
zhihuang9763d562016-08-05 11:14:50 -0700634 rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
635 rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636};
637
638} // namespace
deadbeefab9b2d12015-10-14 11:33:11 -0700639
nisse528b7932017-05-08 03:21:43 -0700640// The PeerConnectionMediaConfig tests below verify that configuration and
641// constraints are propagated into the PeerConnection's MediaConfig. These
642// settings are intended for MediaChannel constructors, but that is not
643// exercised by these unittest.
zhihuang29ff8442016-07-27 11:07:25 -0700644class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
645 public:
zhihuang38ede132017-06-15 12:52:32 -0700646 static rtc::scoped_refptr<PeerConnectionFactoryForTest>
647 CreatePeerConnectionFactoryForTest() {
648 auto audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
649 auto audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
650
651 auto media_engine = std::unique_ptr<cricket::MediaEngineInterface>(
652 cricket::WebRtcMediaEngineFactory::Create(
653 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr,
peaha9cc40b2017-06-29 08:32:09 -0700654 nullptr, nullptr, webrtc::AudioProcessing::Create()));
zhihuang38ede132017-06-15 12:52:32 -0700655
656 std::unique_ptr<webrtc::CallFactoryInterface> call_factory =
657 webrtc::CreateCallFactory();
658
659 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory =
660 webrtc::CreateRtcEventLogFactory();
661
662 return new rtc::RefCountedObject<PeerConnectionFactoryForTest>(
663 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
664 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr, nullptr,
665 nullptr, std::move(media_engine), std::move(call_factory),
666 std::move(event_log_factory));
667 }
668
669 PeerConnectionFactoryForTest(
670 rtc::Thread* network_thread,
671 rtc::Thread* worker_thread,
672 rtc::Thread* signaling_thread,
673 webrtc::AudioDeviceModule* default_adm,
674 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
675 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
676 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
677 cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
678 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
679 std::unique_ptr<cricket::MediaEngineInterface> media_engine,
680 std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
681 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory)
682 : webrtc::PeerConnectionFactory(network_thread,
683 worker_thread,
684 signaling_thread,
685 default_adm,
686 audio_encoder_factory,
687 audio_decoder_factory,
688 video_encoder_factory,
689 video_decoder_factory,
690 audio_mixer,
691 std::move(media_engine),
692 std::move(call_factory),
693 std::move(event_log_factory)) {}
kwiberg1e4e8cb2017-01-31 01:48:08 -0800694
zhihuang29ff8442016-07-27 11:07:25 -0700695 cricket::TransportController* CreateTransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700696 cricket::PortAllocator* port_allocator,
697 bool redetermine_role_on_ice_restart) override {
zhihuang29ff8442016-07-27 11:07:25 -0700698 transport_controller = new cricket::TransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700699 rtc::Thread::Current(), rtc::Thread::Current(), port_allocator,
deadbeef7914b8c2017-04-21 03:23:33 -0700700 redetermine_role_on_ice_restart, rtc::CryptoOptions());
zhihuang29ff8442016-07-27 11:07:25 -0700701 return transport_controller;
702 }
703
704 cricket::TransportController* transport_controller;
zhihuang29ff8442016-07-27 11:07:25 -0700705};
706
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707class PeerConnectionInterfaceTest : public testing::Test {
708 protected:
deadbeef9a6f4d42017-05-15 19:43:33 -0700709 PeerConnectionInterfaceTest()
deadbeef98e186c2017-05-16 18:00:06 -0700710 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
phoglund37ebcf02016-01-08 05:04:57 -0800711#ifdef WEBRTC_ANDROID
712 webrtc::InitializeAndroidObjects();
713#endif
714 }
715
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716 virtual void SetUp() {
717 pc_factory_ = webrtc::CreatePeerConnectionFactory(
danilchape9021a32016-05-17 01:52:02 -0700718 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
719 nullptr, nullptr, nullptr);
720 ASSERT_TRUE(pc_factory_);
zhihuang29ff8442016-07-27 11:07:25 -0700721 pc_factory_for_test_ =
zhihuang38ede132017-06-15 12:52:32 -0700722 PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
zhihuang29ff8442016-07-27 11:07:25 -0700723 pc_factory_for_test_->Initialize();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 }
725
726 void CreatePeerConnection() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700727 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(), nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 }
729
deadbeef293e9262017-01-11 12:28:30 -0800730 // DTLS does not work in a loopback call, so is disabled for most of the
731 // tests in this file.
732 void CreatePeerConnectionWithoutDtls() {
733 FakeConstraints no_dtls_constraints;
734 no_dtls_constraints.AddMandatory(
735 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
736
737 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
738 &no_dtls_constraints);
739 }
740
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700742 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
743 constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744 }
745
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700746 void CreatePeerConnectionWithIceTransportsType(
747 PeerConnectionInterface::IceTransportsType type) {
748 PeerConnectionInterface::RTCConfiguration config;
749 config.type = type;
750 return CreatePeerConnection(config, nullptr);
751 }
752
753 void CreatePeerConnectionWithIceServer(const std::string& uri,
754 const std::string& password) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800755 PeerConnectionInterface::RTCConfiguration config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000756 PeerConnectionInterface::IceServer server;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700757 server.uri = uri;
758 server.password = password;
759 config.servers.push_back(server);
760 CreatePeerConnection(config, nullptr);
761 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700763 void CreatePeerConnection(PeerConnectionInterface::RTCConfiguration config,
764 webrtc::MediaConstraintsInterface* constraints) {
kwibergd1fe2812016-04-27 06:47:29 -0700765 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800766 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
767 port_allocator_ = port_allocator.get();
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000768
deadbeef1dcb1642017-03-29 21:08:16 -0700769 // Create certificate generator unless DTLS constraint is explicitly set to
770 // false.
Henrik Boströmd79599d2016-06-01 13:58:50 +0200771 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000772 bool dtls;
773 if (FindConstraint(constraints,
774 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
775 &dtls,
Henrik Boström5e56c592015-08-11 10:33:13 +0200776 nullptr) && dtls) {
deadbeef8662f942017-01-20 21:20:51 -0800777 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
778 cert_generator.reset(fake_certificate_generator_);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000779 }
Henrik Boströmd79599d2016-06-01 13:58:50 +0200780 pc_ = pc_factory_->CreatePeerConnection(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800781 config, constraints, std::move(port_allocator),
Henrik Boströmd79599d2016-06-01 13:58:50 +0200782 std::move(cert_generator), &observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 ASSERT_TRUE(pc_.get() != NULL);
784 observer_.SetPeerConnectionInterface(pc_.get());
785 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
786 }
787
deadbeef0a6c4ca2015-10-06 11:38:28 -0700788 void CreatePeerConnectionExpectFail(const std::string& uri) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800789 PeerConnectionInterface::RTCConfiguration config;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700790 PeerConnectionInterface::IceServer server;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700791 server.uri = uri;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800792 config.servers.push_back(server);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700793
zhihuang9763d562016-08-05 11:14:50 -0700794 rtc::scoped_refptr<PeerConnectionInterface> pc;
hbosd7973cc2016-05-27 06:08:53 -0700795 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr,
796 &observer_);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800797 EXPECT_EQ(nullptr, pc);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700798 }
799
Steve Anton038834f2017-07-14 15:59:59 -0700800 void CreatePeerConnectionExpectFail(
801 PeerConnectionInterface::RTCConfiguration config) {
802 PeerConnectionInterface::IceServer server;
803 server.uri = kTurnIceServerUri;
804 server.password = kTurnPassword;
805 config.servers.push_back(server);
806 rtc::scoped_refptr<PeerConnectionInterface> pc =
807 pc_factory_->CreatePeerConnection(config, nullptr, nullptr, &observer_);
808 EXPECT_EQ(nullptr, pc);
809 }
810
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811 void CreatePeerConnectionWithDifferentConfigurations() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700812 CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800813 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
814 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
815 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 EXPECT_EQ(kDefaultStunPort,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800817 port_allocator_->stun_servers().begin()->port());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818
deadbeef0a6c4ca2015-10-06 11:38:28 -0700819 CreatePeerConnectionExpectFail(kStunInvalidPort);
820 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
821 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700823 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800824 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
825 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826 EXPECT_EQ(kTurnUsername,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800827 port_allocator_->turn_servers()[0].credentials.username);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 EXPECT_EQ(kTurnPassword,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800829 port_allocator_->turn_servers()[0].credentials.password);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 EXPECT_EQ(kTurnHostname,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800831 port_allocator_->turn_servers()[0].ports[0].address.hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832 }
833
834 void ReleasePeerConnection() {
835 pc_ = NULL;
836 observer_.SetPeerConnectionInterface(NULL);
837 }
838
deadbeefab9b2d12015-10-14 11:33:11 -0700839 void AddVideoStream(const std::string& label) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700841 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700843 rtc::scoped_refptr<VideoTrackSourceInterface> video_source(
deadbeef112b2e92017-02-10 20:13:37 -0800844 pc_factory_->CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(
845 new cricket::FakeVideoCapturer()),
846 NULL));
zhihuang9763d562016-08-05 11:14:50 -0700847 rtc::scoped_refptr<VideoTrackInterface> video_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 pc_factory_->CreateVideoTrack(label + "v0", video_source));
849 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000850 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
852 observer_.renegotiation_needed_ = false;
853 }
854
855 void AddVoiceStream(const std::string& label) {
856 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700857 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700859 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860 pc_factory_->CreateAudioTrack(label + "a0", NULL));
861 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000862 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
864 observer_.renegotiation_needed_ = false;
865 }
866
867 void AddAudioVideoStream(const std::string& stream_label,
868 const std::string& audio_track_label,
869 const std::string& video_track_label) {
870 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700871 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 pc_factory_->CreateLocalMediaStream(stream_label));
zhihuang9763d562016-08-05 11:14:50 -0700873 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874 pc_factory_->CreateAudioTrack(
875 audio_track_label, static_cast<AudioSourceInterface*>(NULL)));
876 stream->AddTrack(audio_track.get());
zhihuang9763d562016-08-05 11:14:50 -0700877 rtc::scoped_refptr<VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -0700878 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -0800879 video_track_label, pc_factory_->CreateVideoSource(
880 std::unique_ptr<cricket::VideoCapturer>(
881 new cricket::FakeVideoCapturer()))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000883 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
885 observer_.renegotiation_needed_ = false;
886 }
887
kwibergd1fe2812016-04-27 06:47:29 -0700888 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700889 bool offer,
890 MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000891 rtc::scoped_refptr<MockCreateSessionDescriptionObserver>
892 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893 MockCreateSessionDescriptionObserver>());
894 if (offer) {
deadbeefc80741f2015-10-22 13:14:45 -0700895 pc_->CreateOffer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 } else {
deadbeefc80741f2015-10-22 13:14:45 -0700897 pc_->CreateAnswer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898 }
899 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700900 *desc = observer->MoveDescription();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000901 return observer->result();
902 }
903
kwibergd1fe2812016-04-27 06:47:29 -0700904 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700905 MediaConstraintsInterface* constraints) {
906 return DoCreateOfferAnswer(desc, true, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907 }
908
kwibergd1fe2812016-04-27 06:47:29 -0700909 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700910 MediaConstraintsInterface* constraints) {
911 return DoCreateOfferAnswer(desc, false, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912 }
913
914 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000915 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
916 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917 MockSetSessionDescriptionObserver>());
918 if (local) {
919 pc_->SetLocalDescription(observer, desc);
920 } else {
921 pc_->SetRemoteDescription(observer, desc);
922 }
zhihuang29ff8442016-07-27 11:07:25 -0700923 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
924 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
925 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926 return observer->result();
927 }
928
929 bool DoSetLocalDescription(SessionDescriptionInterface* desc) {
930 return DoSetSessionDescription(desc, true);
931 }
932
933 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) {
934 return DoSetSessionDescription(desc, false);
935 }
936
937 // Calls PeerConnection::GetStats and check the return value.
938 // It does not verify the values in the StatReports since a RTCP packet might
939 // be required.
940 bool DoGetStats(MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000941 rtc::scoped_refptr<MockStatsObserver> observer(
942 new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000943 if (!pc_->GetStats(
944 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard))
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 return false;
946 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
947 return observer->called();
948 }
949
950 void InitiateCall() {
deadbeef293e9262017-01-11 12:28:30 -0800951 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000952 // Create a local stream with audio&video tracks.
953 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
954 CreateOfferReceiveAnswer();
955 }
956
957 // Verify that RTP Header extensions has been negotiated for audio and video.
958 void VerifyRemoteRtpHeaderExtensions() {
959 const cricket::MediaContentDescription* desc =
960 cricket::GetFirstAudioContentDescription(
961 pc_->remote_description()->description());
962 ASSERT_TRUE(desc != NULL);
963 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
964
965 desc = cricket::GetFirstVideoContentDescription(
966 pc_->remote_description()->description());
967 ASSERT_TRUE(desc != NULL);
968 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
969 }
970
971 void CreateOfferAsRemoteDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700972 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -0700973 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000974 std::string sdp;
975 EXPECT_TRUE(offer->ToString(&sdp));
976 SessionDescriptionInterface* remote_offer =
977 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
978 sdp, NULL);
979 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
980 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
981 }
982
deadbeefab9b2d12015-10-14 11:33:11 -0700983 void CreateAndSetRemoteOffer(const std::string& sdp) {
984 SessionDescriptionInterface* remote_offer =
985 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
986 sdp, nullptr);
987 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
988 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
989 }
990
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991 void CreateAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700992 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -0700993 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000994
995 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
996 // audio codec change, even if the parameter has nothing to do with
997 // receiving. Not all parameters are serialized to SDP.
998 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
999 // the SessionDescription, it is necessary to do that here to in order to
1000 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1001 // https://code.google.com/p/webrtc/issues/detail?id=1356
1002 std::string sdp;
1003 EXPECT_TRUE(answer->ToString(&sdp));
1004 SessionDescriptionInterface* new_answer =
1005 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
1006 sdp, NULL);
1007 EXPECT_TRUE(DoSetLocalDescription(new_answer));
1008 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1009 }
1010
1011 void CreatePrAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001012 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001013 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014
1015 std::string sdp;
1016 EXPECT_TRUE(answer->ToString(&sdp));
1017 SessionDescriptionInterface* pr_answer =
1018 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
1019 sdp, NULL);
1020 EXPECT_TRUE(DoSetLocalDescription(pr_answer));
1021 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
1022 }
1023
1024 void CreateOfferReceiveAnswer() {
1025 CreateOfferAsLocalDescription();
1026 std::string sdp;
1027 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1028 CreateAnswerAsRemoteDescription(sdp);
1029 }
1030
1031 void CreateOfferAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001032 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001033 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1035 // audio codec change, even if the parameter has nothing to do with
1036 // receiving. Not all parameters are serialized to SDP.
1037 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1038 // the SessionDescription, it is necessary to do that here to in order to
1039 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1040 // https://code.google.com/p/webrtc/issues/detail?id=1356
1041 std::string sdp;
1042 EXPECT_TRUE(offer->ToString(&sdp));
1043 SessionDescriptionInterface* new_offer =
1044 webrtc::CreateSessionDescription(
1045 SessionDescriptionInterface::kOffer,
1046 sdp, NULL);
1047
1048 EXPECT_TRUE(DoSetLocalDescription(new_offer));
1049 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
mallinath@webrtc.org68cbd012014-01-22 00:16:46 +00001050 // Wait for the ice_complete message, so that SDP will have candidates.
1051 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001052 }
1053
deadbeefab9b2d12015-10-14 11:33:11 -07001054 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001055 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
1056 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001057 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001058 EXPECT_TRUE(DoSetRemoteDescription(answer));
1059 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1060 }
1061
deadbeefab9b2d12015-10-14 11:33:11 -07001062 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063 webrtc::JsepSessionDescription* pr_answer =
1064 new webrtc::JsepSessionDescription(
1065 SessionDescriptionInterface::kPrAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001066 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067 EXPECT_TRUE(DoSetRemoteDescription(pr_answer));
1068 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
1069 webrtc::JsepSessionDescription* answer =
1070 new webrtc::JsepSessionDescription(
1071 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001072 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073 EXPECT_TRUE(DoSetRemoteDescription(answer));
1074 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1075 }
1076
1077 // Help function used for waiting until a the last signaled remote stream has
1078 // the same label as |stream_label|. In a few of the tests in this file we
1079 // answer with the same session description as we offer and thus we can
1080 // check if OnAddStream have been called with the same stream as we offer to
1081 // send.
1082 void WaitAndVerifyOnAddStream(const std::string& stream_label) {
1083 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout);
1084 }
1085
1086 // Creates an offer and applies it as a local session description.
1087 // Creates an answer with the same SDP an the offer but removes all lines
1088 // that start with a:ssrc"
1089 void CreateOfferReceiveAnswerWithoutSsrc() {
1090 CreateOfferAsLocalDescription();
1091 std::string sdp;
1092 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1093 SetSsrcToZero(&sdp);
1094 CreateAnswerAsRemoteDescription(sdp);
1095 }
1096
deadbeefab9b2d12015-10-14 11:33:11 -07001097 // This function creates a MediaStream with label kStreams[0] and
1098 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
1099 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
kwiberg2bbff992016-03-16 11:03:04 -07001100 // is returned and the MediaStream is stored in
deadbeefab9b2d12015-10-14 11:33:11 -07001101 // |reference_collection_|
kwibergd1fe2812016-04-27 06:47:29 -07001102 std::unique_ptr<SessionDescriptionInterface>
kwiberg2bbff992016-03-16 11:03:04 -07001103 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1104 size_t number_of_video_tracks) {
1105 EXPECT_LE(number_of_audio_tracks, 2u);
1106 EXPECT_LE(number_of_video_tracks, 2u);
deadbeefab9b2d12015-10-14 11:33:11 -07001107
1108 reference_collection_ = StreamCollection::Create();
1109 std::string sdp_ms1 = std::string(kSdpStringInit);
1110
1111 std::string mediastream_label = kStreams[0];
1112
1113 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
1114 webrtc::MediaStream::Create(mediastream_label));
1115 reference_collection_->AddStream(stream);
1116
1117 if (number_of_audio_tracks > 0) {
1118 sdp_ms1 += std::string(kSdpStringAudio);
1119 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1120 AddAudioTrack(kAudioTracks[0], stream);
1121 }
1122 if (number_of_audio_tracks > 1) {
1123 sdp_ms1 += kSdpStringMs1Audio1;
1124 AddAudioTrack(kAudioTracks[1], stream);
1125 }
1126
1127 if (number_of_video_tracks > 0) {
1128 sdp_ms1 += std::string(kSdpStringVideo);
1129 sdp_ms1 += std::string(kSdpStringMs1Video0);
1130 AddVideoTrack(kVideoTracks[0], stream);
1131 }
1132 if (number_of_video_tracks > 1) {
1133 sdp_ms1 += kSdpStringMs1Video1;
1134 AddVideoTrack(kVideoTracks[1], stream);
1135 }
1136
kwibergd1fe2812016-04-27 06:47:29 -07001137 return std::unique_ptr<SessionDescriptionInterface>(
kwiberg2bbff992016-03-16 11:03:04 -07001138 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1139 sdp_ms1, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001140 }
1141
1142 void AddAudioTrack(const std::string& track_id,
1143 MediaStreamInterface* stream) {
1144 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1145 webrtc::AudioTrack::Create(track_id, nullptr));
1146 ASSERT_TRUE(stream->AddTrack(audio_track));
1147 }
1148
1149 void AddVideoTrack(const std::string& track_id,
1150 MediaStreamInterface* stream) {
1151 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -07001152 webrtc::VideoTrack::Create(track_id,
mbonadei539d1042017-07-10 02:40:49 -07001153 webrtc::FakeVideoTrackSource::Create()));
deadbeefab9b2d12015-10-14 11:33:11 -07001154 ASSERT_TRUE(stream->AddTrack(video_track));
1155 }
1156
kwibergfd8be342016-05-14 19:44:11 -07001157 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
deadbeef293e9262017-01-11 12:28:30 -08001158 CreatePeerConnectionWithoutDtls();
zhihuang8f65cdf2016-05-06 18:40:30 -07001159 AddVoiceStream(kStreamLabel1);
kwibergfd8be342016-05-14 19:44:11 -07001160 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001161 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1162 return offer;
1163 }
1164
kwibergfd8be342016-05-14 19:44:11 -07001165 std::unique_ptr<SessionDescriptionInterface>
zhihuang8f65cdf2016-05-06 18:40:30 -07001166 CreateAnswerWithOneAudioStream() {
kwibergfd8be342016-05-14 19:44:11 -07001167 std::unique_ptr<SessionDescriptionInterface> offer =
zhihuang8f65cdf2016-05-06 18:40:30 -07001168 CreateOfferWithOneAudioStream();
1169 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergfd8be342016-05-14 19:44:11 -07001170 std::unique_ptr<SessionDescriptionInterface> answer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001171 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1172 return answer;
1173 }
1174
1175 const std::string& GetFirstAudioStreamCname(
1176 const SessionDescriptionInterface* desc) {
1177 const cricket::ContentInfo* audio_content =
1178 cricket::GetFirstAudioContent(desc->description());
1179 const cricket::AudioContentDescription* audio_desc =
1180 static_cast<const cricket::AudioContentDescription*>(
1181 audio_content->description);
1182 return audio_desc->streams()[0].cname;
1183 }
1184
deadbeef9a6f4d42017-05-15 19:43:33 -07001185 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1186 rtc::AutoSocketServerThread main_;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08001187 cricket::FakePortAllocator* port_allocator_ = nullptr;
deadbeef8662f942017-01-20 21:20:51 -08001188 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
zhihuang9763d562016-08-05 11:14:50 -07001189 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1190 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_;
1191 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192 MockPeerConnectionObserver observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001193 rtc::scoped_refptr<StreamCollection> reference_collection_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001194};
1195
zhihuang29ff8442016-07-27 11:07:25 -07001196// Test that no callbacks on the PeerConnectionObserver are called after the
1197// PeerConnection is closed.
1198TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) {
zhihuang9763d562016-08-05 11:14:50 -07001199 rtc::scoped_refptr<PeerConnectionInterface> pc(
zhihuang29ff8442016-07-27 11:07:25 -07001200 pc_factory_for_test_->CreatePeerConnection(
1201 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr,
1202 nullptr, &observer_));
1203 observer_.SetPeerConnectionInterface(pc.get());
1204 pc->Close();
1205
1206 // No callbacks is expected to be called.
zhihuang81c3a032016-11-17 12:06:24 -08001207 observer_.callback_triggered_ = false;
zhihuang29ff8442016-07-27 11:07:25 -07001208 std::vector<cricket::Candidate> candidates;
1209 pc_factory_for_test_->transport_controller->SignalGatheringState(
1210 cricket::IceGatheringState{});
1211 pc_factory_for_test_->transport_controller->SignalCandidatesGathered(
1212 "", candidates);
1213 pc_factory_for_test_->transport_controller->SignalConnectionState(
1214 cricket::IceConnectionState{});
1215 pc_factory_for_test_->transport_controller->SignalCandidatesRemoved(
1216 candidates);
1217 pc_factory_for_test_->transport_controller->SignalReceiving(false);
zhihuang81c3a032016-11-17 12:06:24 -08001218 EXPECT_FALSE(observer_.callback_triggered_);
zhihuang29ff8442016-07-27 11:07:25 -07001219}
1220
zhihuang8f65cdf2016-05-06 18:40:30 -07001221// Generate different CNAMEs when PeerConnections are created.
1222// The CNAMEs are expected to be generated randomly. It is possible
1223// that the test fails, though the possibility is very low.
1224TEST_F(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
kwibergfd8be342016-05-14 19:44:11 -07001225 std::unique_ptr<SessionDescriptionInterface> offer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001226 CreateOfferWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001227 std::unique_ptr<SessionDescriptionInterface> offer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001228 CreateOfferWithOneAudioStream();
1229 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1230 GetFirstAudioStreamCname(offer2.get()));
1231}
1232
1233TEST_F(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
kwibergfd8be342016-05-14 19:44:11 -07001234 std::unique_ptr<SessionDescriptionInterface> answer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001235 CreateAnswerWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001236 std::unique_ptr<SessionDescriptionInterface> answer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001237 CreateAnswerWithOneAudioStream();
1238 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1239 GetFirstAudioStreamCname(answer2.get()));
1240}
1241
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242TEST_F(PeerConnectionInterfaceTest,
1243 CreatePeerConnectionWithDifferentConfigurations) {
1244 CreatePeerConnectionWithDifferentConfigurations();
1245}
1246
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001247TEST_F(PeerConnectionInterfaceTest,
1248 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1249 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1250 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1251 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1252 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1253 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1254 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1255 port_allocator_->candidate_filter());
1256 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1257 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1258}
1259
1260// Test that when a PeerConnection is created with a nonzero candidate pool
1261// size, the pooled PortAllocatorSession is created with all the attributes
1262// in the RTCConfiguration.
1263TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
1264 PeerConnectionInterface::RTCConfiguration config;
1265 PeerConnectionInterface::IceServer server;
1266 server.uri = kStunAddressOnly;
1267 config.servers.push_back(server);
1268 config.type = PeerConnectionInterface::kRelay;
1269 config.disable_ipv6 = true;
1270 config.tcp_candidate_policy =
1271 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
honghaiz60347052016-05-31 18:29:12 -07001272 config.candidate_network_policy =
1273 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001274 config.ice_candidate_pool_size = 1;
1275 CreatePeerConnection(config, nullptr);
1276
1277 const cricket::FakePortAllocatorSession* session =
1278 static_cast<const cricket::FakePortAllocatorSession*>(
1279 port_allocator_->GetPooledSession());
1280 ASSERT_NE(nullptr, session);
1281 EXPECT_EQ(1UL, session->stun_servers().size());
1282 EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
1283 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
honghaiz60347052016-05-31 18:29:12 -07001284 EXPECT_LT(0U,
1285 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001286}
1287
deadbeefd21eab32017-07-26 16:50:11 -07001288// Test that network-related RTCConfiguration members are applied to the
1289// PortAllocator when CreatePeerConnection is called. Specifically:
1290// - disable_ipv6_on_wifi
1291// - max_ipv6_networks
1292// - tcp_candidate_policy
1293// - candidate_network_policy
1294// - prune_turn_ports
1295//
1296// Note that the candidate filter (RTCConfiguration::type) is already tested
1297// above.
1298TEST_F(PeerConnectionInterfaceTest,
1299 CreatePeerConnectionAppliesNetworkConfigToPortAllocator) {
1300 // Create fake port allocator.
1301 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1302 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
1303 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1304
1305 // Create RTCConfiguration with some network-related fields relevant to
1306 // PortAllocator populated.
1307 PeerConnectionInterface::RTCConfiguration config;
1308 config.disable_ipv6_on_wifi = true;
1309 config.max_ipv6_networks = 10;
1310 config.tcp_candidate_policy =
1311 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
1312 config.candidate_network_policy =
1313 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
1314 config.prune_turn_ports = true;
1315
1316 // Create the PC factory and PC with the above config.
1317 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1318 webrtc::CreatePeerConnectionFactory(
1319 rtc::Thread::Current(), rtc::Thread::Current(),
1320 rtc::Thread::Current(), nullptr, nullptr, nullptr));
1321 rtc::scoped_refptr<PeerConnectionInterface> pc(
1322 pc_factory->CreatePeerConnection(
1323 config, nullptr, std::move(port_allocator), nullptr, &observer_));
1324
1325 // Now validate that the config fields set above were applied to the
1326 // PortAllocator, as flags or otherwise.
1327 EXPECT_FALSE(raw_port_allocator->flags() &
1328 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1329 EXPECT_EQ(10, raw_port_allocator->max_ipv6_networks());
1330 EXPECT_TRUE(raw_port_allocator->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
1331 EXPECT_TRUE(raw_port_allocator->flags() &
1332 cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
1333 EXPECT_TRUE(raw_port_allocator->prune_turn_ports());
1334}
1335
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001336// Test that the PeerConnection initializes the port allocator passed into it,
1337// and on the correct thread.
1338TEST_F(PeerConnectionInterfaceTest,
deadbeefd21eab32017-07-26 16:50:11 -07001339 CreatePeerConnectionInitializesPortAllocatorOnNetworkThread) {
tommie7251592017-07-14 14:44:46 -07001340 std::unique_ptr<rtc::Thread> network_thread(
1341 rtc::Thread::CreateWithSocketServer());
1342 network_thread->Start();
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001343 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1344 webrtc::CreatePeerConnectionFactory(
tommie7251592017-07-14 14:44:46 -07001345 network_thread.get(), rtc::Thread::Current(), rtc::Thread::Current(),
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001346 nullptr, nullptr, nullptr));
1347 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
tommie7251592017-07-14 14:44:46 -07001348 new cricket::FakePortAllocator(network_thread.get(), nullptr));
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001349 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1350 PeerConnectionInterface::RTCConfiguration config;
1351 rtc::scoped_refptr<PeerConnectionInterface> pc(
1352 pc_factory->CreatePeerConnection(
1353 config, nullptr, std::move(port_allocator), nullptr, &observer_));
1354 // FakePortAllocator RTC_CHECKs that it's initialized on the right thread,
1355 // so all we have to do here is check that it's initialized.
1356 EXPECT_TRUE(raw_port_allocator->initialized());
1357}
1358
deadbeef46c73892016-11-16 19:42:04 -08001359// Check that GetConfiguration returns the configuration the PeerConnection was
1360// constructed with, before SetConfiguration is called.
1361TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
1362 PeerConnectionInterface::RTCConfiguration config;
1363 config.type = PeerConnectionInterface::kRelay;
1364 CreatePeerConnection(config, nullptr);
1365
1366 PeerConnectionInterface::RTCConfiguration returned_config =
1367 pc_->GetConfiguration();
1368 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1369}
1370
1371// Check that GetConfiguration returns the last configuration passed into
1372// SetConfiguration.
1373TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
1374 CreatePeerConnection();
1375
1376 PeerConnectionInterface::RTCConfiguration config;
1377 config.type = PeerConnectionInterface::kRelay;
1378 EXPECT_TRUE(pc_->SetConfiguration(config));
1379
1380 PeerConnectionInterface::RTCConfiguration returned_config =
1381 pc_->GetConfiguration();
1382 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1383}
1384
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001385TEST_F(PeerConnectionInterfaceTest, AddStreams) {
deadbeef293e9262017-01-11 12:28:30 -08001386 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001387 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388 AddVoiceStream(kStreamLabel2);
1389 ASSERT_EQ(2u, pc_->local_streams()->count());
1390
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001391 // Test we can add multiple local streams to one peerconnection.
zhihuang9763d562016-08-05 11:14:50 -07001392 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393 pc_factory_->CreateLocalMediaStream(kStreamLabel3));
zhihuang9763d562016-08-05 11:14:50 -07001394 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1395 pc_factory_->CreateAudioTrack(kStreamLabel3,
1396 static_cast<AudioSourceInterface*>(NULL)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001397 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00001398 EXPECT_TRUE(pc_->AddStream(stream));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001399 EXPECT_EQ(3u, pc_->local_streams()->count());
1400
1401 // Remove the third stream.
1402 pc_->RemoveStream(pc_->local_streams()->at(2));
1403 EXPECT_EQ(2u, pc_->local_streams()->count());
1404
1405 // Remove the second stream.
1406 pc_->RemoveStream(pc_->local_streams()->at(1));
1407 EXPECT_EQ(1u, pc_->local_streams()->count());
1408
1409 // Remove the first stream.
1410 pc_->RemoveStream(pc_->local_streams()->at(0));
1411 EXPECT_EQ(0u, pc_->local_streams()->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412}
1413
deadbeefab9b2d12015-10-14 11:33:11 -07001414// Test that the created offer includes streams we added.
1415TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) {
deadbeef293e9262017-01-11 12:28:30 -08001416 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001417 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track");
kwibergd1fe2812016-04-27 06:47:29 -07001418 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001419 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001420
1421 const cricket::ContentInfo* audio_content =
1422 cricket::GetFirstAudioContent(offer->description());
1423 const cricket::AudioContentDescription* audio_desc =
1424 static_cast<const cricket::AudioContentDescription*>(
1425 audio_content->description);
1426 EXPECT_TRUE(
1427 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1428
1429 const cricket::ContentInfo* video_content =
1430 cricket::GetFirstVideoContent(offer->description());
1431 const cricket::VideoContentDescription* video_desc =
1432 static_cast<const cricket::VideoContentDescription*>(
1433 video_content->description);
1434 EXPECT_TRUE(
1435 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1436
1437 // Add another stream and ensure the offer includes both the old and new
1438 // streams.
1439 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2");
kwiberg2bbff992016-03-16 11:03:04 -07001440 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001441
1442 audio_content = cricket::GetFirstAudioContent(offer->description());
1443 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1444 audio_content->description);
1445 EXPECT_TRUE(
1446 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1447 EXPECT_TRUE(
1448 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2"));
1449
1450 video_content = cricket::GetFirstVideoContent(offer->description());
1451 video_desc = static_cast<const cricket::VideoContentDescription*>(
1452 video_content->description);
1453 EXPECT_TRUE(
1454 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1455 EXPECT_TRUE(
1456 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2"));
1457}
1458
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001459TEST_F(PeerConnectionInterfaceTest, RemoveStream) {
deadbeef293e9262017-01-11 12:28:30 -08001460 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001461 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462 ASSERT_EQ(1u, pc_->local_streams()->count());
1463 pc_->RemoveStream(pc_->local_streams()->at(0));
1464 EXPECT_EQ(0u, pc_->local_streams()->count());
1465}
1466
deadbeefe1f9d832016-01-14 15:35:42 -08001467// Test for AddTrack and RemoveTrack methods.
1468// Tests that the created offer includes tracks we added,
1469// and that the RtpSenders are created correctly.
1470// Also tests that RemoveTrack removes the tracks from subsequent offers.
1471TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) {
deadbeef293e9262017-01-11 12:28:30 -08001472 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001473 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001474 rtc::scoped_refptr<MediaStreamInterface> stream(
deadbeefe1f9d832016-01-14 15:35:42 -08001475 pc_factory_->CreateLocalMediaStream(kStreamLabel1));
1476 std::vector<MediaStreamInterface*> stream_list;
1477 stream_list.push_back(stream.get());
zhihuang9763d562016-08-05 11:14:50 -07001478 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001479 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001480 rtc::scoped_refptr<VideoTrackInterface> video_track(
1481 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001482 "video_track", pc_factory_->CreateVideoSource(
1483 std::unique_ptr<cricket::VideoCapturer>(
1484 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001485 auto audio_sender = pc_->AddTrack(audio_track, stream_list);
1486 auto video_sender = pc_->AddTrack(video_track, stream_list);
deadbeefa601f5c2016-06-06 14:27:39 -07001487 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1488 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001489 EXPECT_EQ("audio_track", audio_sender->id());
1490 EXPECT_EQ(audio_track, audio_sender->track());
deadbeefa601f5c2016-06-06 14:27:39 -07001491 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1492 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001493 EXPECT_EQ("video_track", video_sender->id());
1494 EXPECT_EQ(video_track, video_sender->track());
1495
1496 // Now create an offer and check for the senders.
kwibergd1fe2812016-04-27 06:47:29 -07001497 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001498 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001499
1500 const cricket::ContentInfo* audio_content =
1501 cricket::GetFirstAudioContent(offer->description());
1502 const cricket::AudioContentDescription* audio_desc =
1503 static_cast<const cricket::AudioContentDescription*>(
1504 audio_content->description);
1505 EXPECT_TRUE(
1506 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1507
1508 const cricket::ContentInfo* video_content =
1509 cricket::GetFirstVideoContent(offer->description());
1510 const cricket::VideoContentDescription* video_desc =
1511 static_cast<const cricket::VideoContentDescription*>(
1512 video_content->description);
1513 EXPECT_TRUE(
1514 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1515
1516 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1517
1518 // Now try removing the tracks.
1519 EXPECT_TRUE(pc_->RemoveTrack(audio_sender));
1520 EXPECT_TRUE(pc_->RemoveTrack(video_sender));
1521
1522 // Create a new offer and ensure it doesn't contain the removed senders.
kwiberg2bbff992016-03-16 11:03:04 -07001523 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001524
1525 audio_content = cricket::GetFirstAudioContent(offer->description());
1526 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1527 audio_content->description);
1528 EXPECT_FALSE(
1529 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1530
1531 video_content = cricket::GetFirstVideoContent(offer->description());
1532 video_desc = static_cast<const cricket::VideoContentDescription*>(
1533 video_content->description);
1534 EXPECT_FALSE(
1535 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1536
1537 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1538
1539 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1540 // should return false.
1541 EXPECT_FALSE(pc_->RemoveTrack(audio_sender));
1542 EXPECT_FALSE(pc_->RemoveTrack(video_sender));
1543}
1544
1545// Test creating senders without a stream specified,
1546// expecting a random stream ID to be generated.
1547TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
deadbeef293e9262017-01-11 12:28:30 -08001548 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001549 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001550 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001551 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001552 rtc::scoped_refptr<VideoTrackInterface> video_track(
1553 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001554 "video_track", pc_factory_->CreateVideoSource(
1555 std::unique_ptr<cricket::VideoCapturer>(
1556 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001557 auto audio_sender =
1558 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>());
1559 auto video_sender =
1560 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>());
1561 EXPECT_EQ("audio_track", audio_sender->id());
1562 EXPECT_EQ(audio_track, audio_sender->track());
1563 EXPECT_EQ("video_track", video_sender->id());
1564 EXPECT_EQ(video_track, video_sender->track());
1565 // If the ID is truly a random GUID, it should be infinitely unlikely they
1566 // will be the same.
deadbeefa601f5c2016-06-06 14:27:39 -07001567 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
deadbeefe1f9d832016-01-14 15:35:42 -08001568}
1569
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
1571 InitiateCall();
1572 WaitAndVerifyOnAddStream(kStreamLabel1);
1573 VerifyRemoteRtpHeaderExtensions();
1574}
1575
1576TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001577 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001578 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579 CreateOfferAsLocalDescription();
1580 std::string offer;
1581 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1582 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
1583 WaitAndVerifyOnAddStream(kStreamLabel1);
1584}
1585
1586TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001587 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001588 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589
1590 CreateOfferAsRemoteDescription();
1591 CreateAnswerAsLocalDescription();
1592
1593 WaitAndVerifyOnAddStream(kStreamLabel1);
1594}
1595
1596TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001597 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001598 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599
1600 CreateOfferAsRemoteDescription();
1601 CreatePrAnswerAsLocalDescription();
1602 CreateAnswerAsLocalDescription();
1603
1604 WaitAndVerifyOnAddStream(kStreamLabel1);
1605}
1606
1607TEST_F(PeerConnectionInterfaceTest, Renegotiate) {
1608 InitiateCall();
1609 ASSERT_EQ(1u, pc_->remote_streams()->count());
1610 pc_->RemoveStream(pc_->local_streams()->at(0));
1611 CreateOfferReceiveAnswer();
1612 EXPECT_EQ(0u, pc_->remote_streams()->count());
deadbeefab9b2d12015-10-14 11:33:11 -07001613 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614 CreateOfferReceiveAnswer();
1615}
1616
1617// Tests that after negotiating an audio only call, the respondent can perform a
1618// renegotiation that removes the audio stream.
1619TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) {
deadbeef293e9262017-01-11 12:28:30 -08001620 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621 AddVoiceStream(kStreamLabel1);
1622 CreateOfferAsRemoteDescription();
1623 CreateAnswerAsLocalDescription();
1624
1625 ASSERT_EQ(1u, pc_->remote_streams()->count());
1626 pc_->RemoveStream(pc_->local_streams()->at(0));
1627 CreateOfferReceiveAnswer();
1628 EXPECT_EQ(0u, pc_->remote_streams()->count());
1629}
1630
1631// Test that candidates are generated and that we can parse our own candidates.
1632TEST_F(PeerConnectionInterfaceTest, IceCandidates) {
deadbeef293e9262017-01-11 12:28:30 -08001633 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001634
1635 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1636 // SetRemoteDescription takes ownership of offer.
kwibergd1fe2812016-04-27 06:47:29 -07001637 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefab9b2d12015-10-14 11:33:11 -07001638 AddVideoStream(kStreamLabel1);
deadbeefc80741f2015-10-22 13:14:45 -07001639 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001640 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001641
1642 // SetLocalDescription takes ownership of answer.
kwibergd1fe2812016-04-27 06:47:29 -07001643 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001644 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001645 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001646
1647 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout);
1648 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
1649
1650 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1651}
1652
deadbeefab9b2d12015-10-14 11:33:11 -07001653// Test that CreateOffer and CreateAnswer will fail if the track labels are
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001654// not unique.
1655TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) {
deadbeef293e9262017-01-11 12:28:30 -08001656 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001657 // Create a regular offer for the CreateAnswer test later.
kwibergd1fe2812016-04-27 06:47:29 -07001658 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07001659 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001660 EXPECT_TRUE(offer);
1661 offer.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001662
1663 // Create a local stream with audio&video tracks having same label.
1664 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label");
1665
1666 // Test CreateOffer
deadbeefc80741f2015-10-22 13:14:45 -07001667 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668
1669 // Test CreateAnswer
kwibergd1fe2812016-04-27 06:47:29 -07001670 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001671 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001672}
1673
1674// Test that we will get different SSRCs for each tracks in the offer and answer
1675// we created.
1676TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001677 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001678 // Create a local stream with audio&video tracks having different labels.
1679 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1680
1681 // Test CreateOffer
kwibergd1fe2812016-04-27 06:47:29 -07001682 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001683 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684 int audio_ssrc = 0;
1685 int video_ssrc = 0;
1686 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()),
1687 &audio_ssrc));
1688 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()),
1689 &video_ssrc));
1690 EXPECT_NE(audio_ssrc, video_ssrc);
1691
1692 // Test CreateAnswer
1693 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergd1fe2812016-04-27 06:47:29 -07001694 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001695 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696 audio_ssrc = 0;
1697 video_ssrc = 0;
1698 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()),
1699 &audio_ssrc));
1700 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()),
1701 &video_ssrc));
1702 EXPECT_NE(audio_ssrc, video_ssrc);
1703}
1704
deadbeefeb459812015-12-15 19:24:43 -08001705// Test that it's possible to call AddTrack on a MediaStream after adding
1706// the stream to a PeerConnection.
1707// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1708TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001709 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001710 // Create audio stream and add to PeerConnection.
1711 AddVoiceStream(kStreamLabel1);
1712 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1713
1714 // Add video track to the audio-only stream.
zhihuang9763d562016-08-05 11:14:50 -07001715 rtc::scoped_refptr<VideoTrackInterface> video_track(
1716 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001717 "video_label", pc_factory_->CreateVideoSource(
1718 std::unique_ptr<cricket::VideoCapturer>(
1719 new cricket::FakeVideoCapturer()))));
deadbeefeb459812015-12-15 19:24:43 -08001720 stream->AddTrack(video_track.get());
1721
kwibergd1fe2812016-04-27 06:47:29 -07001722 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001723 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001724
1725 const cricket::MediaContentDescription* video_desc =
1726 cricket::GetFirstVideoContentDescription(offer->description());
1727 EXPECT_TRUE(video_desc != nullptr);
1728}
1729
1730// Test that it's possible to call RemoveTrack on a MediaStream after adding
1731// the stream to a PeerConnection.
1732// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1733TEST_F(PeerConnectionInterfaceTest, RemoveTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001734 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001735 // Create audio/video stream and add to PeerConnection.
1736 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1737 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1738
1739 // Remove the video track.
1740 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1741
kwibergd1fe2812016-04-27 06:47:29 -07001742 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001743 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001744
1745 const cricket::MediaContentDescription* video_desc =
1746 cricket::GetFirstVideoContentDescription(offer->description());
1747 EXPECT_TRUE(video_desc == nullptr);
1748}
1749
deadbeef1dcb1642017-03-29 21:08:16 -07001750// Verify that CreateDtmfSender only succeeds if called with a valid local
1751// track. Other aspects of DtmfSenders are tested in
1752// peerconnection_integrationtest.cc.
1753TEST_F(PeerConnectionInterfaceTest, CreateDtmfSenderWithInvalidParams) {
1754 CreatePeerConnection();
1755 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1756 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(nullptr));
1757 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack(
1758 pc_factory_->CreateAudioTrack("dummy_track", nullptr));
1759 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(non_localtrack));
1760}
1761
deadbeefbd7d8f72015-12-18 16:58:44 -08001762// Test creating a sender with a stream ID, and ensure the ID is populated
1763// in the offer.
1764TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) {
deadbeef293e9262017-01-11 12:28:30 -08001765 CreatePeerConnectionWithoutDtls();
deadbeefbd7d8f72015-12-18 16:58:44 -08001766 pc_->CreateSender("video", kStreamLabel1);
1767
kwibergd1fe2812016-04-27 06:47:29 -07001768 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001769 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefbd7d8f72015-12-18 16:58:44 -08001770
1771 const cricket::MediaContentDescription* video_desc =
1772 cricket::GetFirstVideoContentDescription(offer->description());
1773 ASSERT_TRUE(video_desc != nullptr);
1774 ASSERT_EQ(1u, video_desc->streams().size());
1775 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label);
1776}
1777
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778// Test that we can specify a certain track that we want statistics about.
1779TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
1780 InitiateCall();
1781 ASSERT_LT(0u, pc_->remote_streams()->count());
1782 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001783 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784 pc_->remote_streams()->at(0)->GetAudioTracks()[0];
1785 EXPECT_TRUE(DoGetStats(remote_audio));
1786
1787 // Remove the stream. Since we are sending to our selves the local
1788 // and the remote stream is the same.
1789 pc_->RemoveStream(pc_->local_streams()->at(0));
1790 // Do a re-negotiation.
1791 CreateOfferReceiveAnswer();
1792
1793 ASSERT_EQ(0u, pc_->remote_streams()->count());
1794
1795 // Test that we still can get statistics for the old track. Even if it is not
1796 // sent any longer.
1797 EXPECT_TRUE(DoGetStats(remote_audio));
1798}
1799
1800// Test that we can get stats on a video track.
1801TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
1802 InitiateCall();
1803 ASSERT_LT(0u, pc_->remote_streams()->count());
1804 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001805 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806 pc_->remote_streams()->at(0)->GetVideoTracks()[0];
1807 EXPECT_TRUE(DoGetStats(remote_video));
1808}
1809
1810// Test that we don't get statistics for an invalid track.
zhihuange9e94c32016-11-04 11:38:15 -07001811TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001812 InitiateCall();
zhihuang9763d562016-08-05 11:14:50 -07001813 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814 pc_factory_->CreateAudioTrack("unknown track", NULL));
1815 EXPECT_FALSE(DoGetStats(unknown_audio_track));
1816}
1817
1818// This test setup two RTP data channels in loop back.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819TEST_F(PeerConnectionInterfaceTest, TestDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001820 FakeConstraints constraints;
1821 constraints.SetAllowRtpDataChannels();
1822 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001823 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001824 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001825 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001826 pc_->CreateDataChannel("test2", NULL);
1827 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001828 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001830 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001831 new MockDataChannelObserver(data2));
1832
1833 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1834 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1835 std::string data_to_send1 = "testing testing";
1836 std::string data_to_send2 = "testing something else";
1837 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1)));
1838
1839 CreateOfferReceiveAnswer();
1840 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1841 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1842
1843 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1844 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1845 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1)));
1846 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1847
1848 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout);
1849 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1850
1851 data1->Close();
1852 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1853 CreateOfferReceiveAnswer();
1854 EXPECT_FALSE(observer1->IsOpen());
1855 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1856 EXPECT_TRUE(observer2->IsOpen());
1857
1858 data_to_send2 = "testing something else again";
1859 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1860
1861 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1862}
1863
1864// This test verifies that sendnig binary data over RTP data channels should
1865// fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001866TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001867 FakeConstraints constraints;
1868 constraints.SetAllowRtpDataChannels();
1869 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001870 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001871 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001872 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001873 pc_->CreateDataChannel("test2", NULL);
1874 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001875 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001877 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878 new MockDataChannelObserver(data2));
1879
1880 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1881 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1882
1883 CreateOfferReceiveAnswer();
1884 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1885 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1886
1887 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1888 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1889
jbaucheec21bd2016-03-20 06:15:43 -07001890 rtc::CopyOnWriteBuffer buffer("test", 4);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001891 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true)));
1892}
1893
1894// This test setup a RTP data channels in loop back and test that a channel is
1895// opened even if the remote end answer with a zero SSRC.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001896TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897 FakeConstraints constraints;
1898 constraints.SetAllowRtpDataChannels();
1899 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001900 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901 pc_->CreateDataChannel("test1", NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001902 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001903 new MockDataChannelObserver(data1));
1904
1905 CreateOfferReceiveAnswerWithoutSsrc();
1906
1907 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1908
1909 data1->Close();
1910 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1911 CreateOfferReceiveAnswerWithoutSsrc();
1912 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1913 EXPECT_FALSE(observer1->IsOpen());
1914}
1915
1916// This test that if a data channel is added in an answer a receive only channel
1917// channel is created.
1918TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) {
1919 FakeConstraints constraints;
1920 constraints.SetAllowRtpDataChannels();
1921 CreatePeerConnection(&constraints);
1922
1923 std::string offer_label = "offer_channel";
zhihuang9763d562016-08-05 11:14:50 -07001924 rtc::scoped_refptr<DataChannelInterface> offer_channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925 pc_->CreateDataChannel(offer_label, NULL);
1926
1927 CreateOfferAsLocalDescription();
1928
1929 // Replace the data channel label in the offer and apply it as an answer.
1930 std::string receive_label = "answer_channel";
1931 std::string sdp;
1932 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001933 rtc::replace_substrs(offer_label.c_str(), offer_label.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001934 receive_label.c_str(), receive_label.length(),
1935 &sdp);
1936 CreateAnswerAsRemoteDescription(sdp);
1937
1938 // Verify that a new incoming data channel has been created and that
1939 // it is open but can't we written to.
1940 ASSERT_TRUE(observer_.last_datachannel_ != NULL);
1941 DataChannelInterface* received_channel = observer_.last_datachannel_;
1942 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state());
1943 EXPECT_EQ(receive_label, received_channel->label());
1944 EXPECT_FALSE(received_channel->Send(DataBuffer("something")));
1945
1946 // Verify that the channel we initially offered has been rejected.
1947 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
1948
1949 // Do another offer / answer exchange and verify that the data channel is
1950 // opened.
1951 CreateOfferReceiveAnswer();
1952 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(),
1953 kTimeout);
1954}
1955
1956// This test that no data channel is returned if a reliable channel is
1957// requested.
1958// TODO(perkj): Remove this test once reliable channels are implemented.
1959TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) {
1960 FakeConstraints constraints;
1961 constraints.SetAllowRtpDataChannels();
1962 CreatePeerConnection(&constraints);
1963
1964 std::string label = "test";
1965 webrtc::DataChannelInit config;
1966 config.reliable = true;
zhihuang9763d562016-08-05 11:14:50 -07001967 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001968 pc_->CreateDataChannel(label, &config);
1969 EXPECT_TRUE(channel == NULL);
1970}
1971
deadbeefab9b2d12015-10-14 11:33:11 -07001972// Verifies that duplicated label is not allowed for RTP data channel.
1973TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) {
1974 FakeConstraints constraints;
1975 constraints.SetAllowRtpDataChannels();
1976 CreatePeerConnection(&constraints);
1977
1978 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07001979 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001980 pc_->CreateDataChannel(label, nullptr);
1981 EXPECT_NE(channel, nullptr);
1982
zhihuang9763d562016-08-05 11:14:50 -07001983 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001984 pc_->CreateDataChannel(label, nullptr);
1985 EXPECT_EQ(dup_channel, nullptr);
1986}
1987
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988// This tests that a SCTP data channel is returned using different
1989// DataChannelInit configurations.
1990TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
1991 FakeConstraints constraints;
1992 constraints.SetAllowDtlsSctpDataChannels();
1993 CreatePeerConnection(&constraints);
1994
1995 webrtc::DataChannelInit config;
1996
zhihuang9763d562016-08-05 11:14:50 -07001997 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998 pc_->CreateDataChannel("1", &config);
1999 EXPECT_TRUE(channel != NULL);
2000 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002001 EXPECT_TRUE(observer_.renegotiation_needed_);
2002 observer_.renegotiation_needed_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002003
2004 config.ordered = false;
2005 channel = pc_->CreateDataChannel("2", &config);
2006 EXPECT_TRUE(channel != NULL);
2007 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002008 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002009
2010 config.ordered = true;
2011 config.maxRetransmits = 0;
2012 channel = pc_->CreateDataChannel("3", &config);
2013 EXPECT_TRUE(channel != NULL);
2014 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002015 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002016
2017 config.maxRetransmits = -1;
2018 config.maxRetransmitTime = 0;
2019 channel = pc_->CreateDataChannel("4", &config);
2020 EXPECT_TRUE(channel != NULL);
2021 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002022 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002023}
2024
2025// This tests that no data channel is returned if both maxRetransmits and
2026// maxRetransmitTime are set for SCTP data channels.
2027TEST_F(PeerConnectionInterfaceTest,
2028 CreateSctpDataChannelShouldFailForInvalidConfig) {
2029 FakeConstraints constraints;
2030 constraints.SetAllowDtlsSctpDataChannels();
2031 CreatePeerConnection(&constraints);
2032
2033 std::string label = "test";
2034 webrtc::DataChannelInit config;
2035 config.maxRetransmits = 0;
2036 config.maxRetransmitTime = 0;
2037
zhihuang9763d562016-08-05 11:14:50 -07002038 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002039 pc_->CreateDataChannel(label, &config);
2040 EXPECT_TRUE(channel == NULL);
2041}
2042
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002043// The test verifies that creating a SCTP data channel with an id already in use
2044// or out of range should fail.
2045TEST_F(PeerConnectionInterfaceTest,
2046 CreateSctpDataChannelWithInvalidIdShouldFail) {
2047 FakeConstraints constraints;
2048 constraints.SetAllowDtlsSctpDataChannels();
2049 CreatePeerConnection(&constraints);
2050
2051 webrtc::DataChannelInit config;
zhihuang9763d562016-08-05 11:14:50 -07002052 rtc::scoped_refptr<DataChannelInterface> channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002053
wu@webrtc.orgcecfd182013-10-30 05:18:12 +00002054 config.id = 1;
2055 channel = pc_->CreateDataChannel("1", &config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002056 EXPECT_TRUE(channel != NULL);
2057 EXPECT_EQ(1, channel->id());
2058
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059 channel = pc_->CreateDataChannel("x", &config);
2060 EXPECT_TRUE(channel == NULL);
2061
2062 config.id = cricket::kMaxSctpSid;
2063 channel = pc_->CreateDataChannel("max", &config);
2064 EXPECT_TRUE(channel != NULL);
2065 EXPECT_EQ(config.id, channel->id());
2066
2067 config.id = cricket::kMaxSctpSid + 1;
2068 channel = pc_->CreateDataChannel("x", &config);
2069 EXPECT_TRUE(channel == NULL);
2070}
2071
deadbeefab9b2d12015-10-14 11:33:11 -07002072// Verifies that duplicated label is allowed for SCTP data channel.
2073TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
2074 FakeConstraints constraints;
2075 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2076 true);
2077 CreatePeerConnection(&constraints);
2078
2079 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07002080 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002081 pc_->CreateDataChannel(label, nullptr);
2082 EXPECT_NE(channel, nullptr);
2083
zhihuang9763d562016-08-05 11:14:50 -07002084 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002085 pc_->CreateDataChannel(label, nullptr);
2086 EXPECT_NE(dup_channel, nullptr);
2087}
2088
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002089// This test verifies that OnRenegotiationNeeded is fired for every new RTP
2090// DataChannel.
2091TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) {
2092 FakeConstraints constraints;
2093 constraints.SetAllowRtpDataChannels();
2094 CreatePeerConnection(&constraints);
2095
zhihuang9763d562016-08-05 11:14:50 -07002096 rtc::scoped_refptr<DataChannelInterface> dc1 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002097 pc_->CreateDataChannel("test1", NULL);
2098 EXPECT_TRUE(observer_.renegotiation_needed_);
2099 observer_.renegotiation_needed_ = false;
2100
zhihuang9763d562016-08-05 11:14:50 -07002101 rtc::scoped_refptr<DataChannelInterface> dc2 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002102 pc_->CreateDataChannel("test2", NULL);
2103 EXPECT_TRUE(observer_.renegotiation_needed_);
2104}
2105
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002106// This test that a data channel closes when a PeerConnection is deleted/closed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002107TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002108 FakeConstraints constraints;
2109 constraints.SetAllowRtpDataChannels();
2110 CreatePeerConnection(&constraints);
2111
zhihuang9763d562016-08-05 11:14:50 -07002112 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002113 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07002114 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002115 pc_->CreateDataChannel("test2", NULL);
2116 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002117 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002118 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07002119 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120 new MockDataChannelObserver(data2));
2121
2122 CreateOfferReceiveAnswer();
2123 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2124 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
2125
2126 ReleasePeerConnection();
2127 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2128 EXPECT_EQ(DataChannelInterface::kClosed, data2->state());
2129}
2130
2131// This test that data channels can be rejected in an answer.
2132TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) {
2133 FakeConstraints constraints;
2134 constraints.SetAllowRtpDataChannels();
2135 CreatePeerConnection(&constraints);
2136
zhihuang9763d562016-08-05 11:14:50 -07002137 rtc::scoped_refptr<DataChannelInterface> offer_channel(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002138 pc_->CreateDataChannel("offer_channel", NULL));
2139
2140 CreateOfferAsLocalDescription();
2141
2142 // Create an answer where the m-line for data channels are rejected.
2143 std::string sdp;
2144 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2145 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
2146 SessionDescriptionInterface::kAnswer);
2147 EXPECT_TRUE(answer->Initialize(sdp, NULL));
2148 cricket::ContentInfo* data_info =
2149 answer->description()->GetContentByName("data");
2150 data_info->rejected = true;
2151
2152 DoSetRemoteDescription(answer);
2153 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2154}
2155
2156// Test that we can create a session description from an SDP string from
2157// FireFox, use it as a remote session description, generate an answer and use
2158// the answer as a local description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002159TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002160 FakeConstraints constraints;
2161 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2162 true);
2163 CreatePeerConnection(&constraints);
2164 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2165 SessionDescriptionInterface* desc =
2166 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002167 webrtc::kFireFoxSdpOffer, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2169 CreateAnswerAsLocalDescription();
2170 ASSERT_TRUE(pc_->local_description() != NULL);
2171 ASSERT_TRUE(pc_->remote_description() != NULL);
2172
2173 const cricket::ContentInfo* content =
2174 cricket::GetFirstAudioContent(pc_->local_description()->description());
2175 ASSERT_TRUE(content != NULL);
2176 EXPECT_FALSE(content->rejected);
2177
2178 content =
2179 cricket::GetFirstVideoContent(pc_->local_description()->description());
2180 ASSERT_TRUE(content != NULL);
2181 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002182#ifdef HAVE_SCTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183 content =
2184 cricket::GetFirstDataContent(pc_->local_description()->description());
2185 ASSERT_TRUE(content != NULL);
2186 EXPECT_TRUE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002187#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188}
2189
deadbeef8662f942017-01-20 21:20:51 -08002190// Test that an offer can be received which offers DTLS with SDES fallback.
2191// Regression test for issue:
2192// https://bugs.chromium.org/p/webrtc/issues/detail?id=6972
2193TEST_F(PeerConnectionInterfaceTest, ReceiveDtlsSdesFallbackOffer) {
2194 FakeConstraints constraints;
2195 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2196 true);
2197 CreatePeerConnection(&constraints);
2198 // Wait for fake certificate to be generated. Previously, this is what caused
2199 // the "a=crypto" lines to be rejected.
2200 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2201 ASSERT_NE(nullptr, fake_certificate_generator_);
2202 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2203 kTimeout);
2204 SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
2205 SessionDescriptionInterface::kOffer, kDtlsSdesFallbackSdp, nullptr);
2206 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2207 CreateAnswerAsLocalDescription();
2208}
2209
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002210// Test that we can create an audio only offer and receive an answer with a
2211// limited set of audio codecs and receive an updated offer with more audio
2212// codecs, where the added codecs are not supported.
2213TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
deadbeef293e9262017-01-11 12:28:30 -08002214 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002215 AddVoiceStream("audio_label");
2216 CreateOfferAsLocalDescription();
2217
2218 SessionDescriptionInterface* answer =
2219 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
jbauchfabe2c92015-07-16 13:43:14 -07002220 webrtc::kAudioSdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002221 EXPECT_TRUE(DoSetSessionDescription(answer, false));
2222
2223 SessionDescriptionInterface* updated_offer =
2224 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002225 webrtc::kAudioSdpWithUnsupportedCodecs,
2226 nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002227 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false));
2228 CreateAnswerAsLocalDescription();
2229}
2230
deadbeefc80741f2015-10-22 13:14:45 -07002231// Test that if we're receiving (but not sending) a track, subsequent offers
2232// will have m-lines with a=recvonly.
2233TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
2234 FakeConstraints constraints;
2235 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2236 true);
2237 CreatePeerConnection(&constraints);
2238 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2239 CreateAnswerAsLocalDescription();
2240
2241 // At this point we should be receiving stream 1, but not sending anything.
2242 // A new offer should be recvonly.
kwibergd1fe2812016-04-27 06:47:29 -07002243 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002244 DoCreateOffer(&offer, nullptr);
2245
2246 const cricket::ContentInfo* video_content =
2247 cricket::GetFirstVideoContent(offer->description());
2248 const cricket::VideoContentDescription* video_desc =
2249 static_cast<const cricket::VideoContentDescription*>(
2250 video_content->description);
2251 ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction());
2252
2253 const cricket::ContentInfo* audio_content =
2254 cricket::GetFirstAudioContent(offer->description());
2255 const cricket::AudioContentDescription* audio_desc =
2256 static_cast<const cricket::AudioContentDescription*>(
2257 audio_content->description);
2258 ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction());
2259}
2260
2261// Test that if we're receiving (but not sending) a track, and the
2262// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2263// false, the generated m-lines will be a=inactive.
2264TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
2265 FakeConstraints constraints;
2266 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2267 true);
2268 CreatePeerConnection(&constraints);
2269 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2270 CreateAnswerAsLocalDescription();
2271
2272 // At this point we should be receiving stream 1, but not sending anything.
2273 // A new offer would be recvonly, but we'll set the "no receive" constraints
2274 // to make it inactive.
kwibergd1fe2812016-04-27 06:47:29 -07002275 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002276 FakeConstraints offer_constraints;
2277 offer_constraints.AddMandatory(
2278 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false);
2279 offer_constraints.AddMandatory(
2280 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false);
2281 DoCreateOffer(&offer, &offer_constraints);
2282
2283 const cricket::ContentInfo* video_content =
2284 cricket::GetFirstVideoContent(offer->description());
2285 const cricket::VideoContentDescription* video_desc =
2286 static_cast<const cricket::VideoContentDescription*>(
2287 video_content->description);
2288 ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction());
2289
2290 const cricket::ContentInfo* audio_content =
2291 cricket::GetFirstAudioContent(offer->description());
2292 const cricket::AudioContentDescription* audio_desc =
2293 static_cast<const cricket::AudioContentDescription*>(
2294 audio_content->description);
2295 ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction());
2296}
2297
deadbeef653b8e02015-11-11 12:55:10 -08002298// Test that we can use SetConfiguration to change the ICE servers of the
2299// PortAllocator.
2300TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
2301 CreatePeerConnection();
2302
2303 PeerConnectionInterface::RTCConfiguration config;
2304 PeerConnectionInterface::IceServer server;
2305 server.uri = "stun:test_hostname";
2306 config.servers.push_back(server);
2307 EXPECT_TRUE(pc_->SetConfiguration(config));
2308
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08002309 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2310 EXPECT_EQ("test_hostname",
2311 port_allocator_->stun_servers().begin()->hostname());
deadbeef653b8e02015-11-11 12:55:10 -08002312}
2313
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002314TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
2315 CreatePeerConnection();
2316 PeerConnectionInterface::RTCConfiguration config;
2317 config.type = PeerConnectionInterface::kRelay;
2318 EXPECT_TRUE(pc_->SetConfiguration(config));
2319 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2320}
2321
deadbeef293e9262017-01-11 12:28:30 -08002322TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
2323 PeerConnectionInterface::RTCConfiguration config;
2324 config.prune_turn_ports = false;
2325 CreatePeerConnection(config, nullptr);
2326 EXPECT_FALSE(port_allocator_->prune_turn_ports());
2327
2328 config.prune_turn_ports = true;
2329 EXPECT_TRUE(pc_->SetConfiguration(config));
2330 EXPECT_TRUE(port_allocator_->prune_turn_ports());
2331}
2332
skvladd1f5fda2017-02-03 16:54:05 -08002333// Test that the ice check interval can be changed. This does not verify that
2334// the setting makes it all the way to P2PTransportChannel, as that would
2335// require a very complex set of mocks.
2336TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
2337 PeerConnectionInterface::RTCConfiguration config;
2338 config.ice_check_min_interval = rtc::Optional<int>();
2339 CreatePeerConnection(config, nullptr);
2340 config.ice_check_min_interval = rtc::Optional<int>(100);
2341 EXPECT_TRUE(pc_->SetConfiguration(config));
2342 PeerConnectionInterface::RTCConfiguration new_config =
2343 pc_->GetConfiguration();
2344 EXPECT_EQ(new_config.ice_check_min_interval, rtc::Optional<int>(100));
2345}
2346
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002347// Test that when SetConfiguration changes both the pool size and other
2348// attributes, the pooled session is created with the updated attributes.
2349TEST_F(PeerConnectionInterfaceTest,
2350 SetConfigurationCreatesPooledSessionCorrectly) {
2351 CreatePeerConnection();
2352 PeerConnectionInterface::RTCConfiguration config;
2353 config.ice_candidate_pool_size = 1;
2354 PeerConnectionInterface::IceServer server;
2355 server.uri = kStunAddressOnly;
2356 config.servers.push_back(server);
2357 config.type = PeerConnectionInterface::kRelay;
Taylor Brandstetter417eebe2016-05-23 16:02:19 -07002358 EXPECT_TRUE(pc_->SetConfiguration(config));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002359
2360 const cricket::FakePortAllocatorSession* session =
2361 static_cast<const cricket::FakePortAllocatorSession*>(
2362 port_allocator_->GetPooledSession());
2363 ASSERT_NE(nullptr, session);
2364 EXPECT_EQ(1UL, session->stun_servers().size());
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002365}
2366
deadbeef293e9262017-01-11 12:28:30 -08002367// Test that after SetLocalDescription, changing the pool size is not allowed,
2368// and an invalid modification error is returned.
deadbeef6de92f92016-12-12 18:49:32 -08002369TEST_F(PeerConnectionInterfaceTest,
2370 CantChangePoolSizeAfterSetLocalDescription) {
2371 CreatePeerConnection();
2372 // Start by setting a size of 1.
2373 PeerConnectionInterface::RTCConfiguration config;
2374 config.ice_candidate_pool_size = 1;
2375 EXPECT_TRUE(pc_->SetConfiguration(config));
2376
2377 // Set remote offer; can still change pool size at this point.
2378 CreateOfferAsRemoteDescription();
2379 config.ice_candidate_pool_size = 2;
2380 EXPECT_TRUE(pc_->SetConfiguration(config));
2381
2382 // Set local answer; now it's too late.
2383 CreateAnswerAsLocalDescription();
2384 config.ice_candidate_pool_size = 3;
deadbeef293e9262017-01-11 12:28:30 -08002385 RTCError error;
2386 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2387 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2388}
2389
deadbeef42a42632017-03-10 15:18:00 -08002390// Test that after setting an answer, extra pooled sessions are discarded. The
2391// ICE candidate pool is only intended to be used for the first offer/answer.
2392TEST_F(PeerConnectionInterfaceTest,
2393 ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
2394 CreatePeerConnection();
2395
2396 // Set a larger-than-necessary size.
2397 PeerConnectionInterface::RTCConfiguration config;
2398 config.ice_candidate_pool_size = 4;
2399 EXPECT_TRUE(pc_->SetConfiguration(config));
2400
2401 // Do offer/answer.
2402 CreateOfferAsRemoteDescription();
2403 CreateAnswerAsLocalDescription();
2404
2405 // Expect no pooled sessions to be left.
2406 const cricket::PortAllocatorSession* session =
2407 port_allocator_->GetPooledSession();
2408 EXPECT_EQ(nullptr, session);
2409}
2410
2411// After Close is called, pooled candidates should be discarded so as to not
2412// waste network resources.
2413TEST_F(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
2414 CreatePeerConnection();
2415
2416 PeerConnectionInterface::RTCConfiguration config;
2417 config.ice_candidate_pool_size = 3;
2418 EXPECT_TRUE(pc_->SetConfiguration(config));
2419 pc_->Close();
2420
2421 // Expect no pooled sessions to be left.
2422 const cricket::PortAllocatorSession* session =
2423 port_allocator_->GetPooledSession();
2424 EXPECT_EQ(nullptr, session);
2425}
2426
deadbeef293e9262017-01-11 12:28:30 -08002427// Test that SetConfiguration returns an invalid modification error if
2428// modifying a field in the configuration that isn't allowed to be modified.
2429TEST_F(PeerConnectionInterfaceTest,
2430 SetConfigurationReturnsInvalidModificationError) {
2431 PeerConnectionInterface::RTCConfiguration config;
2432 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2433 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2434 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
2435 CreatePeerConnection(config, nullptr);
2436
2437 PeerConnectionInterface::RTCConfiguration modified_config = config;
2438 modified_config.bundle_policy =
2439 PeerConnectionInterface::kBundlePolicyMaxBundle;
2440 RTCError error;
2441 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2442 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2443
2444 modified_config = config;
2445 modified_config.rtcp_mux_policy =
2446 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2447 error.set_type(RTCErrorType::NONE);
2448 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2449 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2450
2451 modified_config = config;
2452 modified_config.continual_gathering_policy =
2453 PeerConnectionInterface::GATHER_CONTINUALLY;
2454 error.set_type(RTCErrorType::NONE);
2455 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2456 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2457}
2458
2459// Test that SetConfiguration returns a range error if the candidate pool size
2460// is negative or larger than allowed by the spec.
2461TEST_F(PeerConnectionInterfaceTest,
2462 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2463 PeerConnectionInterface::RTCConfiguration config;
2464 CreatePeerConnection(config, nullptr);
2465
2466 config.ice_candidate_pool_size = -1;
2467 RTCError error;
2468 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2469 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2470
2471 config.ice_candidate_pool_size = INT_MAX;
2472 error.set_type(RTCErrorType::NONE);
2473 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2474 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2475}
2476
2477// Test that SetConfiguration returns a syntax error if parsing an ICE server
2478// URL failed.
2479TEST_F(PeerConnectionInterfaceTest,
2480 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2481 PeerConnectionInterface::RTCConfiguration config;
2482 CreatePeerConnection(config, nullptr);
2483
2484 PeerConnectionInterface::IceServer bad_server;
2485 bad_server.uri = "stunn:www.example.com";
2486 config.servers.push_back(bad_server);
2487 RTCError error;
2488 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2489 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2490}
2491
2492// Test that SetConfiguration returns an invalid parameter error if a TURN
2493// IceServer is missing a username or password.
2494TEST_F(PeerConnectionInterfaceTest,
2495 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2496 PeerConnectionInterface::RTCConfiguration config;
2497 CreatePeerConnection(config, nullptr);
2498
2499 PeerConnectionInterface::IceServer bad_server;
2500 bad_server.uri = "turn:www.example.com";
2501 // Missing password.
2502 bad_server.username = "foo";
2503 config.servers.push_back(bad_server);
2504 RTCError error;
2505 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2506 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
deadbeef6de92f92016-12-12 18:49:32 -08002507}
2508
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509// Test that PeerConnection::Close changes the states to closed and all remote
2510// tracks change state to ended.
2511TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
2512 // Initialize a PeerConnection and negotiate local and remote session
2513 // description.
2514 InitiateCall();
2515 ASSERT_EQ(1u, pc_->local_streams()->count());
2516 ASSERT_EQ(1u, pc_->remote_streams()->count());
2517
2518 pc_->Close();
2519
2520 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2521 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2522 pc_->ice_connection_state());
2523 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2524 pc_->ice_gathering_state());
2525
2526 EXPECT_EQ(1u, pc_->local_streams()->count());
2527 EXPECT_EQ(1u, pc_->remote_streams()->count());
2528
zhihuang9763d562016-08-05 11:14:50 -07002529 rtc::scoped_refptr<MediaStreamInterface> remote_stream =
2530 pc_->remote_streams()->at(0);
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002531 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002532 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002533 remote_stream->GetAudioTracks()[0]->state(), kTimeout);
2534 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2535 remote_stream->GetVideoTracks()[0]->state(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002536}
2537
2538// Test that PeerConnection methods fails gracefully after
2539// PeerConnection::Close has been called.
2540TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) {
deadbeef293e9262017-01-11 12:28:30 -08002541 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2543 CreateOfferAsRemoteDescription();
2544 CreateAnswerAsLocalDescription();
2545
2546 ASSERT_EQ(1u, pc_->local_streams()->count());
zhihuang9763d562016-08-05 11:14:50 -07002547 rtc::scoped_refptr<MediaStreamInterface> local_stream =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548 pc_->local_streams()->at(0);
2549
2550 pc_->Close();
2551
2552 pc_->RemoveStream(local_stream);
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00002553 EXPECT_FALSE(pc_->AddStream(local_stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002554
2555 ASSERT_FALSE(local_stream->GetAudioTracks().empty());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002556 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0]));
wu@webrtc.org66037362013-08-13 00:09:35 +00002558 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002559
2560 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL);
2561
2562 EXPECT_TRUE(pc_->local_description() != NULL);
2563 EXPECT_TRUE(pc_->remote_description() != NULL);
2564
kwibergd1fe2812016-04-27 06:47:29 -07002565 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07002566 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwibergd1fe2812016-04-27 06:47:29 -07002567 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07002568 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002569
2570 std::string sdp;
2571 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
2572 SessionDescriptionInterface* remote_offer =
2573 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2574 sdp, NULL);
2575 EXPECT_FALSE(DoSetRemoteDescription(remote_offer));
2576
2577 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
2578 SessionDescriptionInterface* local_offer =
2579 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2580 sdp, NULL);
2581 EXPECT_FALSE(DoSetLocalDescription(local_offer));
2582}
2583
2584// Test that GetStats can still be called after PeerConnection::Close.
2585TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) {
2586 InitiateCall();
2587 pc_->Close();
2588 DoGetStats(NULL);
2589}
deadbeefab9b2d12015-10-14 11:33:11 -07002590
2591// NOTE: The series of tests below come from what used to be
2592// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2593// setting a remote or local description has the expected effects.
2594
2595// This test verifies that the remote MediaStreams corresponding to a received
2596// SDP string is created. In this test the two separate MediaStreams are
2597// signaled.
2598TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
2599 FakeConstraints constraints;
2600 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2601 true);
2602 CreatePeerConnection(&constraints);
2603 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2604
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002605 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002606 EXPECT_TRUE(
2607 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2608 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2609 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2610
2611 // Create a session description based on another SDP with another
2612 // MediaStream.
2613 CreateAndSetRemoteOffer(kSdpStringWithStream1And2);
2614
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002615 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002616 EXPECT_TRUE(
2617 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2618}
2619
2620// This test verifies that when remote tracks are added/removed from SDP, the
2621// created remote streams are updated appropriately.
2622TEST_F(PeerConnectionInterfaceTest,
2623 AddRemoveTrackFromExistingRemoteMediaStream) {
2624 FakeConstraints constraints;
2625 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2626 true);
2627 CreatePeerConnection(&constraints);
kwibergd1fe2812016-04-27 06:47:29 -07002628 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
kwiberg2bbff992016-03-16 11:03:04 -07002629 CreateSessionDescriptionAndReference(1, 1);
deadbeefab9b2d12015-10-14 11:33:11 -07002630 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release()));
2631 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2632 reference_collection_));
2633
2634 // Add extra audio and video tracks to the same MediaStream.
kwibergd1fe2812016-04-27 06:47:29 -07002635 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
kwiberg2bbff992016-03-16 11:03:04 -07002636 CreateSessionDescriptionAndReference(2, 2);
deadbeefab9b2d12015-10-14 11:33:11 -07002637 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release()));
2638 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2639 reference_collection_));
zhihuang9763d562016-08-05 11:14:50 -07002640 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
perkjd61bf802016-03-24 03:16:19 -07002641 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2642 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
zhihuang9763d562016-08-05 11:14:50 -07002643 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
perkjd61bf802016-03-24 03:16:19 -07002644 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2645 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002646
2647 // Remove the extra audio and video tracks.
kwibergd1fe2812016-04-27 06:47:29 -07002648 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
kwiberg2bbff992016-03-16 11:03:04 -07002649 CreateSessionDescriptionAndReference(1, 1);
perkjd61bf802016-03-24 03:16:19 -07002650 MockTrackObserver audio_track_observer(audio_track2);
2651 MockTrackObserver video_track_observer(video_track2);
2652
2653 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2654 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
deadbeefab9b2d12015-10-14 11:33:11 -07002655 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release()));
2656 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2657 reference_collection_));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002658 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002659 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002660 audio_track2->state(), kTimeout);
2661 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2662 video_track2->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002663}
2664
2665// This tests that remote tracks are ended if a local session description is set
2666// that rejects the media content type.
2667TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) {
2668 FakeConstraints constraints;
2669 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2670 true);
2671 CreatePeerConnection(&constraints);
2672 // First create and set a remote offer, then reject its video content in our
2673 // answer.
2674 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2675 ASSERT_EQ(1u, observer_.remote_streams()->count());
2676 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2677 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2678 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2679
2680 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video =
2681 remote_stream->GetVideoTracks()[0];
2682 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state());
2683 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio =
2684 remote_stream->GetAudioTracks()[0];
2685 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2686
kwibergd1fe2812016-04-27 06:47:29 -07002687 std::unique_ptr<SessionDescriptionInterface> local_answer;
kwiberg2bbff992016-03-16 11:03:04 -07002688 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002689 cricket::ContentInfo* video_info =
2690 local_answer->description()->GetContentByName("video");
2691 video_info->rejected = true;
2692 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2693 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state());
2694 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2695
2696 // Now create an offer where we reject both video and audio.
kwibergd1fe2812016-04-27 06:47:29 -07002697 std::unique_ptr<SessionDescriptionInterface> local_offer;
kwiberg2bbff992016-03-16 11:03:04 -07002698 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002699 video_info = local_offer->description()->GetContentByName("video");
2700 ASSERT_TRUE(video_info != nullptr);
2701 video_info->rejected = true;
2702 cricket::ContentInfo* audio_info =
2703 local_offer->description()->GetContentByName("audio");
2704 ASSERT_TRUE(audio_info != nullptr);
2705 audio_info->rejected = true;
2706 EXPECT_TRUE(DoSetLocalDescription(local_offer.release()));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002707 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002708 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002709 remote_audio->state(), kTimeout);
2710 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2711 remote_video->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002712}
2713
2714// This tests that we won't crash if the remote track has been removed outside
2715// of PeerConnection and then PeerConnection tries to reject the track.
2716TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) {
2717 FakeConstraints constraints;
2718 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2719 true);
2720 CreatePeerConnection(&constraints);
2721 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2722 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2723 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2724 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2725
kwibergd1fe2812016-04-27 06:47:29 -07002726 std::unique_ptr<SessionDescriptionInterface> local_answer(
deadbeefab9b2d12015-10-14 11:33:11 -07002727 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
2728 kSdpStringWithStream1, nullptr));
2729 cricket::ContentInfo* video_info =
2730 local_answer->description()->GetContentByName("video");
2731 video_info->rejected = true;
2732 cricket::ContentInfo* audio_info =
2733 local_answer->description()->GetContentByName("audio");
2734 audio_info->rejected = true;
2735 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2736
2737 // No crash is a pass.
2738}
2739
deadbeef5e97fb52015-10-15 12:49:08 -07002740// This tests that if a recvonly remote description is set, no remote streams
2741// will be created, even if the description contains SSRCs/MSIDs.
2742// See: https://code.google.com/p/webrtc/issues/detail?id=5054
2743TEST_F(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
2744 FakeConstraints constraints;
2745 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2746 true);
2747 CreatePeerConnection(&constraints);
2748
2749 std::string recvonly_offer = kSdpStringWithStream1;
2750 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly,
2751 strlen(kRecvonly), &recvonly_offer);
2752 CreateAndSetRemoteOffer(recvonly_offer);
2753
2754 EXPECT_EQ(0u, observer_.remote_streams()->count());
2755}
2756
deadbeefab9b2d12015-10-14 11:33:11 -07002757// This tests that a default MediaStream is created if a remote session
2758// description doesn't contain any streams and no MSID support.
2759// It also tests that the default stream is updated if a video m-line is added
2760// in a subsequent session description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002761TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002762 FakeConstraints constraints;
2763 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2764 true);
2765 CreatePeerConnection(&constraints);
2766 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2767
2768 ASSERT_EQ(1u, observer_.remote_streams()->count());
2769 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2770
2771 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2772 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
2773 EXPECT_EQ("default", remote_stream->label());
2774
2775 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2776 ASSERT_EQ(1u, observer_.remote_streams()->count());
2777 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2778 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002779 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2780 remote_stream->GetAudioTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002781 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2782 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002783 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2784 remote_stream->GetVideoTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002785}
2786
2787// This tests that a default MediaStream is created if a remote session
2788// description doesn't contain any streams and media direction is send only.
2789TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002790 SendOnlySdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002791 FakeConstraints constraints;
2792 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2793 true);
2794 CreatePeerConnection(&constraints);
2795 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2796
2797 ASSERT_EQ(1u, observer_.remote_streams()->count());
2798 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2799
2800 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2801 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2802 EXPECT_EQ("default", remote_stream->label());
2803}
2804
2805// This tests that it won't crash when PeerConnection tries to remove
2806// a remote track that as already been removed from the MediaStream.
2807TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) {
2808 FakeConstraints constraints;
2809 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2810 true);
2811 CreatePeerConnection(&constraints);
2812 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2813 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2814 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2815 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2816
2817 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2818
2819 // No crash is a pass.
2820}
2821
2822// This tests that a default MediaStream is created if the remote session
2823// description doesn't contain any streams and don't contain an indication if
2824// MSID is supported.
2825TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002826 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002827 FakeConstraints constraints;
2828 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2829 true);
2830 CreatePeerConnection(&constraints);
2831 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2832
2833 ASSERT_EQ(1u, observer_.remote_streams()->count());
2834 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2835 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2836 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2837}
2838
2839// This tests that a default MediaStream is not created if the remote session
2840// description doesn't contain any streams but does support MSID.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002841TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002842 FakeConstraints constraints;
2843 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2844 true);
2845 CreatePeerConnection(&constraints);
2846 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2847 EXPECT_EQ(0u, observer_.remote_streams()->count());
2848}
2849
deadbeefbda7e0b2015-12-08 17:13:40 -08002850// This tests that when setting a new description, the old default tracks are
2851// not destroyed and recreated.
2852// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
Stefan Holmer102362b2016-03-18 09:39:07 +01002853TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002854 DefaultTracksNotDestroyedAndRecreated) {
deadbeefbda7e0b2015-12-08 17:13:40 -08002855 FakeConstraints constraints;
2856 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2857 true);
2858 CreatePeerConnection(&constraints);
2859 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2860
2861 ASSERT_EQ(1u, observer_.remote_streams()->count());
2862 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2863 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2864
2865 // Set the track to "disabled", then set a new description and ensure the
2866 // track is still disabled, which ensures it hasn't been recreated.
2867 remote_stream->GetAudioTracks()[0]->set_enabled(false);
2868 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2869 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2870 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
2871}
2872
deadbeefab9b2d12015-10-14 11:33:11 -07002873// This tests that a default MediaStream is not created if a remote session
2874// description is updated to not have any MediaStreams.
2875TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) {
2876 FakeConstraints constraints;
2877 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2878 true);
2879 CreatePeerConnection(&constraints);
2880 CreateAndSetRemoteOffer(kSdpStringWithStream1);
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002881 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002882 EXPECT_TRUE(
2883 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2884
2885 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2886 EXPECT_EQ(0u, observer_.remote_streams()->count());
2887}
2888
2889// This tests that an RtpSender is created when the local description is set
2890// after adding a local stream.
2891// TODO(deadbeef): This test and the one below it need to be updated when
2892// an RtpSender's lifetime isn't determined by when a local description is set.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002893TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002894 FakeConstraints constraints;
2895 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2896 true);
2897 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002898
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002899 // Create an offer with 1 stream with 2 tracks of each type.
2900 rtc::scoped_refptr<StreamCollection> stream_collection =
2901 CreateStreamCollection(1, 2);
2902 pc_->AddStream(stream_collection->at(0));
2903 std::unique_ptr<SessionDescriptionInterface> offer;
2904 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2905 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002906
deadbeefab9b2d12015-10-14 11:33:11 -07002907 auto senders = pc_->GetSenders();
2908 EXPECT_EQ(4u, senders.size());
2909 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2910 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2911 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2912 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2913
2914 // Remove an audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002915 pc_->RemoveStream(stream_collection->at(0));
2916 stream_collection = CreateStreamCollection(1, 1);
2917 pc_->AddStream(stream_collection->at(0));
2918 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2919 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
2920
deadbeefab9b2d12015-10-14 11:33:11 -07002921 senders = pc_->GetSenders();
2922 EXPECT_EQ(2u, senders.size());
2923 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2924 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2925 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
2926 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
2927}
2928
2929// This tests that an RtpSender is created when the local description is set
2930// before adding a local stream.
2931TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002932 AddLocalStreamAfterLocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002933 FakeConstraints constraints;
2934 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2935 true);
2936 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002937
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002938 rtc::scoped_refptr<StreamCollection> stream_collection =
2939 CreateStreamCollection(1, 2);
2940 // Add a stream to create the offer, but remove it afterwards.
2941 pc_->AddStream(stream_collection->at(0));
2942 std::unique_ptr<SessionDescriptionInterface> offer;
2943 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2944 pc_->RemoveStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002945
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002946 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002947 auto senders = pc_->GetSenders();
2948 EXPECT_EQ(0u, senders.size());
2949
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002950 pc_->AddStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002951 senders = pc_->GetSenders();
2952 EXPECT_EQ(4u, senders.size());
2953 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2954 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2955 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2956 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2957}
2958
2959// This tests that the expected behavior occurs if the SSRC on a local track is
2960// changed when SetLocalDescription is called.
2961TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002962 ChangeSsrcOnTrackInLocalSessionDescription) {
deadbeefab9b2d12015-10-14 11:33:11 -07002963 FakeConstraints constraints;
2964 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2965 true);
2966 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002967
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002968 rtc::scoped_refptr<StreamCollection> stream_collection =
2969 CreateStreamCollection(2, 1);
2970 pc_->AddStream(stream_collection->at(0));
2971 std::unique_ptr<SessionDescriptionInterface> offer;
2972 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2973 // Grab a copy of the offer before it gets passed into the PC.
2974 std::unique_ptr<JsepSessionDescription> modified_offer(
2975 new JsepSessionDescription(JsepSessionDescription::kOffer));
2976 modified_offer->Initialize(offer->description()->Copy(), offer->session_id(),
2977 offer->session_version());
2978 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002979
deadbeefab9b2d12015-10-14 11:33:11 -07002980 auto senders = pc_->GetSenders();
2981 EXPECT_EQ(2u, senders.size());
2982 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2983 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2984
2985 // Change the ssrc of the audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002986 cricket::MediaContentDescription* desc =
2987 cricket::GetFirstAudioContentDescription(modified_offer->description());
2988 ASSERT_TRUE(desc != NULL);
2989 for (StreamParams& stream : desc->mutable_streams()) {
2990 for (unsigned int& ssrc : stream.ssrcs) {
2991 ++ssrc;
2992 }
2993 }
deadbeefab9b2d12015-10-14 11:33:11 -07002994
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002995 desc =
2996 cricket::GetFirstVideoContentDescription(modified_offer->description());
2997 ASSERT_TRUE(desc != NULL);
2998 for (StreamParams& stream : desc->mutable_streams()) {
2999 for (unsigned int& ssrc : stream.ssrcs) {
3000 ++ssrc;
3001 }
3002 }
3003
3004 EXPECT_TRUE(DoSetLocalDescription(modified_offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07003005 senders = pc_->GetSenders();
3006 EXPECT_EQ(2u, senders.size());
3007 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
3008 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
3009 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
3010 // changed.
3011}
3012
3013// This tests that the expected behavior occurs if a new session description is
3014// set with the same tracks, but on a different MediaStream.
Stefan Holmer55d6e7c2016-03-17 16:26:40 +01003015TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07003016 SignalSameTracksInSeparateMediaStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07003017 FakeConstraints constraints;
3018 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
3019 true);
3020 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07003021
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003022 rtc::scoped_refptr<StreamCollection> stream_collection =
3023 CreateStreamCollection(2, 1);
3024 pc_->AddStream(stream_collection->at(0));
3025 std::unique_ptr<SessionDescriptionInterface> offer;
3026 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3027 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07003028
deadbeefab9b2d12015-10-14 11:33:11 -07003029 auto senders = pc_->GetSenders();
3030 EXPECT_EQ(2u, senders.size());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003031 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
3032 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
deadbeefab9b2d12015-10-14 11:33:11 -07003033
3034 // Add a new MediaStream but with the same tracks as in the first stream.
3035 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
3036 webrtc::MediaStream::Create(kStreams[1]));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003037 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
3038 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
deadbeefab9b2d12015-10-14 11:33:11 -07003039 pc_->AddStream(stream_1);
3040
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003041 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3042 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07003043
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07003044 auto new_senders = pc_->GetSenders();
3045 // Should be the same senders as before, but with updated stream id.
3046 // Note that this behavior is subject to change in the future.
3047 // We may decide the PC should ignore existing tracks in AddStream.
3048 EXPECT_EQ(senders, new_senders);
3049 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
3050 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
deadbeefab9b2d12015-10-14 11:33:11 -07003051}
3052
zhihuang81c3a032016-11-17 12:06:24 -08003053// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
3054TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
3055 FakeConstraints constraints;
3056 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
3057 true);
3058 CreatePeerConnection(&constraints);
3059 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
3060 EXPECT_EQ(observer_.num_added_tracks_, 1);
3061 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
3062
3063 // Create and set the updated remote SDP.
3064 CreateAndSetRemoteOffer(kSdpStringWithStream1);
3065 EXPECT_EQ(observer_.num_added_tracks_, 2);
3066 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
3067}
3068
deadbeefd1a38b52016-12-10 13:15:33 -08003069// Test that when SetConfiguration is called and the configuration is
3070// changing, the next offer causes an ICE restart.
3071TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingIceRetart) {
3072 PeerConnectionInterface::RTCConfiguration config;
3073 config.type = PeerConnectionInterface::kRelay;
3074 // Need to pass default constraints to prevent disabling of DTLS...
3075 FakeConstraints default_constraints;
3076 CreatePeerConnection(config, &default_constraints);
3077 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3078
3079 // Do initial offer/answer so there's something to restart.
3080 CreateOfferAsLocalDescription();
3081 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3082
3083 // Grab the ufrags.
3084 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3085
3086 // Change ICE policy, which should trigger an ICE restart on the next offer.
3087 config.type = PeerConnectionInterface::kAll;
3088 EXPECT_TRUE(pc_->SetConfiguration(config));
3089 CreateOfferAsLocalDescription();
3090
3091 // Grab the new ufrags.
3092 std::vector<std::string> subsequent_ufrags =
3093 GetUfrags(pc_->local_description());
3094
3095 // Sanity check.
3096 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
3097 // Check that each ufrag is different.
3098 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
3099 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
3100 }
3101}
3102
3103// Test that when SetConfiguration is called and the configuration *isn't*
3104// changing, the next offer does *not* cause an ICE restart.
3105TEST_F(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRetart) {
3106 PeerConnectionInterface::RTCConfiguration config;
3107 config.type = PeerConnectionInterface::kRelay;
3108 // Need to pass default constraints to prevent disabling of DTLS...
3109 FakeConstraints default_constraints;
3110 CreatePeerConnection(config, &default_constraints);
3111 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3112
3113 // Do initial offer/answer so there's something to restart.
3114 CreateOfferAsLocalDescription();
3115 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3116
3117 // Grab the ufrags.
3118 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3119
3120 // Call SetConfiguration with a config identical to what the PC was
3121 // constructed with.
3122 EXPECT_TRUE(pc_->SetConfiguration(config));
3123 CreateOfferAsLocalDescription();
3124
3125 // Grab the new ufrags.
3126 std::vector<std::string> subsequent_ufrags =
3127 GetUfrags(pc_->local_description());
3128
3129 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
3130}
3131
3132// Test for a weird corner case scenario:
3133// 1. Audio/video session established.
3134// 2. SetConfiguration changes ICE config; ICE restart needed.
3135// 3. ICE restart initiated by remote peer, but only for one m= section.
3136// 4. Next createOffer should initiate an ICE restart, but only for the other
3137// m= section; it would be pointless to do an ICE restart for the m= section
3138// that was already restarted.
3139TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
3140 PeerConnectionInterface::RTCConfiguration config;
3141 config.type = PeerConnectionInterface::kRelay;
3142 // Need to pass default constraints to prevent disabling of DTLS...
3143 FakeConstraints default_constraints;
3144 CreatePeerConnection(config, &default_constraints);
3145 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3146
3147 // Do initial offer/answer so there's something to restart.
3148 CreateOfferAsLocalDescription();
3149 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3150
3151 // Change ICE policy, which should set the "needs-ice-restart" flag.
3152 config.type = PeerConnectionInterface::kAll;
3153 EXPECT_TRUE(pc_->SetConfiguration(config));
3154
3155 // Do ICE restart for the first m= section, initiated by remote peer.
3156 webrtc::JsepSessionDescription* remote_offer =
3157 new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer);
3158 EXPECT_TRUE(remote_offer->Initialize(kSdpStringWithStream1, nullptr));
3159 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3160 "modified";
3161 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3162 CreateAnswerAsLocalDescription();
3163
3164 // Grab the ufrags.
3165 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3166 ASSERT_EQ(2, initial_ufrags.size());
3167
3168 // Create offer and grab the new ufrags.
3169 CreateOfferAsLocalDescription();
3170 std::vector<std::string> subsequent_ufrags =
3171 GetUfrags(pc_->local_description());
3172 ASSERT_EQ(2, subsequent_ufrags.size());
3173
3174 // Ensure that only the ufrag for the second m= section changed.
3175 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3176 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3177}
3178
deadbeeffe4a8a42016-12-20 17:56:17 -08003179// Tests that the methods to return current/pending descriptions work as
3180// expected at different points in the offer/answer exchange. This test does
3181// one offer/answer exchange as the offerer, then another as the answerer.
3182TEST_F(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
3183 // This disables DTLS so we can apply an answer to ourselves.
3184 CreatePeerConnection();
3185
3186 // Create initial local offer and get SDP (which will also be used as
3187 // answer/pranswer);
3188 std::unique_ptr<SessionDescriptionInterface> offer;
3189 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3190 std::string sdp;
3191 EXPECT_TRUE(offer->ToString(&sdp));
3192
3193 // Set local offer.
3194 SessionDescriptionInterface* local_offer = offer.release();
3195 EXPECT_TRUE(DoSetLocalDescription(local_offer));
3196 EXPECT_EQ(local_offer, pc_->pending_local_description());
3197 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3198 EXPECT_EQ(nullptr, pc_->current_local_description());
3199 EXPECT_EQ(nullptr, pc_->current_remote_description());
3200
3201 // Set remote pranswer.
3202 SessionDescriptionInterface* remote_pranswer =
3203 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3204 sdp, nullptr);
3205 EXPECT_TRUE(DoSetRemoteDescription(remote_pranswer));
3206 EXPECT_EQ(local_offer, pc_->pending_local_description());
3207 EXPECT_EQ(remote_pranswer, pc_->pending_remote_description());
3208 EXPECT_EQ(nullptr, pc_->current_local_description());
3209 EXPECT_EQ(nullptr, pc_->current_remote_description());
3210
3211 // Set remote answer.
3212 SessionDescriptionInterface* remote_answer = webrtc::CreateSessionDescription(
3213 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3214 EXPECT_TRUE(DoSetRemoteDescription(remote_answer));
3215 EXPECT_EQ(nullptr, pc_->pending_local_description());
3216 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3217 EXPECT_EQ(local_offer, pc_->current_local_description());
3218 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3219
3220 // Set remote offer.
3221 SessionDescriptionInterface* remote_offer = webrtc::CreateSessionDescription(
3222 SessionDescriptionInterface::kOffer, sdp, nullptr);
3223 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3224 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3225 EXPECT_EQ(nullptr, pc_->pending_local_description());
3226 EXPECT_EQ(local_offer, pc_->current_local_description());
3227 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3228
3229 // Set local pranswer.
3230 SessionDescriptionInterface* local_pranswer =
3231 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3232 sdp, nullptr);
3233 EXPECT_TRUE(DoSetLocalDescription(local_pranswer));
3234 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3235 EXPECT_EQ(local_pranswer, pc_->pending_local_description());
3236 EXPECT_EQ(local_offer, pc_->current_local_description());
3237 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3238
3239 // Set local answer.
3240 SessionDescriptionInterface* local_answer = webrtc::CreateSessionDescription(
3241 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3242 EXPECT_TRUE(DoSetLocalDescription(local_answer));
3243 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3244 EXPECT_EQ(nullptr, pc_->pending_local_description());
3245 EXPECT_EQ(remote_offer, pc_->current_remote_description());
3246 EXPECT_EQ(local_answer, pc_->current_local_description());
3247}
3248
zhihuang77985012017-02-07 15:45:16 -08003249// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3250// after the PeerConnection is closed.
3251TEST_F(PeerConnectionInterfaceTest,
3252 StartAndStopLoggingAfterPeerConnectionClosed) {
3253 CreatePeerConnection();
3254 // The RtcEventLog will be reset when the PeerConnection is closed.
3255 pc_->Close();
3256
3257 rtc::PlatformFile file = 0;
3258 int64_t max_size_bytes = 1024;
3259 EXPECT_FALSE(pc_->StartRtcEventLog(file, max_size_bytes));
3260 pc_->StopRtcEventLog();
3261}
3262
deadbeef30952b42017-04-21 02:41:29 -07003263// Test that generated offers/answers include "ice-option:trickle".
3264TEST_F(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
3265 CreatePeerConnection();
3266
3267 // First, create an offer with audio/video.
3268 FakeConstraints constraints;
3269 constraints.SetMandatoryReceiveAudio(true);
3270 constraints.SetMandatoryReceiveVideo(true);
3271 std::unique_ptr<SessionDescriptionInterface> offer;
3272 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3273 cricket::SessionDescription* desc = offer->description();
3274 ASSERT_EQ(2u, desc->transport_infos().size());
3275 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3276 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3277
3278 // Apply the offer as a remote description, then create an answer.
3279 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3280 std::unique_ptr<SessionDescriptionInterface> answer;
3281 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3282 desc = answer->description();
3283 ASSERT_EQ(2u, desc->transport_infos().size());
3284 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3285 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3286}
3287
deadbeef1dcb1642017-03-29 21:08:16 -07003288// Test that ICE renomination isn't offered if it's not enabled in the PC's
3289// RTCConfiguration.
3290TEST_F(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
3291 PeerConnectionInterface::RTCConfiguration config;
3292 config.enable_ice_renomination = false;
3293 CreatePeerConnection(config, nullptr);
3294 AddVoiceStream("foo");
3295
3296 std::unique_ptr<SessionDescriptionInterface> offer;
3297 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3298 cricket::SessionDescription* desc = offer->description();
3299 EXPECT_EQ(1u, desc->transport_infos().size());
3300 EXPECT_FALSE(
3301 desc->transport_infos()[0].description.GetIceParameters().renomination);
3302}
3303
3304// Test that the ICE renomination option is present in generated offers/answers
3305// if it's enabled in the PC's RTCConfiguration.
3306TEST_F(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
3307 PeerConnectionInterface::RTCConfiguration config;
3308 config.enable_ice_renomination = true;
3309 CreatePeerConnection(config, nullptr);
3310 AddVoiceStream("foo");
3311
3312 std::unique_ptr<SessionDescriptionInterface> offer;
3313 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3314 cricket::SessionDescription* desc = offer->description();
3315 EXPECT_EQ(1u, desc->transport_infos().size());
3316 EXPECT_TRUE(
3317 desc->transport_infos()[0].description.GetIceParameters().renomination);
3318
3319 // Set the offer as a remote description, then create an answer and ensure it
3320 // has the renomination flag too.
3321 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3322 std::unique_ptr<SessionDescriptionInterface> answer;
3323 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3324 desc = answer->description();
3325 EXPECT_EQ(1u, desc->transport_infos().size());
3326 EXPECT_TRUE(
3327 desc->transport_infos()[0].description.GetIceParameters().renomination);
3328}
3329
3330// Test that if CreateOffer is called with the deprecated "offer to receive
3331// audio/video" constraints, they're processed and result in an offer with
3332// audio/video sections just as if RTCOfferAnswerOptions had been used.
3333TEST_F(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
3334 CreatePeerConnection();
3335
3336 FakeConstraints constraints;
3337 constraints.SetMandatoryReceiveAudio(true);
3338 constraints.SetMandatoryReceiveVideo(true);
3339 std::unique_ptr<SessionDescriptionInterface> offer;
3340 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3341
3342 cricket::SessionDescription* desc = offer->description();
3343 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3344 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3345 ASSERT_NE(nullptr, audio);
3346 ASSERT_NE(nullptr, video);
3347 EXPECT_FALSE(audio->rejected);
3348 EXPECT_FALSE(video->rejected);
3349}
3350
3351// Test that if CreateAnswer is called with the deprecated "offer to receive
3352// audio/video" constraints, they're processed and can be used to reject an
3353// offered m= section just as can be done with RTCOfferAnswerOptions;
3354TEST_F(PeerConnectionInterfaceTest, CreateAnswerWithOfferToReceiveConstraints) {
3355 CreatePeerConnection();
3356
3357 // First, create an offer with audio/video and apply it as a remote
3358 // description.
3359 FakeConstraints constraints;
3360 constraints.SetMandatoryReceiveAudio(true);
3361 constraints.SetMandatoryReceiveVideo(true);
3362 std::unique_ptr<SessionDescriptionInterface> offer;
3363 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3364 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3365
3366 // Now create answer that rejects audio/video.
3367 constraints.SetMandatoryReceiveAudio(false);
3368 constraints.SetMandatoryReceiveVideo(false);
3369 std::unique_ptr<SessionDescriptionInterface> answer;
3370 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3371
3372 cricket::SessionDescription* desc = answer->description();
3373 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3374 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3375 ASSERT_NE(nullptr, audio);
3376 ASSERT_NE(nullptr, video);
3377 EXPECT_TRUE(audio->rejected);
3378 EXPECT_TRUE(video->rejected);
3379}
3380
3381#ifdef HAVE_SCTP
3382#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3383 DataChannelOnlyOfferWithMaxBundlePolicy
3384#else
3385#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3386 DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy
3387#endif
3388
3389// Test that negotiation can succeed with a data channel only, and with the max
3390// bundle policy. Previously there was a bug that prevented this.
3391TEST_F(PeerConnectionInterfaceTest,
3392 MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy) {
3393 PeerConnectionInterface::RTCConfiguration config;
3394 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3395 CreatePeerConnection(config, nullptr);
3396
3397 // First, create an offer with only a data channel and apply it as a remote
3398 // description.
3399 pc_->CreateDataChannel("test", nullptr);
3400 std::unique_ptr<SessionDescriptionInterface> offer;
3401 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3402 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3403
3404 // Create and set answer as well.
3405 std::unique_ptr<SessionDescriptionInterface> answer;
3406 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3407 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
3408}
3409
zstein4b979802017-06-02 14:37:37 -07003410TEST_F(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
3411 CreatePeerConnection();
3412 PeerConnectionInterface::BitrateParameters bitrate;
3413 bitrate.current_bitrate_bps = rtc::Optional<int>(100000);
3414 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3415}
3416
3417TEST_F(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
3418 CreatePeerConnection();
3419 PeerConnectionInterface::BitrateParameters bitrate;
3420 bitrate.min_bitrate_bps = rtc::Optional<int>(-1);
3421 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3422}
3423
3424TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
3425 CreatePeerConnection();
3426 PeerConnectionInterface::BitrateParameters bitrate;
3427 bitrate.min_bitrate_bps = rtc::Optional<int>(5);
3428 bitrate.current_bitrate_bps = rtc::Optional<int>(3);
3429 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3430}
3431
3432TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
3433 CreatePeerConnection();
3434 PeerConnectionInterface::BitrateParameters bitrate;
3435 bitrate.current_bitrate_bps = rtc::Optional<int>(-1);
3436 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3437}
3438
3439TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
3440 CreatePeerConnection();
3441 PeerConnectionInterface::BitrateParameters bitrate;
3442 bitrate.current_bitrate_bps = rtc::Optional<int>(10);
3443 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3444 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3445}
3446
3447TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
3448 CreatePeerConnection();
3449 PeerConnectionInterface::BitrateParameters bitrate;
3450 bitrate.min_bitrate_bps = rtc::Optional<int>(10);
3451 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3452 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3453}
3454
3455TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
3456 CreatePeerConnection();
3457 PeerConnectionInterface::BitrateParameters bitrate;
3458 bitrate.max_bitrate_bps = rtc::Optional<int>(-1);
3459 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3460}
3461
Steve Anton038834f2017-07-14 15:59:59 -07003462// ice_regather_interval_range requires WebRTC to be configured for continual
3463// gathering already.
3464TEST_F(PeerConnectionInterfaceTest,
3465 SetIceRegatherIntervalRangeWithoutContinualGatheringFails) {
3466 PeerConnectionInterface::RTCConfiguration config;
3467 config.ice_regather_interval_range.emplace(1000, 2000);
3468 config.continual_gathering_policy =
3469 PeerConnectionInterface::ContinualGatheringPolicy::GATHER_ONCE;
3470 CreatePeerConnectionExpectFail(config);
3471}
3472
3473// Ensures that there is no error when ice_regather_interval_range is set with
3474// continual gathering enabled.
3475TEST_F(PeerConnectionInterfaceTest,
3476 SetIceRegatherIntervalRangeWithContinualGathering) {
3477 PeerConnectionInterface::RTCConfiguration config;
3478 config.ice_regather_interval_range.emplace(1000, 2000);
3479 config.continual_gathering_policy =
3480 PeerConnectionInterface::ContinualGatheringPolicy::GATHER_CONTINUALLY;
3481 CreatePeerConnection(config, nullptr);
3482}
3483
zstein4b979802017-06-02 14:37:37 -07003484// The current bitrate from Call's BitrateConfigMask is currently clamped by
3485// Call's BitrateConfig, which comes from the SDP or a default value. This test
3486// checks that a call to SetBitrate with a current bitrate that will be clamped
3487// succeeds.
3488TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
3489 CreatePeerConnection();
3490 PeerConnectionInterface::BitrateParameters bitrate;
3491 bitrate.current_bitrate_bps = rtc::Optional<int>(1);
3492 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3493}
3494
nisse51542be2016-02-12 02:27:06 -08003495class PeerConnectionMediaConfigTest : public testing::Test {
3496 protected:
3497 void SetUp() override {
zhihuang38ede132017-06-15 12:52:32 -07003498 pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
nisse51542be2016-02-12 02:27:06 -08003499 pcf_->Initialize();
3500 }
nisseeaabdf62017-05-05 02:23:02 -07003501 const cricket::MediaConfig TestCreatePeerConnection(
nisse51542be2016-02-12 02:27:06 -08003502 const PeerConnectionInterface::RTCConfiguration& config,
3503 const MediaConstraintsInterface *constraints) {
nisse51542be2016-02-12 02:27:06 -08003504
zhihuang9763d562016-08-05 11:14:50 -07003505 rtc::scoped_refptr<PeerConnectionInterface> pc(pcf_->CreatePeerConnection(
3506 config, constraints, nullptr, nullptr, &observer_));
nisse51542be2016-02-12 02:27:06 -08003507 EXPECT_TRUE(pc.get());
nisseeaabdf62017-05-05 02:23:02 -07003508 return pc->GetConfiguration().media_config;
nisse51542be2016-02-12 02:27:06 -08003509 }
3510
zhihuang9763d562016-08-05 11:14:50 -07003511 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
nisse51542be2016-02-12 02:27:06 -08003512 MockPeerConnectionObserver observer_;
3513};
3514
3515// This test verifies the default behaviour with no constraints and a
3516// default RTCConfiguration.
3517TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3518 PeerConnectionInterface::RTCConfiguration config;
3519 FakeConstraints constraints;
3520
3521 const cricket::MediaConfig& media_config =
3522 TestCreatePeerConnection(config, &constraints);
3523
3524 EXPECT_FALSE(media_config.enable_dscp);
nisse0db023a2016-03-01 04:29:59 -08003525 EXPECT_TRUE(media_config.video.enable_cpu_overuse_detection);
3526 EXPECT_FALSE(media_config.video.disable_prerenderer_smoothing);
3527 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003528}
3529
3530// This test verifies the DSCP constraint is recognized and passed to
nisse528b7932017-05-08 03:21:43 -07003531// the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003532TEST_F(PeerConnectionMediaConfigTest, TestDscpConstraintTrue) {
3533 PeerConnectionInterface::RTCConfiguration config;
3534 FakeConstraints constraints;
3535
3536 constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDscp, true);
3537 const cricket::MediaConfig& media_config =
3538 TestCreatePeerConnection(config, &constraints);
3539
3540 EXPECT_TRUE(media_config.enable_dscp);
3541}
3542
3543// This test verifies the cpu overuse detection constraint is
nisse528b7932017-05-08 03:21:43 -07003544// recognized and passed to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003545TEST_F(PeerConnectionMediaConfigTest, TestCpuOveruseConstraintFalse) {
3546 PeerConnectionInterface::RTCConfiguration config;
3547 FakeConstraints constraints;
3548
3549 constraints.AddOptional(
3550 webrtc::MediaConstraintsInterface::kCpuOveruseDetection, false);
3551 const cricket::MediaConfig media_config =
3552 TestCreatePeerConnection(config, &constraints);
3553
nisse0db023a2016-03-01 04:29:59 -08003554 EXPECT_FALSE(media_config.video.enable_cpu_overuse_detection);
nisse51542be2016-02-12 02:27:06 -08003555}
3556
3557// This test verifies that the disable_prerenderer_smoothing flag is
nisse528b7932017-05-08 03:21:43 -07003558// propagated from RTCConfiguration to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003559TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3560 PeerConnectionInterface::RTCConfiguration config;
3561 FakeConstraints constraints;
3562
Niels Möller71bdda02016-03-31 12:59:59 +02003563 config.set_prerenderer_smoothing(false);
nisse51542be2016-02-12 02:27:06 -08003564 const cricket::MediaConfig& media_config =
3565 TestCreatePeerConnection(config, &constraints);
3566
nisse0db023a2016-03-01 04:29:59 -08003567 EXPECT_TRUE(media_config.video.disable_prerenderer_smoothing);
3568}
3569
3570// This test verifies the suspend below min bitrate constraint is
nisse528b7932017-05-08 03:21:43 -07003571// recognized and passed to the PeerConnection.
nisse0db023a2016-03-01 04:29:59 -08003572TEST_F(PeerConnectionMediaConfigTest,
3573 TestSuspendBelowMinBitrateConstraintTrue) {
3574 PeerConnectionInterface::RTCConfiguration config;
3575 FakeConstraints constraints;
3576
3577 constraints.AddOptional(
3578 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3579 true);
3580 const cricket::MediaConfig media_config =
3581 TestCreatePeerConnection(config, &constraints);
3582
3583 EXPECT_TRUE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003584}
3585
deadbeefab9b2d12015-10-14 11:33:11 -07003586// The following tests verify that session options are created correctly.
deadbeefc80741f2015-10-22 13:14:45 -07003587// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of
3588// "verify options are converted correctly", should be "pass options into
3589// CreateOffer and verify the correct offer is produced."
deadbeefab9b2d12015-10-14 11:33:11 -07003590
3591TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) {
3592 RTCOfferAnswerOptions rtc_options;
3593 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3594
3595 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003596 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003597
3598 rtc_options.offer_to_receive_audio =
3599 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003600 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003601}
3602
3603TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) {
3604 RTCOfferAnswerOptions rtc_options;
3605 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3606
3607 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003608 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003609
3610 rtc_options.offer_to_receive_video =
3611 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003612 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003613}
3614
3615// Test that a MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003616// OfferToReceiveAudio and OfferToReceiveVideo options are set.
deadbeefab9b2d12015-10-14 11:33:11 -07003617TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) {
3618 RTCOfferAnswerOptions rtc_options;
3619 rtc_options.offer_to_receive_audio = 1;
3620 rtc_options.offer_to_receive_video = 1;
3621
3622 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003623 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003624 EXPECT_TRUE(options.has_audio());
3625 EXPECT_TRUE(options.has_video());
3626 EXPECT_TRUE(options.bundle_enabled);
3627}
3628
3629// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003630// OfferToReceiveAudio is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003631TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) {
3632 RTCOfferAnswerOptions rtc_options;
3633 rtc_options.offer_to_receive_audio = 1;
3634
3635 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003636 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003637 EXPECT_TRUE(options.has_audio());
3638 EXPECT_FALSE(options.has_video());
3639 EXPECT_TRUE(options.bundle_enabled);
3640}
3641
3642// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003643// the default OfferOptions are used.
deadbeefab9b2d12015-10-14 11:33:11 -07003644TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) {
3645 RTCOfferAnswerOptions rtc_options;
3646
3647 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003648 options.transport_options["audio"] = cricket::TransportOptions();
3649 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003650 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefc80741f2015-10-22 13:14:45 -07003651 EXPECT_TRUE(options.has_audio());
deadbeefab9b2d12015-10-14 11:33:11 -07003652 EXPECT_FALSE(options.has_video());
deadbeefc80741f2015-10-22 13:14:45 -07003653 EXPECT_TRUE(options.bundle_enabled);
deadbeefab9b2d12015-10-14 11:33:11 -07003654 EXPECT_TRUE(options.vad_enabled);
deadbeef0ed85b22016-02-23 17:24:52 -08003655 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3656 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003657}
3658
3659// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003660// OfferToReceiveVideo is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003661TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) {
3662 RTCOfferAnswerOptions rtc_options;
3663 rtc_options.offer_to_receive_audio = 0;
3664 rtc_options.offer_to_receive_video = 1;
3665
3666 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003667 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003668 EXPECT_FALSE(options.has_audio());
3669 EXPECT_TRUE(options.has_video());
3670 EXPECT_TRUE(options.bundle_enabled);
3671}
3672
3673// Test that a correct MediaSessionOptions is created for an offer if
3674// UseRtpMux is set to false.
3675TEST(CreateSessionOptionsTest,
3676 GetMediaSessionOptionsForOfferWithBundleDisabled) {
3677 RTCOfferAnswerOptions rtc_options;
3678 rtc_options.offer_to_receive_audio = 1;
3679 rtc_options.offer_to_receive_video = 1;
3680 rtc_options.use_rtp_mux = false;
3681
3682 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003683 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003684 EXPECT_TRUE(options.has_audio());
3685 EXPECT_TRUE(options.has_video());
3686 EXPECT_FALSE(options.bundle_enabled);
3687}
3688
3689// Test that a correct MediaSessionOptions is created to restart ice if
3690// IceRestart is set. It also tests that subsequent MediaSessionOptions don't
Taylor Brandstetterf475d362016-01-08 15:35:57 -08003691// have |audio_transport_options.ice_restart| etc. set.
deadbeefab9b2d12015-10-14 11:33:11 -07003692TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) {
3693 RTCOfferAnswerOptions rtc_options;
3694 rtc_options.ice_restart = true;
3695
3696 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003697 options.transport_options["audio"] = cricket::TransportOptions();
3698 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003699 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003700 EXPECT_TRUE(options.transport_options["audio"].ice_restart);
3701 EXPECT_TRUE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003702
3703 rtc_options = RTCOfferAnswerOptions();
htaaac2dea2016-03-10 13:35:55 -08003704 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003705 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3706 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003707}
3708
3709// Test that the MediaConstraints in an answer don't affect if audio and video
3710// is offered in an offer but that if kOfferToReceiveAudio or
3711// kOfferToReceiveVideo constraints are true in an offer, the media type will be
3712// included in subsequent answers.
3713TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) {
3714 FakeConstraints answer_c;
3715 answer_c.SetMandatoryReceiveAudio(true);
3716 answer_c.SetMandatoryReceiveVideo(true);
3717
3718 cricket::MediaSessionOptions answer_options;
3719 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options));
3720 EXPECT_TRUE(answer_options.has_audio());
3721 EXPECT_TRUE(answer_options.has_video());
3722
deadbeefc80741f2015-10-22 13:14:45 -07003723 RTCOfferAnswerOptions rtc_offer_options;
deadbeefab9b2d12015-10-14 11:33:11 -07003724
3725 cricket::MediaSessionOptions offer_options;
htaaac2dea2016-03-10 13:35:55 -08003726 EXPECT_TRUE(
3727 ExtractMediaSessionOptions(rtc_offer_options, false, &offer_options));
deadbeefc80741f2015-10-22 13:14:45 -07003728 EXPECT_TRUE(offer_options.has_audio());
htaaac2dea2016-03-10 13:35:55 -08003729 EXPECT_TRUE(offer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003730
deadbeefc80741f2015-10-22 13:14:45 -07003731 RTCOfferAnswerOptions updated_rtc_offer_options;
3732 updated_rtc_offer_options.offer_to_receive_audio = 1;
3733 updated_rtc_offer_options.offer_to_receive_video = 1;
deadbeefab9b2d12015-10-14 11:33:11 -07003734
3735 cricket::MediaSessionOptions updated_offer_options;
htaaac2dea2016-03-10 13:35:55 -08003736 EXPECT_TRUE(ExtractMediaSessionOptions(updated_rtc_offer_options, false,
htaa2a49d92016-03-04 02:51:39 -08003737 &updated_offer_options));
deadbeefab9b2d12015-10-14 11:33:11 -07003738 EXPECT_TRUE(updated_offer_options.has_audio());
3739 EXPECT_TRUE(updated_offer_options.has_video());
3740
3741 // Since an offer has been created with both audio and video, subsequent
3742 // offers and answers should contain both audio and video.
3743 // Answers will only contain the media types that exist in the offer
3744 // regardless of the value of |updated_answer_options.has_audio| and
3745 // |updated_answer_options.has_video|.
3746 FakeConstraints updated_answer_c;
3747 answer_c.SetMandatoryReceiveAudio(false);
3748 answer_c.SetMandatoryReceiveVideo(false);
3749
3750 cricket::MediaSessionOptions updated_answer_options;
3751 EXPECT_TRUE(
3752 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options));
3753 EXPECT_TRUE(updated_answer_options.has_audio());
3754 EXPECT_TRUE(updated_answer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003755}
deadbeef3edec7c2016-12-10 11:44:26 -08003756
deadbeef293e9262017-01-11 12:28:30 -08003757// Tests a few random fields being different.
3758TEST(RTCConfigurationTest, ComparisonOperators) {
3759 PeerConnectionInterface::RTCConfiguration a;
3760 PeerConnectionInterface::RTCConfiguration b;
3761 EXPECT_EQ(a, b);
3762
3763 PeerConnectionInterface::RTCConfiguration c;
3764 c.servers.push_back(PeerConnectionInterface::IceServer());
3765 EXPECT_NE(a, c);
3766
3767 PeerConnectionInterface::RTCConfiguration d;
3768 d.type = PeerConnectionInterface::kRelay;
3769 EXPECT_NE(a, d);
3770
3771 PeerConnectionInterface::RTCConfiguration e;
3772 e.audio_jitter_buffer_max_packets = 5;
3773 EXPECT_NE(a, e);
3774
3775 PeerConnectionInterface::RTCConfiguration f;
3776 f.ice_connection_receiving_timeout = 1337;
3777 EXPECT_NE(a, f);
3778
3779 PeerConnectionInterface::RTCConfiguration g;
3780 g.disable_ipv6 = true;
3781 EXPECT_NE(a, g);
3782
3783 PeerConnectionInterface::RTCConfiguration h(
3784 PeerConnectionInterface::RTCConfigurationType::kAggressive);
3785 EXPECT_NE(a, h);
3786}
korniltsev.anatolyec390b52017-07-24 17:00:25 -07003787
3788// This test ensures OnRenegotiationNeeded is called when we add track with
3789// MediaStream -> AddTrack in the same way it is called when we add track with
3790// PeerConnection -> AddTrack.
3791// The test can be removed once addStream is rewritten in terms of addTrack
3792// https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
3793TEST_F(PeerConnectionInterfaceTest, MediaStreamAddTrackRemoveTrackRenegotiate) {
3794 CreatePeerConnectionWithoutDtls();
3795 rtc::scoped_refptr<MediaStreamInterface> stream(
3796 pc_factory_->CreateLocalMediaStream(kStreamLabel1));
3797 pc_->AddStream(stream);
3798 rtc::scoped_refptr<AudioTrackInterface> audio_track(
3799 pc_factory_->CreateAudioTrack("audio_track", nullptr));
3800 rtc::scoped_refptr<VideoTrackInterface> video_track(
3801 pc_factory_->CreateVideoTrack(
3802 "video_track", pc_factory_->CreateVideoSource(
3803 std::unique_ptr<cricket::VideoCapturer>(
3804 new cricket::FakeVideoCapturer()))));
3805 stream->AddTrack(audio_track);
3806 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3807 observer_.renegotiation_needed_ = false;
3808
3809 stream->AddTrack(video_track);
3810 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3811 observer_.renegotiation_needed_ = false;
3812
3813 stream->RemoveTrack(audio_track);
3814 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3815 observer_.renegotiation_needed_ = false;
3816
3817 stream->RemoveTrack(video_track);
3818 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
3819 observer_.renegotiation_needed_ = false;
3820}