blob: 30567b95d387ac6d872dac3dd0a05745188c6f62 [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],
perkjf1377f72017-07-07 16:38:28 -0700463 webrtc::FakeVideoTrackSource::Create(),
464 rtc::Thread::Current()));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700465 stream->AddTrack(video_track);
466 }
deadbeefab9b2d12015-10-14 11:33:11 -0700467
468 local_collection->AddStream(stream);
469 }
470 return local_collection;
471}
472
473// Check equality of StreamCollections.
474bool CompareStreamCollections(StreamCollectionInterface* s1,
475 StreamCollectionInterface* s2) {
476 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
477 return false;
478 }
479
480 for (size_t i = 0; i != s1->count(); ++i) {
481 if (s1->at(i)->label() != s2->at(i)->label()) {
482 return false;
483 }
484 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
485 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
486 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
487 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
488
489 if (audio_tracks1.size() != audio_tracks2.size()) {
490 return false;
491 }
492 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
493 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
494 return false;
495 }
496 }
497 if (video_tracks1.size() != video_tracks2.size()) {
498 return false;
499 }
500 for (size_t j = 0; j != video_tracks1.size(); ++j) {
501 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
502 return false;
503 }
504 }
505 }
506 return true;
507}
508
perkjd61bf802016-03-24 03:16:19 -0700509// Helper class to test Observer.
510class MockTrackObserver : public ObserverInterface {
511 public:
512 explicit MockTrackObserver(NotifierInterface* notifier)
513 : notifier_(notifier) {
514 notifier_->RegisterObserver(this);
515 }
516
517 ~MockTrackObserver() { Unregister(); }
518
519 void Unregister() {
520 if (notifier_) {
521 notifier_->UnregisterObserver(this);
522 notifier_ = nullptr;
523 }
524 }
525
526 MOCK_METHOD0(OnChanged, void());
527
528 private:
529 NotifierInterface* notifier_;
530};
531
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532class MockPeerConnectionObserver : public PeerConnectionObserver {
533 public:
deadbeefab9b2d12015-10-14 11:33:11 -0700534 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {}
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200535 virtual ~MockPeerConnectionObserver() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 }
537 void SetPeerConnectionInterface(PeerConnectionInterface* pc) {
538 pc_ = pc;
539 if (pc) {
540 state_ = pc_->signaling_state();
541 }
542 }
nisseef8b61e2016-04-29 06:09:15 -0700543 void OnSignalingChange(
544 PeerConnectionInterface::SignalingState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000545 EXPECT_EQ(pc_->signaling_state(), new_state);
546 state_ = new_state;
547 }
deadbeefab9b2d12015-10-14 11:33:11 -0700548
549 MediaStreamInterface* RemoteStream(const std::string& label) {
550 return remote_streams_->find(label);
551 }
552 StreamCollectionInterface* remote_streams() const { return remote_streams_; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700553 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 last_added_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700555 remote_streams_->AddStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556 }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700557 void OnRemoveStream(
558 rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 last_removed_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700560 remote_streams_->RemoveStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561 }
perkjdfb769d2016-02-09 03:09:43 -0800562 void OnRenegotiationNeeded() override { renegotiation_needed_ = true; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700563 void OnDataChannel(
564 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 last_datachannel_ = data_channel;
566 }
567
perkjdfb769d2016-02-09 03:09:43 -0800568 void OnIceConnectionChange(
569 PeerConnectionInterface::IceConnectionState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 EXPECT_EQ(pc_->ice_connection_state(), new_state);
zhihuang81c3a032016-11-17 12:06:24 -0800571 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 }
perkjdfb769d2016-02-09 03:09:43 -0800573 void OnIceGatheringChange(
574 PeerConnectionInterface::IceGatheringState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 EXPECT_EQ(pc_->ice_gathering_state(), new_state);
perkjdfb769d2016-02-09 03:09:43 -0800576 ice_complete_ = new_state == PeerConnectionInterface::kIceGatheringComplete;
zhihuang81c3a032016-11-17 12:06:24 -0800577 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 }
perkjdfb769d2016-02-09 03:09:43 -0800579 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew,
581 pc_->ice_gathering_state());
582
583 std::string sdp;
584 EXPECT_TRUE(candidate->ToString(&sdp));
585 EXPECT_LT(0u, sdp.size());
586 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(),
587 candidate->sdp_mline_index(), sdp, NULL));
588 EXPECT_TRUE(last_candidate_.get() != NULL);
zhihuang81c3a032016-11-17 12:06:24 -0800589 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700590 }
591
592 void OnIceCandidatesRemoved(
593 const std::vector<cricket::Candidate>& candidates) override {
zhihuang81c3a032016-11-17 12:06:24 -0800594 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700595 }
596
597 void OnIceConnectionReceivingChange(bool receiving) override {
zhihuang81c3a032016-11-17 12:06:24 -0800598 callback_triggered_ = true;
599 }
600
zhihuangc63b8942016-12-02 15:41:10 -0800601 void OnAddTrack(
602 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
603 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
604 streams) override {
zhihuang81c3a032016-11-17 12:06:24 -0800605 EXPECT_TRUE(receiver != nullptr);
606 num_added_tracks_++;
607 last_added_track_label_ = receiver->id();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000608 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000609
610 // Returns the label of the last added stream.
611 // Empty string if no stream have been added.
612 std::string GetLastAddedStreamLabel() {
613 if (last_added_stream_.get())
614 return last_added_stream_->label();
615 return "";
616 }
617 std::string GetLastRemovedStreamLabel() {
618 if (last_removed_stream_.get())
619 return last_removed_stream_->label();
620 return "";
621 }
622
zhihuang9763d562016-08-05 11:14:50 -0700623 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624 PeerConnectionInterface::SignalingState state_;
kwibergd1fe2812016-04-27 06:47:29 -0700625 std::unique_ptr<IceCandidateInterface> last_candidate_;
zhihuang9763d562016-08-05 11:14:50 -0700626 rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
deadbeefab9b2d12015-10-14 11:33:11 -0700627 rtc::scoped_refptr<StreamCollection> remote_streams_;
628 bool renegotiation_needed_ = false;
629 bool ice_complete_ = false;
zhihuang81c3a032016-11-17 12:06:24 -0800630 bool callback_triggered_ = false;
631 int num_added_tracks_ = 0;
632 std::string last_added_track_label_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633
634 private:
zhihuang9763d562016-08-05 11:14:50 -0700635 rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
636 rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637};
638
639} // namespace
deadbeefab9b2d12015-10-14 11:33:11 -0700640
nisse528b7932017-05-08 03:21:43 -0700641// The PeerConnectionMediaConfig tests below verify that configuration and
642// constraints are propagated into the PeerConnection's MediaConfig. These
643// settings are intended for MediaChannel constructors, but that is not
644// exercised by these unittest.
zhihuang29ff8442016-07-27 11:07:25 -0700645class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
646 public:
zhihuang38ede132017-06-15 12:52:32 -0700647 static rtc::scoped_refptr<PeerConnectionFactoryForTest>
648 CreatePeerConnectionFactoryForTest() {
649 auto audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
650 auto audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
651
652 auto media_engine = std::unique_ptr<cricket::MediaEngineInterface>(
653 cricket::WebRtcMediaEngineFactory::Create(
654 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr,
peaha9cc40b2017-06-29 08:32:09 -0700655 nullptr, nullptr, webrtc::AudioProcessing::Create()));
zhihuang38ede132017-06-15 12:52:32 -0700656
657 std::unique_ptr<webrtc::CallFactoryInterface> call_factory =
658 webrtc::CreateCallFactory();
659
660 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory =
661 webrtc::CreateRtcEventLogFactory();
662
663 return new rtc::RefCountedObject<PeerConnectionFactoryForTest>(
664 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
665 nullptr, audio_encoder_factory, audio_decoder_factory, nullptr, nullptr,
666 nullptr, std::move(media_engine), std::move(call_factory),
667 std::move(event_log_factory));
668 }
669
670 PeerConnectionFactoryForTest(
671 rtc::Thread* network_thread,
672 rtc::Thread* worker_thread,
673 rtc::Thread* signaling_thread,
674 webrtc::AudioDeviceModule* default_adm,
675 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
676 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
677 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
678 cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
679 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
680 std::unique_ptr<cricket::MediaEngineInterface> media_engine,
681 std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
682 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory)
683 : webrtc::PeerConnectionFactory(network_thread,
684 worker_thread,
685 signaling_thread,
686 default_adm,
687 audio_encoder_factory,
688 audio_decoder_factory,
689 video_encoder_factory,
690 video_decoder_factory,
691 audio_mixer,
692 std::move(media_engine),
693 std::move(call_factory),
694 std::move(event_log_factory)) {}
kwiberg1e4e8cb2017-01-31 01:48:08 -0800695
zhihuang29ff8442016-07-27 11:07:25 -0700696 cricket::TransportController* CreateTransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700697 cricket::PortAllocator* port_allocator,
698 bool redetermine_role_on_ice_restart) override {
zhihuang29ff8442016-07-27 11:07:25 -0700699 transport_controller = new cricket::TransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700700 rtc::Thread::Current(), rtc::Thread::Current(), port_allocator,
deadbeef7914b8c2017-04-21 03:23:33 -0700701 redetermine_role_on_ice_restart, rtc::CryptoOptions());
zhihuang29ff8442016-07-27 11:07:25 -0700702 return transport_controller;
703 }
704
705 cricket::TransportController* transport_controller;
zhihuang29ff8442016-07-27 11:07:25 -0700706};
707
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708class PeerConnectionInterfaceTest : public testing::Test {
709 protected:
deadbeef9a6f4d42017-05-15 19:43:33 -0700710 PeerConnectionInterfaceTest()
deadbeef98e186c2017-05-16 18:00:06 -0700711 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
phoglund37ebcf02016-01-08 05:04:57 -0800712#ifdef WEBRTC_ANDROID
713 webrtc::InitializeAndroidObjects();
714#endif
715 }
716
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717 virtual void SetUp() {
718 pc_factory_ = webrtc::CreatePeerConnectionFactory(
danilchape9021a32016-05-17 01:52:02 -0700719 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
720 nullptr, nullptr, nullptr);
721 ASSERT_TRUE(pc_factory_);
zhihuang29ff8442016-07-27 11:07:25 -0700722 pc_factory_for_test_ =
zhihuang38ede132017-06-15 12:52:32 -0700723 PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
zhihuang29ff8442016-07-27 11:07:25 -0700724 pc_factory_for_test_->Initialize();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 }
726
727 void CreatePeerConnection() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700728 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(), nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 }
730
deadbeef293e9262017-01-11 12:28:30 -0800731 // DTLS does not work in a loopback call, so is disabled for most of the
732 // tests in this file.
733 void CreatePeerConnectionWithoutDtls() {
734 FakeConstraints no_dtls_constraints;
735 no_dtls_constraints.AddMandatory(
736 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
737
738 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
739 &no_dtls_constraints);
740 }
741
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700743 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
744 constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 }
746
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700747 void CreatePeerConnectionWithIceTransportsType(
748 PeerConnectionInterface::IceTransportsType type) {
749 PeerConnectionInterface::RTCConfiguration config;
750 config.type = type;
751 return CreatePeerConnection(config, nullptr);
752 }
753
754 void CreatePeerConnectionWithIceServer(const std::string& uri,
755 const std::string& password) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800756 PeerConnectionInterface::RTCConfiguration config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757 PeerConnectionInterface::IceServer server;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700758 server.uri = uri;
759 server.password = password;
760 config.servers.push_back(server);
761 CreatePeerConnection(config, nullptr);
762 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700764 void CreatePeerConnection(PeerConnectionInterface::RTCConfiguration config,
765 webrtc::MediaConstraintsInterface* constraints) {
kwibergd1fe2812016-04-27 06:47:29 -0700766 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800767 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
768 port_allocator_ = port_allocator.get();
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000769
deadbeef1dcb1642017-03-29 21:08:16 -0700770 // Create certificate generator unless DTLS constraint is explicitly set to
771 // false.
Henrik Boströmd79599d2016-06-01 13:58:50 +0200772 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000773 bool dtls;
774 if (FindConstraint(constraints,
775 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
776 &dtls,
Henrik Boström5e56c592015-08-11 10:33:13 +0200777 nullptr) && dtls) {
deadbeef8662f942017-01-20 21:20:51 -0800778 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
779 cert_generator.reset(fake_certificate_generator_);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000780 }
Henrik Boströmd79599d2016-06-01 13:58:50 +0200781 pc_ = pc_factory_->CreatePeerConnection(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800782 config, constraints, std::move(port_allocator),
Henrik Boströmd79599d2016-06-01 13:58:50 +0200783 std::move(cert_generator), &observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784 ASSERT_TRUE(pc_.get() != NULL);
785 observer_.SetPeerConnectionInterface(pc_.get());
786 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
787 }
788
deadbeef0a6c4ca2015-10-06 11:38:28 -0700789 void CreatePeerConnectionExpectFail(const std::string& uri) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800790 PeerConnectionInterface::RTCConfiguration config;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700791 PeerConnectionInterface::IceServer server;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700792 server.uri = uri;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800793 config.servers.push_back(server);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700794
zhihuang9763d562016-08-05 11:14:50 -0700795 rtc::scoped_refptr<PeerConnectionInterface> pc;
hbosd7973cc2016-05-27 06:08:53 -0700796 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr,
797 &observer_);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800798 EXPECT_EQ(nullptr, pc);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700799 }
800
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801 void CreatePeerConnectionWithDifferentConfigurations() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700802 CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800803 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
804 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
805 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 EXPECT_EQ(kDefaultStunPort,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800807 port_allocator_->stun_servers().begin()->port());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808
deadbeef0a6c4ca2015-10-06 11:38:28 -0700809 CreatePeerConnectionExpectFail(kStunInvalidPort);
810 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
811 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700813 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800814 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
815 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 EXPECT_EQ(kTurnUsername,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800817 port_allocator_->turn_servers()[0].credentials.username);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818 EXPECT_EQ(kTurnPassword,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800819 port_allocator_->turn_servers()[0].credentials.password);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 EXPECT_EQ(kTurnHostname,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800821 port_allocator_->turn_servers()[0].ports[0].address.hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 }
823
824 void ReleasePeerConnection() {
825 pc_ = NULL;
826 observer_.SetPeerConnectionInterface(NULL);
827 }
828
deadbeefab9b2d12015-10-14 11:33:11 -0700829 void AddVideoStream(const std::string& label) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700831 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700833 rtc::scoped_refptr<VideoTrackSourceInterface> video_source(
deadbeef112b2e92017-02-10 20:13:37 -0800834 pc_factory_->CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(
835 new cricket::FakeVideoCapturer()),
836 NULL));
zhihuang9763d562016-08-05 11:14:50 -0700837 rtc::scoped_refptr<VideoTrackInterface> video_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838 pc_factory_->CreateVideoTrack(label + "v0", video_source));
839 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000840 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
842 observer_.renegotiation_needed_ = false;
843 }
844
845 void AddVoiceStream(const std::string& label) {
846 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700847 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700849 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000850 pc_factory_->CreateAudioTrack(label + "a0", NULL));
851 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000852 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
854 observer_.renegotiation_needed_ = false;
855 }
856
857 void AddAudioVideoStream(const std::string& stream_label,
858 const std::string& audio_track_label,
859 const std::string& video_track_label) {
860 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700861 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862 pc_factory_->CreateLocalMediaStream(stream_label));
zhihuang9763d562016-08-05 11:14:50 -0700863 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864 pc_factory_->CreateAudioTrack(
865 audio_track_label, static_cast<AudioSourceInterface*>(NULL)));
866 stream->AddTrack(audio_track.get());
zhihuang9763d562016-08-05 11:14:50 -0700867 rtc::scoped_refptr<VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -0700868 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -0800869 video_track_label, pc_factory_->CreateVideoSource(
870 std::unique_ptr<cricket::VideoCapturer>(
871 new cricket::FakeVideoCapturer()))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000873 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
875 observer_.renegotiation_needed_ = false;
876 }
877
kwibergd1fe2812016-04-27 06:47:29 -0700878 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700879 bool offer,
880 MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000881 rtc::scoped_refptr<MockCreateSessionDescriptionObserver>
882 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883 MockCreateSessionDescriptionObserver>());
884 if (offer) {
deadbeefc80741f2015-10-22 13:14:45 -0700885 pc_->CreateOffer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000886 } else {
deadbeefc80741f2015-10-22 13:14:45 -0700887 pc_->CreateAnswer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 }
889 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700890 *desc = observer->MoveDescription();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891 return observer->result();
892 }
893
kwibergd1fe2812016-04-27 06:47:29 -0700894 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700895 MediaConstraintsInterface* constraints) {
896 return DoCreateOfferAnswer(desc, true, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897 }
898
kwibergd1fe2812016-04-27 06:47:29 -0700899 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700900 MediaConstraintsInterface* constraints) {
901 return DoCreateOfferAnswer(desc, false, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902 }
903
904 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000905 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
906 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907 MockSetSessionDescriptionObserver>());
908 if (local) {
909 pc_->SetLocalDescription(observer, desc);
910 } else {
911 pc_->SetRemoteDescription(observer, desc);
912 }
zhihuang29ff8442016-07-27 11:07:25 -0700913 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
914 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
915 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916 return observer->result();
917 }
918
919 bool DoSetLocalDescription(SessionDescriptionInterface* desc) {
920 return DoSetSessionDescription(desc, true);
921 }
922
923 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) {
924 return DoSetSessionDescription(desc, false);
925 }
926
927 // Calls PeerConnection::GetStats and check the return value.
928 // It does not verify the values in the StatReports since a RTCP packet might
929 // be required.
930 bool DoGetStats(MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000931 rtc::scoped_refptr<MockStatsObserver> observer(
932 new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000933 if (!pc_->GetStats(
934 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard))
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935 return false;
936 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
937 return observer->called();
938 }
939
940 void InitiateCall() {
deadbeef293e9262017-01-11 12:28:30 -0800941 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 // Create a local stream with audio&video tracks.
943 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
944 CreateOfferReceiveAnswer();
945 }
946
947 // Verify that RTP Header extensions has been negotiated for audio and video.
948 void VerifyRemoteRtpHeaderExtensions() {
949 const cricket::MediaContentDescription* desc =
950 cricket::GetFirstAudioContentDescription(
951 pc_->remote_description()->description());
952 ASSERT_TRUE(desc != NULL);
953 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
954
955 desc = cricket::GetFirstVideoContentDescription(
956 pc_->remote_description()->description());
957 ASSERT_TRUE(desc != NULL);
958 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
959 }
960
961 void CreateOfferAsRemoteDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700962 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -0700963 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964 std::string sdp;
965 EXPECT_TRUE(offer->ToString(&sdp));
966 SessionDescriptionInterface* remote_offer =
967 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
968 sdp, NULL);
969 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
970 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
971 }
972
deadbeefab9b2d12015-10-14 11:33:11 -0700973 void CreateAndSetRemoteOffer(const std::string& sdp) {
974 SessionDescriptionInterface* remote_offer =
975 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
976 sdp, nullptr);
977 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
978 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
979 }
980
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981 void CreateAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700982 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -0700983 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000984
985 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
986 // audio codec change, even if the parameter has nothing to do with
987 // receiving. Not all parameters are serialized to SDP.
988 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
989 // the SessionDescription, it is necessary to do that here to in order to
990 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
991 // https://code.google.com/p/webrtc/issues/detail?id=1356
992 std::string sdp;
993 EXPECT_TRUE(answer->ToString(&sdp));
994 SessionDescriptionInterface* new_answer =
995 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
996 sdp, NULL);
997 EXPECT_TRUE(DoSetLocalDescription(new_answer));
998 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
999 }
1000
1001 void CreatePrAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001002 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001003 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001004
1005 std::string sdp;
1006 EXPECT_TRUE(answer->ToString(&sdp));
1007 SessionDescriptionInterface* pr_answer =
1008 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
1009 sdp, NULL);
1010 EXPECT_TRUE(DoSetLocalDescription(pr_answer));
1011 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
1012 }
1013
1014 void CreateOfferReceiveAnswer() {
1015 CreateOfferAsLocalDescription();
1016 std::string sdp;
1017 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1018 CreateAnswerAsRemoteDescription(sdp);
1019 }
1020
1021 void CreateOfferAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001022 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001023 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1025 // audio codec change, even if the parameter has nothing to do with
1026 // receiving. Not all parameters are serialized to SDP.
1027 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1028 // the SessionDescription, it is necessary to do that here to in order to
1029 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1030 // https://code.google.com/p/webrtc/issues/detail?id=1356
1031 std::string sdp;
1032 EXPECT_TRUE(offer->ToString(&sdp));
1033 SessionDescriptionInterface* new_offer =
1034 webrtc::CreateSessionDescription(
1035 SessionDescriptionInterface::kOffer,
1036 sdp, NULL);
1037
1038 EXPECT_TRUE(DoSetLocalDescription(new_offer));
1039 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
mallinath@webrtc.org68cbd012014-01-22 00:16:46 +00001040 // Wait for the ice_complete message, so that SDP will have candidates.
1041 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001042 }
1043
deadbeefab9b2d12015-10-14 11:33:11 -07001044 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
1046 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001047 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001048 EXPECT_TRUE(DoSetRemoteDescription(answer));
1049 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1050 }
1051
deadbeefab9b2d12015-10-14 11:33:11 -07001052 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053 webrtc::JsepSessionDescription* pr_answer =
1054 new webrtc::JsepSessionDescription(
1055 SessionDescriptionInterface::kPrAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001056 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057 EXPECT_TRUE(DoSetRemoteDescription(pr_answer));
1058 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
1059 webrtc::JsepSessionDescription* answer =
1060 new webrtc::JsepSessionDescription(
1061 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001062 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063 EXPECT_TRUE(DoSetRemoteDescription(answer));
1064 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1065 }
1066
1067 // Help function used for waiting until a the last signaled remote stream has
1068 // the same label as |stream_label|. In a few of the tests in this file we
1069 // answer with the same session description as we offer and thus we can
1070 // check if OnAddStream have been called with the same stream as we offer to
1071 // send.
1072 void WaitAndVerifyOnAddStream(const std::string& stream_label) {
1073 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout);
1074 }
1075
1076 // Creates an offer and applies it as a local session description.
1077 // Creates an answer with the same SDP an the offer but removes all lines
1078 // that start with a:ssrc"
1079 void CreateOfferReceiveAnswerWithoutSsrc() {
1080 CreateOfferAsLocalDescription();
1081 std::string sdp;
1082 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1083 SetSsrcToZero(&sdp);
1084 CreateAnswerAsRemoteDescription(sdp);
1085 }
1086
deadbeefab9b2d12015-10-14 11:33:11 -07001087 // This function creates a MediaStream with label kStreams[0] and
1088 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
1089 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
kwiberg2bbff992016-03-16 11:03:04 -07001090 // is returned and the MediaStream is stored in
deadbeefab9b2d12015-10-14 11:33:11 -07001091 // |reference_collection_|
kwibergd1fe2812016-04-27 06:47:29 -07001092 std::unique_ptr<SessionDescriptionInterface>
kwiberg2bbff992016-03-16 11:03:04 -07001093 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1094 size_t number_of_video_tracks) {
1095 EXPECT_LE(number_of_audio_tracks, 2u);
1096 EXPECT_LE(number_of_video_tracks, 2u);
deadbeefab9b2d12015-10-14 11:33:11 -07001097
1098 reference_collection_ = StreamCollection::Create();
1099 std::string sdp_ms1 = std::string(kSdpStringInit);
1100
1101 std::string mediastream_label = kStreams[0];
1102
1103 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
1104 webrtc::MediaStream::Create(mediastream_label));
1105 reference_collection_->AddStream(stream);
1106
1107 if (number_of_audio_tracks > 0) {
1108 sdp_ms1 += std::string(kSdpStringAudio);
1109 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1110 AddAudioTrack(kAudioTracks[0], stream);
1111 }
1112 if (number_of_audio_tracks > 1) {
1113 sdp_ms1 += kSdpStringMs1Audio1;
1114 AddAudioTrack(kAudioTracks[1], stream);
1115 }
1116
1117 if (number_of_video_tracks > 0) {
1118 sdp_ms1 += std::string(kSdpStringVideo);
1119 sdp_ms1 += std::string(kSdpStringMs1Video0);
1120 AddVideoTrack(kVideoTracks[0], stream);
1121 }
1122 if (number_of_video_tracks > 1) {
1123 sdp_ms1 += kSdpStringMs1Video1;
1124 AddVideoTrack(kVideoTracks[1], stream);
1125 }
1126
kwibergd1fe2812016-04-27 06:47:29 -07001127 return std::unique_ptr<SessionDescriptionInterface>(
kwiberg2bbff992016-03-16 11:03:04 -07001128 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1129 sdp_ms1, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001130 }
1131
1132 void AddAudioTrack(const std::string& track_id,
1133 MediaStreamInterface* stream) {
1134 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1135 webrtc::AudioTrack::Create(track_id, nullptr));
1136 ASSERT_TRUE(stream->AddTrack(audio_track));
1137 }
1138
1139 void AddVideoTrack(const std::string& track_id,
1140 MediaStreamInterface* stream) {
1141 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -07001142 webrtc::VideoTrack::Create(track_id,
perkjf1377f72017-07-07 16:38:28 -07001143 webrtc::FakeVideoTrackSource::Create(),
1144 rtc::Thread::Current()));
deadbeefab9b2d12015-10-14 11:33:11 -07001145 ASSERT_TRUE(stream->AddTrack(video_track));
1146 }
1147
kwibergfd8be342016-05-14 19:44:11 -07001148 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
deadbeef293e9262017-01-11 12:28:30 -08001149 CreatePeerConnectionWithoutDtls();
zhihuang8f65cdf2016-05-06 18:40:30 -07001150 AddVoiceStream(kStreamLabel1);
kwibergfd8be342016-05-14 19:44:11 -07001151 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001152 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1153 return offer;
1154 }
1155
kwibergfd8be342016-05-14 19:44:11 -07001156 std::unique_ptr<SessionDescriptionInterface>
zhihuang8f65cdf2016-05-06 18:40:30 -07001157 CreateAnswerWithOneAudioStream() {
kwibergfd8be342016-05-14 19:44:11 -07001158 std::unique_ptr<SessionDescriptionInterface> offer =
zhihuang8f65cdf2016-05-06 18:40:30 -07001159 CreateOfferWithOneAudioStream();
1160 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergfd8be342016-05-14 19:44:11 -07001161 std::unique_ptr<SessionDescriptionInterface> answer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001162 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1163 return answer;
1164 }
1165
1166 const std::string& GetFirstAudioStreamCname(
1167 const SessionDescriptionInterface* desc) {
1168 const cricket::ContentInfo* audio_content =
1169 cricket::GetFirstAudioContent(desc->description());
1170 const cricket::AudioContentDescription* audio_desc =
1171 static_cast<const cricket::AudioContentDescription*>(
1172 audio_content->description);
1173 return audio_desc->streams()[0].cname;
1174 }
1175
deadbeef9a6f4d42017-05-15 19:43:33 -07001176 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1177 rtc::AutoSocketServerThread main_;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08001178 cricket::FakePortAllocator* port_allocator_ = nullptr;
deadbeef8662f942017-01-20 21:20:51 -08001179 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
zhihuang9763d562016-08-05 11:14:50 -07001180 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1181 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_;
1182 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183 MockPeerConnectionObserver observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001184 rtc::scoped_refptr<StreamCollection> reference_collection_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001185};
1186
zhihuang29ff8442016-07-27 11:07:25 -07001187// Test that no callbacks on the PeerConnectionObserver are called after the
1188// PeerConnection is closed.
1189TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) {
zhihuang9763d562016-08-05 11:14:50 -07001190 rtc::scoped_refptr<PeerConnectionInterface> pc(
zhihuang29ff8442016-07-27 11:07:25 -07001191 pc_factory_for_test_->CreatePeerConnection(
1192 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr,
1193 nullptr, &observer_));
1194 observer_.SetPeerConnectionInterface(pc.get());
1195 pc->Close();
1196
1197 // No callbacks is expected to be called.
zhihuang81c3a032016-11-17 12:06:24 -08001198 observer_.callback_triggered_ = false;
zhihuang29ff8442016-07-27 11:07:25 -07001199 std::vector<cricket::Candidate> candidates;
1200 pc_factory_for_test_->transport_controller->SignalGatheringState(
1201 cricket::IceGatheringState{});
1202 pc_factory_for_test_->transport_controller->SignalCandidatesGathered(
1203 "", candidates);
1204 pc_factory_for_test_->transport_controller->SignalConnectionState(
1205 cricket::IceConnectionState{});
1206 pc_factory_for_test_->transport_controller->SignalCandidatesRemoved(
1207 candidates);
1208 pc_factory_for_test_->transport_controller->SignalReceiving(false);
zhihuang81c3a032016-11-17 12:06:24 -08001209 EXPECT_FALSE(observer_.callback_triggered_);
zhihuang29ff8442016-07-27 11:07:25 -07001210}
1211
zhihuang8f65cdf2016-05-06 18:40:30 -07001212// Generate different CNAMEs when PeerConnections are created.
1213// The CNAMEs are expected to be generated randomly. It is possible
1214// that the test fails, though the possibility is very low.
1215TEST_F(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
kwibergfd8be342016-05-14 19:44:11 -07001216 std::unique_ptr<SessionDescriptionInterface> offer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001217 CreateOfferWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001218 std::unique_ptr<SessionDescriptionInterface> offer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001219 CreateOfferWithOneAudioStream();
1220 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1221 GetFirstAudioStreamCname(offer2.get()));
1222}
1223
1224TEST_F(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
kwibergfd8be342016-05-14 19:44:11 -07001225 std::unique_ptr<SessionDescriptionInterface> answer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001226 CreateAnswerWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001227 std::unique_ptr<SessionDescriptionInterface> answer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001228 CreateAnswerWithOneAudioStream();
1229 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1230 GetFirstAudioStreamCname(answer2.get()));
1231}
1232
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001233TEST_F(PeerConnectionInterfaceTest,
1234 CreatePeerConnectionWithDifferentConfigurations) {
1235 CreatePeerConnectionWithDifferentConfigurations();
1236}
1237
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001238TEST_F(PeerConnectionInterfaceTest,
1239 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1240 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1241 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1242 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1243 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1244 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1245 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1246 port_allocator_->candidate_filter());
1247 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1248 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1249}
1250
1251// Test that when a PeerConnection is created with a nonzero candidate pool
1252// size, the pooled PortAllocatorSession is created with all the attributes
1253// in the RTCConfiguration.
1254TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
1255 PeerConnectionInterface::RTCConfiguration config;
1256 PeerConnectionInterface::IceServer server;
1257 server.uri = kStunAddressOnly;
1258 config.servers.push_back(server);
1259 config.type = PeerConnectionInterface::kRelay;
1260 config.disable_ipv6 = true;
1261 config.tcp_candidate_policy =
1262 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
honghaiz60347052016-05-31 18:29:12 -07001263 config.candidate_network_policy =
1264 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001265 config.ice_candidate_pool_size = 1;
1266 CreatePeerConnection(config, nullptr);
1267
1268 const cricket::FakePortAllocatorSession* session =
1269 static_cast<const cricket::FakePortAllocatorSession*>(
1270 port_allocator_->GetPooledSession());
1271 ASSERT_NE(nullptr, session);
1272 EXPECT_EQ(1UL, session->stun_servers().size());
1273 EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
1274 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
honghaiz60347052016-05-31 18:29:12 -07001275 EXPECT_LT(0U,
1276 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001277}
1278
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001279// Test that the PeerConnection initializes the port allocator passed into it,
1280// and on the correct thread.
1281TEST_F(PeerConnectionInterfaceTest,
1282 CreatePeerConnectionInitializesPortAllocator) {
1283 rtc::Thread network_thread;
1284 network_thread.Start();
1285 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1286 webrtc::CreatePeerConnectionFactory(
1287 &network_thread, rtc::Thread::Current(), rtc::Thread::Current(),
1288 nullptr, nullptr, nullptr));
1289 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1290 new cricket::FakePortAllocator(&network_thread, nullptr));
1291 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1292 PeerConnectionInterface::RTCConfiguration config;
1293 rtc::scoped_refptr<PeerConnectionInterface> pc(
1294 pc_factory->CreatePeerConnection(
1295 config, nullptr, std::move(port_allocator), nullptr, &observer_));
1296 // FakePortAllocator RTC_CHECKs that it's initialized on the right thread,
1297 // so all we have to do here is check that it's initialized.
1298 EXPECT_TRUE(raw_port_allocator->initialized());
1299}
1300
deadbeef46c73892016-11-16 19:42:04 -08001301// Check that GetConfiguration returns the configuration the PeerConnection was
1302// constructed with, before SetConfiguration is called.
1303TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
1304 PeerConnectionInterface::RTCConfiguration config;
1305 config.type = PeerConnectionInterface::kRelay;
1306 CreatePeerConnection(config, nullptr);
1307
1308 PeerConnectionInterface::RTCConfiguration returned_config =
1309 pc_->GetConfiguration();
1310 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1311}
1312
1313// Check that GetConfiguration returns the last configuration passed into
1314// SetConfiguration.
1315TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
1316 CreatePeerConnection();
1317
1318 PeerConnectionInterface::RTCConfiguration config;
1319 config.type = PeerConnectionInterface::kRelay;
1320 EXPECT_TRUE(pc_->SetConfiguration(config));
1321
1322 PeerConnectionInterface::RTCConfiguration returned_config =
1323 pc_->GetConfiguration();
1324 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1325}
1326
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001327TEST_F(PeerConnectionInterfaceTest, AddStreams) {
deadbeef293e9262017-01-11 12:28:30 -08001328 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001329 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330 AddVoiceStream(kStreamLabel2);
1331 ASSERT_EQ(2u, pc_->local_streams()->count());
1332
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001333 // Test we can add multiple local streams to one peerconnection.
zhihuang9763d562016-08-05 11:14:50 -07001334 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335 pc_factory_->CreateLocalMediaStream(kStreamLabel3));
zhihuang9763d562016-08-05 11:14:50 -07001336 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1337 pc_factory_->CreateAudioTrack(kStreamLabel3,
1338 static_cast<AudioSourceInterface*>(NULL)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001339 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00001340 EXPECT_TRUE(pc_->AddStream(stream));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001341 EXPECT_EQ(3u, pc_->local_streams()->count());
1342
1343 // Remove the third stream.
1344 pc_->RemoveStream(pc_->local_streams()->at(2));
1345 EXPECT_EQ(2u, pc_->local_streams()->count());
1346
1347 // Remove the second stream.
1348 pc_->RemoveStream(pc_->local_streams()->at(1));
1349 EXPECT_EQ(1u, pc_->local_streams()->count());
1350
1351 // Remove the first stream.
1352 pc_->RemoveStream(pc_->local_streams()->at(0));
1353 EXPECT_EQ(0u, pc_->local_streams()->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001354}
1355
deadbeefab9b2d12015-10-14 11:33:11 -07001356// Test that the created offer includes streams we added.
1357TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) {
deadbeef293e9262017-01-11 12:28:30 -08001358 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001359 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track");
kwibergd1fe2812016-04-27 06:47:29 -07001360 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001361 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001362
1363 const cricket::ContentInfo* audio_content =
1364 cricket::GetFirstAudioContent(offer->description());
1365 const cricket::AudioContentDescription* audio_desc =
1366 static_cast<const cricket::AudioContentDescription*>(
1367 audio_content->description);
1368 EXPECT_TRUE(
1369 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1370
1371 const cricket::ContentInfo* video_content =
1372 cricket::GetFirstVideoContent(offer->description());
1373 const cricket::VideoContentDescription* video_desc =
1374 static_cast<const cricket::VideoContentDescription*>(
1375 video_content->description);
1376 EXPECT_TRUE(
1377 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1378
1379 // Add another stream and ensure the offer includes both the old and new
1380 // streams.
1381 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2");
kwiberg2bbff992016-03-16 11:03:04 -07001382 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001383
1384 audio_content = cricket::GetFirstAudioContent(offer->description());
1385 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1386 audio_content->description);
1387 EXPECT_TRUE(
1388 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1389 EXPECT_TRUE(
1390 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2"));
1391
1392 video_content = cricket::GetFirstVideoContent(offer->description());
1393 video_desc = static_cast<const cricket::VideoContentDescription*>(
1394 video_content->description);
1395 EXPECT_TRUE(
1396 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1397 EXPECT_TRUE(
1398 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2"));
1399}
1400
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001401TEST_F(PeerConnectionInterfaceTest, RemoveStream) {
deadbeef293e9262017-01-11 12:28:30 -08001402 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001403 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001404 ASSERT_EQ(1u, pc_->local_streams()->count());
1405 pc_->RemoveStream(pc_->local_streams()->at(0));
1406 EXPECT_EQ(0u, pc_->local_streams()->count());
1407}
1408
deadbeefe1f9d832016-01-14 15:35:42 -08001409// Test for AddTrack and RemoveTrack methods.
1410// Tests that the created offer includes tracks we added,
1411// and that the RtpSenders are created correctly.
1412// Also tests that RemoveTrack removes the tracks from subsequent offers.
1413TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) {
deadbeef293e9262017-01-11 12:28:30 -08001414 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001415 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001416 rtc::scoped_refptr<MediaStreamInterface> stream(
deadbeefe1f9d832016-01-14 15:35:42 -08001417 pc_factory_->CreateLocalMediaStream(kStreamLabel1));
1418 std::vector<MediaStreamInterface*> stream_list;
1419 stream_list.push_back(stream.get());
zhihuang9763d562016-08-05 11:14:50 -07001420 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001421 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001422 rtc::scoped_refptr<VideoTrackInterface> video_track(
1423 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001424 "video_track", pc_factory_->CreateVideoSource(
1425 std::unique_ptr<cricket::VideoCapturer>(
1426 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001427 auto audio_sender = pc_->AddTrack(audio_track, stream_list);
1428 auto video_sender = pc_->AddTrack(video_track, stream_list);
deadbeefa601f5c2016-06-06 14:27:39 -07001429 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1430 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001431 EXPECT_EQ("audio_track", audio_sender->id());
1432 EXPECT_EQ(audio_track, audio_sender->track());
deadbeefa601f5c2016-06-06 14:27:39 -07001433 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1434 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001435 EXPECT_EQ("video_track", video_sender->id());
1436 EXPECT_EQ(video_track, video_sender->track());
1437
1438 // Now create an offer and check for the senders.
kwibergd1fe2812016-04-27 06:47:29 -07001439 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001440 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001441
1442 const cricket::ContentInfo* audio_content =
1443 cricket::GetFirstAudioContent(offer->description());
1444 const cricket::AudioContentDescription* audio_desc =
1445 static_cast<const cricket::AudioContentDescription*>(
1446 audio_content->description);
1447 EXPECT_TRUE(
1448 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1449
1450 const cricket::ContentInfo* video_content =
1451 cricket::GetFirstVideoContent(offer->description());
1452 const cricket::VideoContentDescription* video_desc =
1453 static_cast<const cricket::VideoContentDescription*>(
1454 video_content->description);
1455 EXPECT_TRUE(
1456 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1457
1458 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1459
1460 // Now try removing the tracks.
1461 EXPECT_TRUE(pc_->RemoveTrack(audio_sender));
1462 EXPECT_TRUE(pc_->RemoveTrack(video_sender));
1463
1464 // Create a new offer and ensure it doesn't contain the removed senders.
kwiberg2bbff992016-03-16 11:03:04 -07001465 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001466
1467 audio_content = cricket::GetFirstAudioContent(offer->description());
1468 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1469 audio_content->description);
1470 EXPECT_FALSE(
1471 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1472
1473 video_content = cricket::GetFirstVideoContent(offer->description());
1474 video_desc = static_cast<const cricket::VideoContentDescription*>(
1475 video_content->description);
1476 EXPECT_FALSE(
1477 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1478
1479 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1480
1481 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1482 // should return false.
1483 EXPECT_FALSE(pc_->RemoveTrack(audio_sender));
1484 EXPECT_FALSE(pc_->RemoveTrack(video_sender));
1485}
1486
1487// Test creating senders without a stream specified,
1488// expecting a random stream ID to be generated.
1489TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
deadbeef293e9262017-01-11 12:28:30 -08001490 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001491 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001492 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001493 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001494 rtc::scoped_refptr<VideoTrackInterface> video_track(
1495 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001496 "video_track", pc_factory_->CreateVideoSource(
1497 std::unique_ptr<cricket::VideoCapturer>(
1498 new cricket::FakeVideoCapturer()))));
deadbeefe1f9d832016-01-14 15:35:42 -08001499 auto audio_sender =
1500 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>());
1501 auto video_sender =
1502 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>());
1503 EXPECT_EQ("audio_track", audio_sender->id());
1504 EXPECT_EQ(audio_track, audio_sender->track());
1505 EXPECT_EQ("video_track", video_sender->id());
1506 EXPECT_EQ(video_track, video_sender->track());
1507 // If the ID is truly a random GUID, it should be infinitely unlikely they
1508 // will be the same.
deadbeefa601f5c2016-06-06 14:27:39 -07001509 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
deadbeefe1f9d832016-01-14 15:35:42 -08001510}
1511
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001512TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
1513 InitiateCall();
1514 WaitAndVerifyOnAddStream(kStreamLabel1);
1515 VerifyRemoteRtpHeaderExtensions();
1516}
1517
1518TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001519 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001520 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001521 CreateOfferAsLocalDescription();
1522 std::string offer;
1523 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1524 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
1525 WaitAndVerifyOnAddStream(kStreamLabel1);
1526}
1527
1528TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001529 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001530 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001531
1532 CreateOfferAsRemoteDescription();
1533 CreateAnswerAsLocalDescription();
1534
1535 WaitAndVerifyOnAddStream(kStreamLabel1);
1536}
1537
1538TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001539 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001540 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541
1542 CreateOfferAsRemoteDescription();
1543 CreatePrAnswerAsLocalDescription();
1544 CreateAnswerAsLocalDescription();
1545
1546 WaitAndVerifyOnAddStream(kStreamLabel1);
1547}
1548
1549TEST_F(PeerConnectionInterfaceTest, Renegotiate) {
1550 InitiateCall();
1551 ASSERT_EQ(1u, pc_->remote_streams()->count());
1552 pc_->RemoveStream(pc_->local_streams()->at(0));
1553 CreateOfferReceiveAnswer();
1554 EXPECT_EQ(0u, pc_->remote_streams()->count());
deadbeefab9b2d12015-10-14 11:33:11 -07001555 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556 CreateOfferReceiveAnswer();
1557}
1558
1559// Tests that after negotiating an audio only call, the respondent can perform a
1560// renegotiation that removes the audio stream.
1561TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) {
deadbeef293e9262017-01-11 12:28:30 -08001562 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563 AddVoiceStream(kStreamLabel1);
1564 CreateOfferAsRemoteDescription();
1565 CreateAnswerAsLocalDescription();
1566
1567 ASSERT_EQ(1u, pc_->remote_streams()->count());
1568 pc_->RemoveStream(pc_->local_streams()->at(0));
1569 CreateOfferReceiveAnswer();
1570 EXPECT_EQ(0u, pc_->remote_streams()->count());
1571}
1572
1573// Test that candidates are generated and that we can parse our own candidates.
1574TEST_F(PeerConnectionInterfaceTest, IceCandidates) {
deadbeef293e9262017-01-11 12:28:30 -08001575 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576
1577 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1578 // SetRemoteDescription takes ownership of offer.
kwibergd1fe2812016-04-27 06:47:29 -07001579 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefab9b2d12015-10-14 11:33:11 -07001580 AddVideoStream(kStreamLabel1);
deadbeefc80741f2015-10-22 13:14:45 -07001581 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001582 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583
1584 // SetLocalDescription takes ownership of answer.
kwibergd1fe2812016-04-27 06:47:29 -07001585 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001586 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001587 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588
1589 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout);
1590 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
1591
1592 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1593}
1594
deadbeefab9b2d12015-10-14 11:33:11 -07001595// Test that CreateOffer and CreateAnswer will fail if the track labels are
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596// not unique.
1597TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) {
deadbeef293e9262017-01-11 12:28:30 -08001598 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001599 // Create a regular offer for the CreateAnswer test later.
kwibergd1fe2812016-04-27 06:47:29 -07001600 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07001601 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001602 EXPECT_TRUE(offer);
1603 offer.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604
1605 // Create a local stream with audio&video tracks having same label.
1606 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label");
1607
1608 // Test CreateOffer
deadbeefc80741f2015-10-22 13:14:45 -07001609 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610
1611 // Test CreateAnswer
kwibergd1fe2812016-04-27 06:47:29 -07001612 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001613 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614}
1615
1616// Test that we will get different SSRCs for each tracks in the offer and answer
1617// we created.
1618TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001619 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001620 // Create a local stream with audio&video tracks having different labels.
1621 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1622
1623 // Test CreateOffer
kwibergd1fe2812016-04-27 06:47:29 -07001624 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001625 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626 int audio_ssrc = 0;
1627 int video_ssrc = 0;
1628 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()),
1629 &audio_ssrc));
1630 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()),
1631 &video_ssrc));
1632 EXPECT_NE(audio_ssrc, video_ssrc);
1633
1634 // Test CreateAnswer
1635 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergd1fe2812016-04-27 06:47:29 -07001636 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001637 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001638 audio_ssrc = 0;
1639 video_ssrc = 0;
1640 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()),
1641 &audio_ssrc));
1642 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()),
1643 &video_ssrc));
1644 EXPECT_NE(audio_ssrc, video_ssrc);
1645}
1646
deadbeefeb459812015-12-15 19:24:43 -08001647// Test that it's possible to call AddTrack on a MediaStream after adding
1648// the stream to a PeerConnection.
1649// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1650TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001651 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001652 // Create audio stream and add to PeerConnection.
1653 AddVoiceStream(kStreamLabel1);
1654 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1655
1656 // Add video track to the audio-only stream.
zhihuang9763d562016-08-05 11:14:50 -07001657 rtc::scoped_refptr<VideoTrackInterface> video_track(
1658 pc_factory_->CreateVideoTrack(
deadbeef112b2e92017-02-10 20:13:37 -08001659 "video_label", pc_factory_->CreateVideoSource(
1660 std::unique_ptr<cricket::VideoCapturer>(
1661 new cricket::FakeVideoCapturer()))));
deadbeefeb459812015-12-15 19:24:43 -08001662 stream->AddTrack(video_track.get());
1663
kwibergd1fe2812016-04-27 06:47:29 -07001664 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001665 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001666
1667 const cricket::MediaContentDescription* video_desc =
1668 cricket::GetFirstVideoContentDescription(offer->description());
1669 EXPECT_TRUE(video_desc != nullptr);
1670}
1671
1672// Test that it's possible to call RemoveTrack on a MediaStream after adding
1673// the stream to a PeerConnection.
1674// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1675TEST_F(PeerConnectionInterfaceTest, RemoveTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001676 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001677 // Create audio/video stream and add to PeerConnection.
1678 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1679 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1680
1681 // Remove the video track.
1682 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1683
kwibergd1fe2812016-04-27 06:47:29 -07001684 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001685 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001686
1687 const cricket::MediaContentDescription* video_desc =
1688 cricket::GetFirstVideoContentDescription(offer->description());
1689 EXPECT_TRUE(video_desc == nullptr);
1690}
1691
deadbeef1dcb1642017-03-29 21:08:16 -07001692// Verify that CreateDtmfSender only succeeds if called with a valid local
1693// track. Other aspects of DtmfSenders are tested in
1694// peerconnection_integrationtest.cc.
1695TEST_F(PeerConnectionInterfaceTest, CreateDtmfSenderWithInvalidParams) {
1696 CreatePeerConnection();
1697 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1698 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(nullptr));
1699 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack(
1700 pc_factory_->CreateAudioTrack("dummy_track", nullptr));
1701 EXPECT_EQ(nullptr, pc_->CreateDtmfSender(non_localtrack));
1702}
1703
deadbeefbd7d8f72015-12-18 16:58:44 -08001704// Test creating a sender with a stream ID, and ensure the ID is populated
1705// in the offer.
1706TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) {
deadbeef293e9262017-01-11 12:28:30 -08001707 CreatePeerConnectionWithoutDtls();
deadbeefbd7d8f72015-12-18 16:58:44 -08001708 pc_->CreateSender("video", kStreamLabel1);
1709
kwibergd1fe2812016-04-27 06:47:29 -07001710 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001711 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefbd7d8f72015-12-18 16:58:44 -08001712
1713 const cricket::MediaContentDescription* video_desc =
1714 cricket::GetFirstVideoContentDescription(offer->description());
1715 ASSERT_TRUE(video_desc != nullptr);
1716 ASSERT_EQ(1u, video_desc->streams().size());
1717 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label);
1718}
1719
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720// Test that we can specify a certain track that we want statistics about.
1721TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
1722 InitiateCall();
1723 ASSERT_LT(0u, pc_->remote_streams()->count());
1724 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001725 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001726 pc_->remote_streams()->at(0)->GetAudioTracks()[0];
1727 EXPECT_TRUE(DoGetStats(remote_audio));
1728
1729 // Remove the stream. Since we are sending to our selves the local
1730 // and the remote stream is the same.
1731 pc_->RemoveStream(pc_->local_streams()->at(0));
1732 // Do a re-negotiation.
1733 CreateOfferReceiveAnswer();
1734
1735 ASSERT_EQ(0u, pc_->remote_streams()->count());
1736
1737 // Test that we still can get statistics for the old track. Even if it is not
1738 // sent any longer.
1739 EXPECT_TRUE(DoGetStats(remote_audio));
1740}
1741
1742// Test that we can get stats on a video track.
1743TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
1744 InitiateCall();
1745 ASSERT_LT(0u, pc_->remote_streams()->count());
1746 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001747 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001748 pc_->remote_streams()->at(0)->GetVideoTracks()[0];
1749 EXPECT_TRUE(DoGetStats(remote_video));
1750}
1751
1752// Test that we don't get statistics for an invalid track.
zhihuange9e94c32016-11-04 11:38:15 -07001753TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001754 InitiateCall();
zhihuang9763d562016-08-05 11:14:50 -07001755 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756 pc_factory_->CreateAudioTrack("unknown track", NULL));
1757 EXPECT_FALSE(DoGetStats(unknown_audio_track));
1758}
1759
1760// This test setup two RTP data channels in loop back.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001761TEST_F(PeerConnectionInterfaceTest, TestDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001762 FakeConstraints constraints;
1763 constraints.SetAllowRtpDataChannels();
1764 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001765 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001767 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768 pc_->CreateDataChannel("test2", NULL);
1769 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001770 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001771 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001772 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001773 new MockDataChannelObserver(data2));
1774
1775 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1776 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1777 std::string data_to_send1 = "testing testing";
1778 std::string data_to_send2 = "testing something else";
1779 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1)));
1780
1781 CreateOfferReceiveAnswer();
1782 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1783 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1784
1785 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1786 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1787 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1)));
1788 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1789
1790 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout);
1791 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1792
1793 data1->Close();
1794 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1795 CreateOfferReceiveAnswer();
1796 EXPECT_FALSE(observer1->IsOpen());
1797 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1798 EXPECT_TRUE(observer2->IsOpen());
1799
1800 data_to_send2 = "testing something else again";
1801 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1802
1803 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1804}
1805
1806// This test verifies that sendnig binary data over RTP data channels should
1807// fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809 FakeConstraints constraints;
1810 constraints.SetAllowRtpDataChannels();
1811 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001812 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001814 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815 pc_->CreateDataChannel("test2", NULL);
1816 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001817 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001818 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001819 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001820 new MockDataChannelObserver(data2));
1821
1822 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1823 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1824
1825 CreateOfferReceiveAnswer();
1826 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1827 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1828
1829 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1830 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1831
jbaucheec21bd2016-03-20 06:15:43 -07001832 rtc::CopyOnWriteBuffer buffer("test", 4);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001833 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true)));
1834}
1835
1836// This test setup a RTP data channels in loop back and test that a channel is
1837// opened even if the remote end answer with a zero SSRC.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001838TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001839 FakeConstraints constraints;
1840 constraints.SetAllowRtpDataChannels();
1841 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001842 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001843 pc_->CreateDataChannel("test1", NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001844 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001845 new MockDataChannelObserver(data1));
1846
1847 CreateOfferReceiveAnswerWithoutSsrc();
1848
1849 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1850
1851 data1->Close();
1852 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1853 CreateOfferReceiveAnswerWithoutSsrc();
1854 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1855 EXPECT_FALSE(observer1->IsOpen());
1856}
1857
1858// This test that if a data channel is added in an answer a receive only channel
1859// channel is created.
1860TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) {
1861 FakeConstraints constraints;
1862 constraints.SetAllowRtpDataChannels();
1863 CreatePeerConnection(&constraints);
1864
1865 std::string offer_label = "offer_channel";
zhihuang9763d562016-08-05 11:14:50 -07001866 rtc::scoped_refptr<DataChannelInterface> offer_channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001867 pc_->CreateDataChannel(offer_label, NULL);
1868
1869 CreateOfferAsLocalDescription();
1870
1871 // Replace the data channel label in the offer and apply it as an answer.
1872 std::string receive_label = "answer_channel";
1873 std::string sdp;
1874 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001875 rtc::replace_substrs(offer_label.c_str(), offer_label.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876 receive_label.c_str(), receive_label.length(),
1877 &sdp);
1878 CreateAnswerAsRemoteDescription(sdp);
1879
1880 // Verify that a new incoming data channel has been created and that
1881 // it is open but can't we written to.
1882 ASSERT_TRUE(observer_.last_datachannel_ != NULL);
1883 DataChannelInterface* received_channel = observer_.last_datachannel_;
1884 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state());
1885 EXPECT_EQ(receive_label, received_channel->label());
1886 EXPECT_FALSE(received_channel->Send(DataBuffer("something")));
1887
1888 // Verify that the channel we initially offered has been rejected.
1889 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
1890
1891 // Do another offer / answer exchange and verify that the data channel is
1892 // opened.
1893 CreateOfferReceiveAnswer();
1894 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(),
1895 kTimeout);
1896}
1897
1898// This test that no data channel is returned if a reliable channel is
1899// requested.
1900// TODO(perkj): Remove this test once reliable channels are implemented.
1901TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) {
1902 FakeConstraints constraints;
1903 constraints.SetAllowRtpDataChannels();
1904 CreatePeerConnection(&constraints);
1905
1906 std::string label = "test";
1907 webrtc::DataChannelInit config;
1908 config.reliable = true;
zhihuang9763d562016-08-05 11:14:50 -07001909 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001910 pc_->CreateDataChannel(label, &config);
1911 EXPECT_TRUE(channel == NULL);
1912}
1913
deadbeefab9b2d12015-10-14 11:33:11 -07001914// Verifies that duplicated label is not allowed for RTP data channel.
1915TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) {
1916 FakeConstraints constraints;
1917 constraints.SetAllowRtpDataChannels();
1918 CreatePeerConnection(&constraints);
1919
1920 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07001921 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001922 pc_->CreateDataChannel(label, nullptr);
1923 EXPECT_NE(channel, nullptr);
1924
zhihuang9763d562016-08-05 11:14:50 -07001925 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001926 pc_->CreateDataChannel(label, nullptr);
1927 EXPECT_EQ(dup_channel, nullptr);
1928}
1929
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001930// This tests that a SCTP data channel is returned using different
1931// DataChannelInit configurations.
1932TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
1933 FakeConstraints constraints;
1934 constraints.SetAllowDtlsSctpDataChannels();
1935 CreatePeerConnection(&constraints);
1936
1937 webrtc::DataChannelInit config;
1938
zhihuang9763d562016-08-05 11:14:50 -07001939 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001940 pc_->CreateDataChannel("1", &config);
1941 EXPECT_TRUE(channel != NULL);
1942 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001943 EXPECT_TRUE(observer_.renegotiation_needed_);
1944 observer_.renegotiation_needed_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001945
1946 config.ordered = false;
1947 channel = pc_->CreateDataChannel("2", &config);
1948 EXPECT_TRUE(channel != NULL);
1949 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001950 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001951
1952 config.ordered = true;
1953 config.maxRetransmits = 0;
1954 channel = pc_->CreateDataChannel("3", &config);
1955 EXPECT_TRUE(channel != NULL);
1956 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001957 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958
1959 config.maxRetransmits = -1;
1960 config.maxRetransmitTime = 0;
1961 channel = pc_->CreateDataChannel("4", &config);
1962 EXPECT_TRUE(channel != NULL);
1963 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001964 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965}
1966
1967// This tests that no data channel is returned if both maxRetransmits and
1968// maxRetransmitTime are set for SCTP data channels.
1969TEST_F(PeerConnectionInterfaceTest,
1970 CreateSctpDataChannelShouldFailForInvalidConfig) {
1971 FakeConstraints constraints;
1972 constraints.SetAllowDtlsSctpDataChannels();
1973 CreatePeerConnection(&constraints);
1974
1975 std::string label = "test";
1976 webrtc::DataChannelInit config;
1977 config.maxRetransmits = 0;
1978 config.maxRetransmitTime = 0;
1979
zhihuang9763d562016-08-05 11:14:50 -07001980 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001981 pc_->CreateDataChannel(label, &config);
1982 EXPECT_TRUE(channel == NULL);
1983}
1984
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001985// The test verifies that creating a SCTP data channel with an id already in use
1986// or out of range should fail.
1987TEST_F(PeerConnectionInterfaceTest,
1988 CreateSctpDataChannelWithInvalidIdShouldFail) {
1989 FakeConstraints constraints;
1990 constraints.SetAllowDtlsSctpDataChannels();
1991 CreatePeerConnection(&constraints);
1992
1993 webrtc::DataChannelInit config;
zhihuang9763d562016-08-05 11:14:50 -07001994 rtc::scoped_refptr<DataChannelInterface> channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001995
wu@webrtc.orgcecfd182013-10-30 05:18:12 +00001996 config.id = 1;
1997 channel = pc_->CreateDataChannel("1", &config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998 EXPECT_TRUE(channel != NULL);
1999 EXPECT_EQ(1, channel->id());
2000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002001 channel = pc_->CreateDataChannel("x", &config);
2002 EXPECT_TRUE(channel == NULL);
2003
2004 config.id = cricket::kMaxSctpSid;
2005 channel = pc_->CreateDataChannel("max", &config);
2006 EXPECT_TRUE(channel != NULL);
2007 EXPECT_EQ(config.id, channel->id());
2008
2009 config.id = cricket::kMaxSctpSid + 1;
2010 channel = pc_->CreateDataChannel("x", &config);
2011 EXPECT_TRUE(channel == NULL);
2012}
2013
deadbeefab9b2d12015-10-14 11:33:11 -07002014// Verifies that duplicated label is allowed for SCTP data channel.
2015TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
2016 FakeConstraints constraints;
2017 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2018 true);
2019 CreatePeerConnection(&constraints);
2020
2021 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07002022 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002023 pc_->CreateDataChannel(label, nullptr);
2024 EXPECT_NE(channel, nullptr);
2025
zhihuang9763d562016-08-05 11:14:50 -07002026 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07002027 pc_->CreateDataChannel(label, nullptr);
2028 EXPECT_NE(dup_channel, nullptr);
2029}
2030
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002031// This test verifies that OnRenegotiationNeeded is fired for every new RTP
2032// DataChannel.
2033TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) {
2034 FakeConstraints constraints;
2035 constraints.SetAllowRtpDataChannels();
2036 CreatePeerConnection(&constraints);
2037
zhihuang9763d562016-08-05 11:14:50 -07002038 rtc::scoped_refptr<DataChannelInterface> dc1 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002039 pc_->CreateDataChannel("test1", NULL);
2040 EXPECT_TRUE(observer_.renegotiation_needed_);
2041 observer_.renegotiation_needed_ = false;
2042
zhihuang9763d562016-08-05 11:14:50 -07002043 rtc::scoped_refptr<DataChannelInterface> dc2 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002044 pc_->CreateDataChannel("test2", NULL);
2045 EXPECT_TRUE(observer_.renegotiation_needed_);
2046}
2047
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002048// This test that a data channel closes when a PeerConnection is deleted/closed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002049TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002050 FakeConstraints constraints;
2051 constraints.SetAllowRtpDataChannels();
2052 CreatePeerConnection(&constraints);
2053
zhihuang9763d562016-08-05 11:14:50 -07002054 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002055 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07002056 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002057 pc_->CreateDataChannel("test2", NULL);
2058 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002059 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002060 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07002061 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002062 new MockDataChannelObserver(data2));
2063
2064 CreateOfferReceiveAnswer();
2065 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2066 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
2067
2068 ReleasePeerConnection();
2069 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2070 EXPECT_EQ(DataChannelInterface::kClosed, data2->state());
2071}
2072
2073// This test that data channels can be rejected in an answer.
2074TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) {
2075 FakeConstraints constraints;
2076 constraints.SetAllowRtpDataChannels();
2077 CreatePeerConnection(&constraints);
2078
zhihuang9763d562016-08-05 11:14:50 -07002079 rtc::scoped_refptr<DataChannelInterface> offer_channel(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002080 pc_->CreateDataChannel("offer_channel", NULL));
2081
2082 CreateOfferAsLocalDescription();
2083
2084 // Create an answer where the m-line for data channels are rejected.
2085 std::string sdp;
2086 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2087 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
2088 SessionDescriptionInterface::kAnswer);
2089 EXPECT_TRUE(answer->Initialize(sdp, NULL));
2090 cricket::ContentInfo* data_info =
2091 answer->description()->GetContentByName("data");
2092 data_info->rejected = true;
2093
2094 DoSetRemoteDescription(answer);
2095 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2096}
2097
2098// Test that we can create a session description from an SDP string from
2099// FireFox, use it as a remote session description, generate an answer and use
2100// the answer as a local description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002101TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002102 FakeConstraints constraints;
2103 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2104 true);
2105 CreatePeerConnection(&constraints);
2106 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2107 SessionDescriptionInterface* desc =
2108 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002109 webrtc::kFireFoxSdpOffer, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002110 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2111 CreateAnswerAsLocalDescription();
2112 ASSERT_TRUE(pc_->local_description() != NULL);
2113 ASSERT_TRUE(pc_->remote_description() != NULL);
2114
2115 const cricket::ContentInfo* content =
2116 cricket::GetFirstAudioContent(pc_->local_description()->description());
2117 ASSERT_TRUE(content != NULL);
2118 EXPECT_FALSE(content->rejected);
2119
2120 content =
2121 cricket::GetFirstVideoContent(pc_->local_description()->description());
2122 ASSERT_TRUE(content != NULL);
2123 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002124#ifdef HAVE_SCTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002125 content =
2126 cricket::GetFirstDataContent(pc_->local_description()->description());
2127 ASSERT_TRUE(content != NULL);
2128 EXPECT_TRUE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002129#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002130}
2131
deadbeef8662f942017-01-20 21:20:51 -08002132// Test that an offer can be received which offers DTLS with SDES fallback.
2133// Regression test for issue:
2134// https://bugs.chromium.org/p/webrtc/issues/detail?id=6972
2135TEST_F(PeerConnectionInterfaceTest, ReceiveDtlsSdesFallbackOffer) {
2136 FakeConstraints constraints;
2137 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2138 true);
2139 CreatePeerConnection(&constraints);
2140 // Wait for fake certificate to be generated. Previously, this is what caused
2141 // the "a=crypto" lines to be rejected.
2142 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2143 ASSERT_NE(nullptr, fake_certificate_generator_);
2144 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2145 kTimeout);
2146 SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
2147 SessionDescriptionInterface::kOffer, kDtlsSdesFallbackSdp, nullptr);
2148 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2149 CreateAnswerAsLocalDescription();
2150}
2151
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002152// Test that we can create an audio only offer and receive an answer with a
2153// limited set of audio codecs and receive an updated offer with more audio
2154// codecs, where the added codecs are not supported.
2155TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
deadbeef293e9262017-01-11 12:28:30 -08002156 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157 AddVoiceStream("audio_label");
2158 CreateOfferAsLocalDescription();
2159
2160 SessionDescriptionInterface* answer =
2161 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
jbauchfabe2c92015-07-16 13:43:14 -07002162 webrtc::kAudioSdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002163 EXPECT_TRUE(DoSetSessionDescription(answer, false));
2164
2165 SessionDescriptionInterface* updated_offer =
2166 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002167 webrtc::kAudioSdpWithUnsupportedCodecs,
2168 nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false));
2170 CreateAnswerAsLocalDescription();
2171}
2172
deadbeefc80741f2015-10-22 13:14:45 -07002173// Test that if we're receiving (but not sending) a track, subsequent offers
2174// will have m-lines with a=recvonly.
2175TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
2176 FakeConstraints constraints;
2177 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2178 true);
2179 CreatePeerConnection(&constraints);
2180 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2181 CreateAnswerAsLocalDescription();
2182
2183 // At this point we should be receiving stream 1, but not sending anything.
2184 // A new offer should be recvonly.
kwibergd1fe2812016-04-27 06:47:29 -07002185 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002186 DoCreateOffer(&offer, nullptr);
2187
2188 const cricket::ContentInfo* video_content =
2189 cricket::GetFirstVideoContent(offer->description());
2190 const cricket::VideoContentDescription* video_desc =
2191 static_cast<const cricket::VideoContentDescription*>(
2192 video_content->description);
2193 ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction());
2194
2195 const cricket::ContentInfo* audio_content =
2196 cricket::GetFirstAudioContent(offer->description());
2197 const cricket::AudioContentDescription* audio_desc =
2198 static_cast<const cricket::AudioContentDescription*>(
2199 audio_content->description);
2200 ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction());
2201}
2202
2203// Test that if we're receiving (but not sending) a track, and the
2204// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2205// false, the generated m-lines will be a=inactive.
2206TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
2207 FakeConstraints constraints;
2208 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2209 true);
2210 CreatePeerConnection(&constraints);
2211 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2212 CreateAnswerAsLocalDescription();
2213
2214 // At this point we should be receiving stream 1, but not sending anything.
2215 // A new offer would be recvonly, but we'll set the "no receive" constraints
2216 // to make it inactive.
kwibergd1fe2812016-04-27 06:47:29 -07002217 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002218 FakeConstraints offer_constraints;
2219 offer_constraints.AddMandatory(
2220 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false);
2221 offer_constraints.AddMandatory(
2222 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false);
2223 DoCreateOffer(&offer, &offer_constraints);
2224
2225 const cricket::ContentInfo* video_content =
2226 cricket::GetFirstVideoContent(offer->description());
2227 const cricket::VideoContentDescription* video_desc =
2228 static_cast<const cricket::VideoContentDescription*>(
2229 video_content->description);
2230 ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction());
2231
2232 const cricket::ContentInfo* audio_content =
2233 cricket::GetFirstAudioContent(offer->description());
2234 const cricket::AudioContentDescription* audio_desc =
2235 static_cast<const cricket::AudioContentDescription*>(
2236 audio_content->description);
2237 ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction());
2238}
2239
deadbeef653b8e02015-11-11 12:55:10 -08002240// Test that we can use SetConfiguration to change the ICE servers of the
2241// PortAllocator.
2242TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
2243 CreatePeerConnection();
2244
2245 PeerConnectionInterface::RTCConfiguration config;
2246 PeerConnectionInterface::IceServer server;
2247 server.uri = "stun:test_hostname";
2248 config.servers.push_back(server);
2249 EXPECT_TRUE(pc_->SetConfiguration(config));
2250
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08002251 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2252 EXPECT_EQ("test_hostname",
2253 port_allocator_->stun_servers().begin()->hostname());
deadbeef653b8e02015-11-11 12:55:10 -08002254}
2255
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002256TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
2257 CreatePeerConnection();
2258 PeerConnectionInterface::RTCConfiguration config;
2259 config.type = PeerConnectionInterface::kRelay;
2260 EXPECT_TRUE(pc_->SetConfiguration(config));
2261 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2262}
2263
deadbeef293e9262017-01-11 12:28:30 -08002264TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
2265 PeerConnectionInterface::RTCConfiguration config;
2266 config.prune_turn_ports = false;
2267 CreatePeerConnection(config, nullptr);
2268 EXPECT_FALSE(port_allocator_->prune_turn_ports());
2269
2270 config.prune_turn_ports = true;
2271 EXPECT_TRUE(pc_->SetConfiguration(config));
2272 EXPECT_TRUE(port_allocator_->prune_turn_ports());
2273}
2274
skvladd1f5fda2017-02-03 16:54:05 -08002275// Test that the ice check interval can be changed. This does not verify that
2276// the setting makes it all the way to P2PTransportChannel, as that would
2277// require a very complex set of mocks.
2278TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
2279 PeerConnectionInterface::RTCConfiguration config;
2280 config.ice_check_min_interval = rtc::Optional<int>();
2281 CreatePeerConnection(config, nullptr);
2282 config.ice_check_min_interval = rtc::Optional<int>(100);
2283 EXPECT_TRUE(pc_->SetConfiguration(config));
2284 PeerConnectionInterface::RTCConfiguration new_config =
2285 pc_->GetConfiguration();
2286 EXPECT_EQ(new_config.ice_check_min_interval, rtc::Optional<int>(100));
2287}
2288
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002289// Test that when SetConfiguration changes both the pool size and other
2290// attributes, the pooled session is created with the updated attributes.
2291TEST_F(PeerConnectionInterfaceTest,
2292 SetConfigurationCreatesPooledSessionCorrectly) {
2293 CreatePeerConnection();
2294 PeerConnectionInterface::RTCConfiguration config;
2295 config.ice_candidate_pool_size = 1;
2296 PeerConnectionInterface::IceServer server;
2297 server.uri = kStunAddressOnly;
2298 config.servers.push_back(server);
2299 config.type = PeerConnectionInterface::kRelay;
Taylor Brandstetter417eebe2016-05-23 16:02:19 -07002300 EXPECT_TRUE(pc_->SetConfiguration(config));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002301
2302 const cricket::FakePortAllocatorSession* session =
2303 static_cast<const cricket::FakePortAllocatorSession*>(
2304 port_allocator_->GetPooledSession());
2305 ASSERT_NE(nullptr, session);
2306 EXPECT_EQ(1UL, session->stun_servers().size());
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002307}
2308
deadbeef293e9262017-01-11 12:28:30 -08002309// Test that after SetLocalDescription, changing the pool size is not allowed,
2310// and an invalid modification error is returned.
deadbeef6de92f92016-12-12 18:49:32 -08002311TEST_F(PeerConnectionInterfaceTest,
2312 CantChangePoolSizeAfterSetLocalDescription) {
2313 CreatePeerConnection();
2314 // Start by setting a size of 1.
2315 PeerConnectionInterface::RTCConfiguration config;
2316 config.ice_candidate_pool_size = 1;
2317 EXPECT_TRUE(pc_->SetConfiguration(config));
2318
2319 // Set remote offer; can still change pool size at this point.
2320 CreateOfferAsRemoteDescription();
2321 config.ice_candidate_pool_size = 2;
2322 EXPECT_TRUE(pc_->SetConfiguration(config));
2323
2324 // Set local answer; now it's too late.
2325 CreateAnswerAsLocalDescription();
2326 config.ice_candidate_pool_size = 3;
deadbeef293e9262017-01-11 12:28:30 -08002327 RTCError error;
2328 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2329 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2330}
2331
deadbeef42a42632017-03-10 15:18:00 -08002332// Test that after setting an answer, extra pooled sessions are discarded. The
2333// ICE candidate pool is only intended to be used for the first offer/answer.
2334TEST_F(PeerConnectionInterfaceTest,
2335 ExtraPooledSessionsDiscardedAfterApplyingAnswer) {
2336 CreatePeerConnection();
2337
2338 // Set a larger-than-necessary size.
2339 PeerConnectionInterface::RTCConfiguration config;
2340 config.ice_candidate_pool_size = 4;
2341 EXPECT_TRUE(pc_->SetConfiguration(config));
2342
2343 // Do offer/answer.
2344 CreateOfferAsRemoteDescription();
2345 CreateAnswerAsLocalDescription();
2346
2347 // Expect no pooled sessions to be left.
2348 const cricket::PortAllocatorSession* session =
2349 port_allocator_->GetPooledSession();
2350 EXPECT_EQ(nullptr, session);
2351}
2352
2353// After Close is called, pooled candidates should be discarded so as to not
2354// waste network resources.
2355TEST_F(PeerConnectionInterfaceTest, PooledSessionsDiscardedAfterClose) {
2356 CreatePeerConnection();
2357
2358 PeerConnectionInterface::RTCConfiguration config;
2359 config.ice_candidate_pool_size = 3;
2360 EXPECT_TRUE(pc_->SetConfiguration(config));
2361 pc_->Close();
2362
2363 // Expect no pooled sessions to be left.
2364 const cricket::PortAllocatorSession* session =
2365 port_allocator_->GetPooledSession();
2366 EXPECT_EQ(nullptr, session);
2367}
2368
deadbeef293e9262017-01-11 12:28:30 -08002369// Test that SetConfiguration returns an invalid modification error if
2370// modifying a field in the configuration that isn't allowed to be modified.
2371TEST_F(PeerConnectionInterfaceTest,
2372 SetConfigurationReturnsInvalidModificationError) {
2373 PeerConnectionInterface::RTCConfiguration config;
2374 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2375 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2376 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
2377 CreatePeerConnection(config, nullptr);
2378
2379 PeerConnectionInterface::RTCConfiguration modified_config = config;
2380 modified_config.bundle_policy =
2381 PeerConnectionInterface::kBundlePolicyMaxBundle;
2382 RTCError error;
2383 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2384 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2385
2386 modified_config = config;
2387 modified_config.rtcp_mux_policy =
2388 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2389 error.set_type(RTCErrorType::NONE);
2390 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2391 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2392
2393 modified_config = config;
2394 modified_config.continual_gathering_policy =
2395 PeerConnectionInterface::GATHER_CONTINUALLY;
2396 error.set_type(RTCErrorType::NONE);
2397 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2398 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2399}
2400
2401// Test that SetConfiguration returns a range error if the candidate pool size
2402// is negative or larger than allowed by the spec.
2403TEST_F(PeerConnectionInterfaceTest,
2404 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2405 PeerConnectionInterface::RTCConfiguration config;
2406 CreatePeerConnection(config, nullptr);
2407
2408 config.ice_candidate_pool_size = -1;
2409 RTCError error;
2410 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2411 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2412
2413 config.ice_candidate_pool_size = INT_MAX;
2414 error.set_type(RTCErrorType::NONE);
2415 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2416 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2417}
2418
2419// Test that SetConfiguration returns a syntax error if parsing an ICE server
2420// URL failed.
2421TEST_F(PeerConnectionInterfaceTest,
2422 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2423 PeerConnectionInterface::RTCConfiguration config;
2424 CreatePeerConnection(config, nullptr);
2425
2426 PeerConnectionInterface::IceServer bad_server;
2427 bad_server.uri = "stunn:www.example.com";
2428 config.servers.push_back(bad_server);
2429 RTCError error;
2430 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2431 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2432}
2433
2434// Test that SetConfiguration returns an invalid parameter error if a TURN
2435// IceServer is missing a username or password.
2436TEST_F(PeerConnectionInterfaceTest,
2437 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2438 PeerConnectionInterface::RTCConfiguration config;
2439 CreatePeerConnection(config, nullptr);
2440
2441 PeerConnectionInterface::IceServer bad_server;
2442 bad_server.uri = "turn:www.example.com";
2443 // Missing password.
2444 bad_server.username = "foo";
2445 config.servers.push_back(bad_server);
2446 RTCError error;
2447 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2448 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
deadbeef6de92f92016-12-12 18:49:32 -08002449}
2450
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451// Test that PeerConnection::Close changes the states to closed and all remote
2452// tracks change state to ended.
2453TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
2454 // Initialize a PeerConnection and negotiate local and remote session
2455 // description.
2456 InitiateCall();
2457 ASSERT_EQ(1u, pc_->local_streams()->count());
2458 ASSERT_EQ(1u, pc_->remote_streams()->count());
2459
2460 pc_->Close();
2461
2462 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2463 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2464 pc_->ice_connection_state());
2465 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2466 pc_->ice_gathering_state());
2467
2468 EXPECT_EQ(1u, pc_->local_streams()->count());
2469 EXPECT_EQ(1u, pc_->remote_streams()->count());
2470
zhihuang9763d562016-08-05 11:14:50 -07002471 rtc::scoped_refptr<MediaStreamInterface> remote_stream =
2472 pc_->remote_streams()->at(0);
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002473 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002474 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002475 remote_stream->GetAudioTracks()[0]->state(), kTimeout);
2476 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2477 remote_stream->GetVideoTracks()[0]->state(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002478}
2479
2480// Test that PeerConnection methods fails gracefully after
2481// PeerConnection::Close has been called.
2482TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) {
deadbeef293e9262017-01-11 12:28:30 -08002483 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2485 CreateOfferAsRemoteDescription();
2486 CreateAnswerAsLocalDescription();
2487
2488 ASSERT_EQ(1u, pc_->local_streams()->count());
zhihuang9763d562016-08-05 11:14:50 -07002489 rtc::scoped_refptr<MediaStreamInterface> local_stream =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002490 pc_->local_streams()->at(0);
2491
2492 pc_->Close();
2493
2494 pc_->RemoveStream(local_stream);
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00002495 EXPECT_FALSE(pc_->AddStream(local_stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002496
2497 ASSERT_FALSE(local_stream->GetAudioTracks().empty());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002498 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0]));
wu@webrtc.org66037362013-08-13 00:09:35 +00002500 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002501
2502 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL);
2503
2504 EXPECT_TRUE(pc_->local_description() != NULL);
2505 EXPECT_TRUE(pc_->remote_description() != NULL);
2506
kwibergd1fe2812016-04-27 06:47:29 -07002507 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07002508 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwibergd1fe2812016-04-27 06:47:29 -07002509 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07002510 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511
2512 std::string sdp;
2513 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
2514 SessionDescriptionInterface* remote_offer =
2515 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2516 sdp, NULL);
2517 EXPECT_FALSE(DoSetRemoteDescription(remote_offer));
2518
2519 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
2520 SessionDescriptionInterface* local_offer =
2521 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2522 sdp, NULL);
2523 EXPECT_FALSE(DoSetLocalDescription(local_offer));
2524}
2525
2526// Test that GetStats can still be called after PeerConnection::Close.
2527TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) {
2528 InitiateCall();
2529 pc_->Close();
2530 DoGetStats(NULL);
2531}
deadbeefab9b2d12015-10-14 11:33:11 -07002532
2533// NOTE: The series of tests below come from what used to be
2534// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2535// setting a remote or local description has the expected effects.
2536
2537// This test verifies that the remote MediaStreams corresponding to a received
2538// SDP string is created. In this test the two separate MediaStreams are
2539// signaled.
2540TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
2541 FakeConstraints constraints;
2542 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2543 true);
2544 CreatePeerConnection(&constraints);
2545 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2546
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002547 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002548 EXPECT_TRUE(
2549 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2550 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2551 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2552
2553 // Create a session description based on another SDP with another
2554 // MediaStream.
2555 CreateAndSetRemoteOffer(kSdpStringWithStream1And2);
2556
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002557 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002558 EXPECT_TRUE(
2559 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2560}
2561
2562// This test verifies that when remote tracks are added/removed from SDP, the
2563// created remote streams are updated appropriately.
2564TEST_F(PeerConnectionInterfaceTest,
2565 AddRemoveTrackFromExistingRemoteMediaStream) {
2566 FakeConstraints constraints;
2567 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2568 true);
2569 CreatePeerConnection(&constraints);
kwibergd1fe2812016-04-27 06:47:29 -07002570 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
kwiberg2bbff992016-03-16 11:03:04 -07002571 CreateSessionDescriptionAndReference(1, 1);
deadbeefab9b2d12015-10-14 11:33:11 -07002572 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release()));
2573 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2574 reference_collection_));
2575
2576 // Add extra audio and video tracks to the same MediaStream.
kwibergd1fe2812016-04-27 06:47:29 -07002577 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
kwiberg2bbff992016-03-16 11:03:04 -07002578 CreateSessionDescriptionAndReference(2, 2);
deadbeefab9b2d12015-10-14 11:33:11 -07002579 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release()));
2580 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2581 reference_collection_));
zhihuang9763d562016-08-05 11:14:50 -07002582 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
perkjd61bf802016-03-24 03:16:19 -07002583 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2584 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
zhihuang9763d562016-08-05 11:14:50 -07002585 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
perkjd61bf802016-03-24 03:16:19 -07002586 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2587 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002588
2589 // Remove the extra audio and video tracks.
kwibergd1fe2812016-04-27 06:47:29 -07002590 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
kwiberg2bbff992016-03-16 11:03:04 -07002591 CreateSessionDescriptionAndReference(1, 1);
perkjd61bf802016-03-24 03:16:19 -07002592 MockTrackObserver audio_track_observer(audio_track2);
2593 MockTrackObserver video_track_observer(video_track2);
2594
2595 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2596 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
deadbeefab9b2d12015-10-14 11:33:11 -07002597 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release()));
2598 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2599 reference_collection_));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002600 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002601 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002602 audio_track2->state(), kTimeout);
2603 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2604 video_track2->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002605}
2606
2607// This tests that remote tracks are ended if a local session description is set
2608// that rejects the media content type.
2609TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) {
2610 FakeConstraints constraints;
2611 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2612 true);
2613 CreatePeerConnection(&constraints);
2614 // First create and set a remote offer, then reject its video content in our
2615 // answer.
2616 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2617 ASSERT_EQ(1u, observer_.remote_streams()->count());
2618 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2619 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2620 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2621
2622 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video =
2623 remote_stream->GetVideoTracks()[0];
2624 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state());
2625 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio =
2626 remote_stream->GetAudioTracks()[0];
2627 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2628
kwibergd1fe2812016-04-27 06:47:29 -07002629 std::unique_ptr<SessionDescriptionInterface> local_answer;
kwiberg2bbff992016-03-16 11:03:04 -07002630 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002631 cricket::ContentInfo* video_info =
2632 local_answer->description()->GetContentByName("video");
2633 video_info->rejected = true;
2634 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2635 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state());
2636 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2637
2638 // Now create an offer where we reject both video and audio.
kwibergd1fe2812016-04-27 06:47:29 -07002639 std::unique_ptr<SessionDescriptionInterface> local_offer;
kwiberg2bbff992016-03-16 11:03:04 -07002640 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002641 video_info = local_offer->description()->GetContentByName("video");
2642 ASSERT_TRUE(video_info != nullptr);
2643 video_info->rejected = true;
2644 cricket::ContentInfo* audio_info =
2645 local_offer->description()->GetContentByName("audio");
2646 ASSERT_TRUE(audio_info != nullptr);
2647 audio_info->rejected = true;
2648 EXPECT_TRUE(DoSetLocalDescription(local_offer.release()));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002649 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002650 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002651 remote_audio->state(), kTimeout);
2652 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2653 remote_video->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002654}
2655
2656// This tests that we won't crash if the remote track has been removed outside
2657// of PeerConnection and then PeerConnection tries to reject the track.
2658TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) {
2659 FakeConstraints constraints;
2660 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2661 true);
2662 CreatePeerConnection(&constraints);
2663 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2664 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2665 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2666 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2667
kwibergd1fe2812016-04-27 06:47:29 -07002668 std::unique_ptr<SessionDescriptionInterface> local_answer(
deadbeefab9b2d12015-10-14 11:33:11 -07002669 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
2670 kSdpStringWithStream1, nullptr));
2671 cricket::ContentInfo* video_info =
2672 local_answer->description()->GetContentByName("video");
2673 video_info->rejected = true;
2674 cricket::ContentInfo* audio_info =
2675 local_answer->description()->GetContentByName("audio");
2676 audio_info->rejected = true;
2677 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2678
2679 // No crash is a pass.
2680}
2681
deadbeef5e97fb52015-10-15 12:49:08 -07002682// This tests that if a recvonly remote description is set, no remote streams
2683// will be created, even if the description contains SSRCs/MSIDs.
2684// See: https://code.google.com/p/webrtc/issues/detail?id=5054
2685TEST_F(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
2686 FakeConstraints constraints;
2687 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2688 true);
2689 CreatePeerConnection(&constraints);
2690
2691 std::string recvonly_offer = kSdpStringWithStream1;
2692 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly,
2693 strlen(kRecvonly), &recvonly_offer);
2694 CreateAndSetRemoteOffer(recvonly_offer);
2695
2696 EXPECT_EQ(0u, observer_.remote_streams()->count());
2697}
2698
deadbeefab9b2d12015-10-14 11:33:11 -07002699// This tests that a default MediaStream is created if a remote session
2700// description doesn't contain any streams and no MSID support.
2701// It also tests that the default stream is updated if a video m-line is added
2702// in a subsequent session description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002703TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002704 FakeConstraints constraints;
2705 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2706 true);
2707 CreatePeerConnection(&constraints);
2708 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2709
2710 ASSERT_EQ(1u, observer_.remote_streams()->count());
2711 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2712
2713 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2714 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
2715 EXPECT_EQ("default", remote_stream->label());
2716
2717 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2718 ASSERT_EQ(1u, observer_.remote_streams()->count());
2719 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2720 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002721 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2722 remote_stream->GetAudioTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002723 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2724 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002725 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2726 remote_stream->GetVideoTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002727}
2728
2729// This tests that a default MediaStream is created if a remote session
2730// description doesn't contain any streams and media direction is send only.
2731TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002732 SendOnlySdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002733 FakeConstraints constraints;
2734 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2735 true);
2736 CreatePeerConnection(&constraints);
2737 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2738
2739 ASSERT_EQ(1u, observer_.remote_streams()->count());
2740 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2741
2742 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2743 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2744 EXPECT_EQ("default", remote_stream->label());
2745}
2746
2747// This tests that it won't crash when PeerConnection tries to remove
2748// a remote track that as already been removed from the MediaStream.
2749TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) {
2750 FakeConstraints constraints;
2751 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2752 true);
2753 CreatePeerConnection(&constraints);
2754 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2755 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2756 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2757 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2758
2759 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2760
2761 // No crash is a pass.
2762}
2763
2764// This tests that a default MediaStream is created if the remote session
2765// description doesn't contain any streams and don't contain an indication if
2766// MSID is supported.
2767TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002768 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002769 FakeConstraints constraints;
2770 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2771 true);
2772 CreatePeerConnection(&constraints);
2773 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2774
2775 ASSERT_EQ(1u, observer_.remote_streams()->count());
2776 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2777 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2778 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2779}
2780
2781// This tests that a default MediaStream is not created if the remote session
2782// description doesn't contain any streams but does support MSID.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002783TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002784 FakeConstraints constraints;
2785 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2786 true);
2787 CreatePeerConnection(&constraints);
2788 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2789 EXPECT_EQ(0u, observer_.remote_streams()->count());
2790}
2791
deadbeefbda7e0b2015-12-08 17:13:40 -08002792// This tests that when setting a new description, the old default tracks are
2793// not destroyed and recreated.
2794// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
Stefan Holmer102362b2016-03-18 09:39:07 +01002795TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002796 DefaultTracksNotDestroyedAndRecreated) {
deadbeefbda7e0b2015-12-08 17:13:40 -08002797 FakeConstraints constraints;
2798 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2799 true);
2800 CreatePeerConnection(&constraints);
2801 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2802
2803 ASSERT_EQ(1u, observer_.remote_streams()->count());
2804 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2805 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2806
2807 // Set the track to "disabled", then set a new description and ensure the
2808 // track is still disabled, which ensures it hasn't been recreated.
2809 remote_stream->GetAudioTracks()[0]->set_enabled(false);
2810 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2811 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2812 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
2813}
2814
deadbeefab9b2d12015-10-14 11:33:11 -07002815// This tests that a default MediaStream is not created if a remote session
2816// description is updated to not have any MediaStreams.
2817TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) {
2818 FakeConstraints constraints;
2819 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2820 true);
2821 CreatePeerConnection(&constraints);
2822 CreateAndSetRemoteOffer(kSdpStringWithStream1);
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002823 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002824 EXPECT_TRUE(
2825 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2826
2827 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2828 EXPECT_EQ(0u, observer_.remote_streams()->count());
2829}
2830
2831// This tests that an RtpSender is created when the local description is set
2832// after adding a local stream.
2833// TODO(deadbeef): This test and the one below it need to be updated when
2834// an RtpSender's lifetime isn't determined by when a local description is set.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002835TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002836 FakeConstraints constraints;
2837 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2838 true);
2839 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002840
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002841 // Create an offer with 1 stream with 2 tracks of each type.
2842 rtc::scoped_refptr<StreamCollection> stream_collection =
2843 CreateStreamCollection(1, 2);
2844 pc_->AddStream(stream_collection->at(0));
2845 std::unique_ptr<SessionDescriptionInterface> offer;
2846 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2847 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002848
deadbeefab9b2d12015-10-14 11:33:11 -07002849 auto senders = pc_->GetSenders();
2850 EXPECT_EQ(4u, senders.size());
2851 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2852 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2853 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2854 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2855
2856 // Remove an audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002857 pc_->RemoveStream(stream_collection->at(0));
2858 stream_collection = CreateStreamCollection(1, 1);
2859 pc_->AddStream(stream_collection->at(0));
2860 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2861 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
2862
deadbeefab9b2d12015-10-14 11:33:11 -07002863 senders = pc_->GetSenders();
2864 EXPECT_EQ(2u, senders.size());
2865 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2866 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2867 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
2868 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
2869}
2870
2871// This tests that an RtpSender is created when the local description is set
2872// before adding a local stream.
2873TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002874 AddLocalStreamAfterLocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002875 FakeConstraints constraints;
2876 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2877 true);
2878 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002879
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002880 rtc::scoped_refptr<StreamCollection> stream_collection =
2881 CreateStreamCollection(1, 2);
2882 // Add a stream to create the offer, but remove it afterwards.
2883 pc_->AddStream(stream_collection->at(0));
2884 std::unique_ptr<SessionDescriptionInterface> offer;
2885 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2886 pc_->RemoveStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002887
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002888 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002889 auto senders = pc_->GetSenders();
2890 EXPECT_EQ(0u, senders.size());
2891
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002892 pc_->AddStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002893 senders = pc_->GetSenders();
2894 EXPECT_EQ(4u, senders.size());
2895 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2896 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2897 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2898 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2899}
2900
2901// This tests that the expected behavior occurs if the SSRC on a local track is
2902// changed when SetLocalDescription is called.
2903TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002904 ChangeSsrcOnTrackInLocalSessionDescription) {
deadbeefab9b2d12015-10-14 11:33:11 -07002905 FakeConstraints constraints;
2906 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2907 true);
2908 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002909
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002910 rtc::scoped_refptr<StreamCollection> stream_collection =
2911 CreateStreamCollection(2, 1);
2912 pc_->AddStream(stream_collection->at(0));
2913 std::unique_ptr<SessionDescriptionInterface> offer;
2914 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2915 // Grab a copy of the offer before it gets passed into the PC.
2916 std::unique_ptr<JsepSessionDescription> modified_offer(
2917 new JsepSessionDescription(JsepSessionDescription::kOffer));
2918 modified_offer->Initialize(offer->description()->Copy(), offer->session_id(),
2919 offer->session_version());
2920 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002921
deadbeefab9b2d12015-10-14 11:33:11 -07002922 auto senders = pc_->GetSenders();
2923 EXPECT_EQ(2u, senders.size());
2924 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2925 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2926
2927 // Change the ssrc of the audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002928 cricket::MediaContentDescription* desc =
2929 cricket::GetFirstAudioContentDescription(modified_offer->description());
2930 ASSERT_TRUE(desc != NULL);
2931 for (StreamParams& stream : desc->mutable_streams()) {
2932 for (unsigned int& ssrc : stream.ssrcs) {
2933 ++ssrc;
2934 }
2935 }
deadbeefab9b2d12015-10-14 11:33:11 -07002936
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002937 desc =
2938 cricket::GetFirstVideoContentDescription(modified_offer->description());
2939 ASSERT_TRUE(desc != NULL);
2940 for (StreamParams& stream : desc->mutable_streams()) {
2941 for (unsigned int& ssrc : stream.ssrcs) {
2942 ++ssrc;
2943 }
2944 }
2945
2946 EXPECT_TRUE(DoSetLocalDescription(modified_offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002947 senders = pc_->GetSenders();
2948 EXPECT_EQ(2u, senders.size());
2949 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2950 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2951 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
2952 // changed.
2953}
2954
2955// This tests that the expected behavior occurs if a new session description is
2956// set with the same tracks, but on a different MediaStream.
Stefan Holmer55d6e7c2016-03-17 16:26:40 +01002957TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002958 SignalSameTracksInSeparateMediaStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002959 FakeConstraints constraints;
2960 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2961 true);
2962 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002963
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002964 rtc::scoped_refptr<StreamCollection> stream_collection =
2965 CreateStreamCollection(2, 1);
2966 pc_->AddStream(stream_collection->at(0));
2967 std::unique_ptr<SessionDescriptionInterface> offer;
2968 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2969 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002970
deadbeefab9b2d12015-10-14 11:33:11 -07002971 auto senders = pc_->GetSenders();
2972 EXPECT_EQ(2u, senders.size());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002973 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
2974 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
deadbeefab9b2d12015-10-14 11:33:11 -07002975
2976 // Add a new MediaStream but with the same tracks as in the first stream.
2977 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
2978 webrtc::MediaStream::Create(kStreams[1]));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002979 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
2980 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
deadbeefab9b2d12015-10-14 11:33:11 -07002981 pc_->AddStream(stream_1);
2982
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002983 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2984 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002985
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002986 auto new_senders = pc_->GetSenders();
2987 // Should be the same senders as before, but with updated stream id.
2988 // Note that this behavior is subject to change in the future.
2989 // We may decide the PC should ignore existing tracks in AddStream.
2990 EXPECT_EQ(senders, new_senders);
2991 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
2992 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
deadbeefab9b2d12015-10-14 11:33:11 -07002993}
2994
zhihuang81c3a032016-11-17 12:06:24 -08002995// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
2996TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
2997 FakeConstraints constraints;
2998 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2999 true);
3000 CreatePeerConnection(&constraints);
3001 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
3002 EXPECT_EQ(observer_.num_added_tracks_, 1);
3003 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
3004
3005 // Create and set the updated remote SDP.
3006 CreateAndSetRemoteOffer(kSdpStringWithStream1);
3007 EXPECT_EQ(observer_.num_added_tracks_, 2);
3008 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
3009}
3010
deadbeefd1a38b52016-12-10 13:15:33 -08003011// Test that when SetConfiguration is called and the configuration is
3012// changing, the next offer causes an ICE restart.
3013TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingIceRetart) {
3014 PeerConnectionInterface::RTCConfiguration config;
3015 config.type = PeerConnectionInterface::kRelay;
3016 // Need to pass default constraints to prevent disabling of DTLS...
3017 FakeConstraints default_constraints;
3018 CreatePeerConnection(config, &default_constraints);
3019 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3020
3021 // Do initial offer/answer so there's something to restart.
3022 CreateOfferAsLocalDescription();
3023 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3024
3025 // Grab the ufrags.
3026 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3027
3028 // Change ICE policy, which should trigger an ICE restart on the next offer.
3029 config.type = PeerConnectionInterface::kAll;
3030 EXPECT_TRUE(pc_->SetConfiguration(config));
3031 CreateOfferAsLocalDescription();
3032
3033 // Grab the new ufrags.
3034 std::vector<std::string> subsequent_ufrags =
3035 GetUfrags(pc_->local_description());
3036
3037 // Sanity check.
3038 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
3039 // Check that each ufrag is different.
3040 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
3041 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
3042 }
3043}
3044
3045// Test that when SetConfiguration is called and the configuration *isn't*
3046// changing, the next offer does *not* cause an ICE restart.
3047TEST_F(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRetart) {
3048 PeerConnectionInterface::RTCConfiguration config;
3049 config.type = PeerConnectionInterface::kRelay;
3050 // Need to pass default constraints to prevent disabling of DTLS...
3051 FakeConstraints default_constraints;
3052 CreatePeerConnection(config, &default_constraints);
3053 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3054
3055 // Do initial offer/answer so there's something to restart.
3056 CreateOfferAsLocalDescription();
3057 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3058
3059 // Grab the ufrags.
3060 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3061
3062 // Call SetConfiguration with a config identical to what the PC was
3063 // constructed with.
3064 EXPECT_TRUE(pc_->SetConfiguration(config));
3065 CreateOfferAsLocalDescription();
3066
3067 // Grab the new ufrags.
3068 std::vector<std::string> subsequent_ufrags =
3069 GetUfrags(pc_->local_description());
3070
3071 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
3072}
3073
3074// Test for a weird corner case scenario:
3075// 1. Audio/video session established.
3076// 2. SetConfiguration changes ICE config; ICE restart needed.
3077// 3. ICE restart initiated by remote peer, but only for one m= section.
3078// 4. Next createOffer should initiate an ICE restart, but only for the other
3079// m= section; it would be pointless to do an ICE restart for the m= section
3080// that was already restarted.
3081TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
3082 PeerConnectionInterface::RTCConfiguration config;
3083 config.type = PeerConnectionInterface::kRelay;
3084 // Need to pass default constraints to prevent disabling of DTLS...
3085 FakeConstraints default_constraints;
3086 CreatePeerConnection(config, &default_constraints);
3087 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3088
3089 // Do initial offer/answer so there's something to restart.
3090 CreateOfferAsLocalDescription();
3091 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3092
3093 // Change ICE policy, which should set the "needs-ice-restart" flag.
3094 config.type = PeerConnectionInterface::kAll;
3095 EXPECT_TRUE(pc_->SetConfiguration(config));
3096
3097 // Do ICE restart for the first m= section, initiated by remote peer.
3098 webrtc::JsepSessionDescription* remote_offer =
3099 new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer);
3100 EXPECT_TRUE(remote_offer->Initialize(kSdpStringWithStream1, nullptr));
3101 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3102 "modified";
3103 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3104 CreateAnswerAsLocalDescription();
3105
3106 // Grab the ufrags.
3107 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3108 ASSERT_EQ(2, initial_ufrags.size());
3109
3110 // Create offer and grab the new ufrags.
3111 CreateOfferAsLocalDescription();
3112 std::vector<std::string> subsequent_ufrags =
3113 GetUfrags(pc_->local_description());
3114 ASSERT_EQ(2, subsequent_ufrags.size());
3115
3116 // Ensure that only the ufrag for the second m= section changed.
3117 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3118 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3119}
3120
deadbeeffe4a8a42016-12-20 17:56:17 -08003121// Tests that the methods to return current/pending descriptions work as
3122// expected at different points in the offer/answer exchange. This test does
3123// one offer/answer exchange as the offerer, then another as the answerer.
3124TEST_F(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
3125 // This disables DTLS so we can apply an answer to ourselves.
3126 CreatePeerConnection();
3127
3128 // Create initial local offer and get SDP (which will also be used as
3129 // answer/pranswer);
3130 std::unique_ptr<SessionDescriptionInterface> offer;
3131 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3132 std::string sdp;
3133 EXPECT_TRUE(offer->ToString(&sdp));
3134
3135 // Set local offer.
3136 SessionDescriptionInterface* local_offer = offer.release();
3137 EXPECT_TRUE(DoSetLocalDescription(local_offer));
3138 EXPECT_EQ(local_offer, pc_->pending_local_description());
3139 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3140 EXPECT_EQ(nullptr, pc_->current_local_description());
3141 EXPECT_EQ(nullptr, pc_->current_remote_description());
3142
3143 // Set remote pranswer.
3144 SessionDescriptionInterface* remote_pranswer =
3145 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3146 sdp, nullptr);
3147 EXPECT_TRUE(DoSetRemoteDescription(remote_pranswer));
3148 EXPECT_EQ(local_offer, pc_->pending_local_description());
3149 EXPECT_EQ(remote_pranswer, pc_->pending_remote_description());
3150 EXPECT_EQ(nullptr, pc_->current_local_description());
3151 EXPECT_EQ(nullptr, pc_->current_remote_description());
3152
3153 // Set remote answer.
3154 SessionDescriptionInterface* remote_answer = webrtc::CreateSessionDescription(
3155 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3156 EXPECT_TRUE(DoSetRemoteDescription(remote_answer));
3157 EXPECT_EQ(nullptr, pc_->pending_local_description());
3158 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3159 EXPECT_EQ(local_offer, pc_->current_local_description());
3160 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3161
3162 // Set remote offer.
3163 SessionDescriptionInterface* remote_offer = webrtc::CreateSessionDescription(
3164 SessionDescriptionInterface::kOffer, sdp, nullptr);
3165 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3166 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3167 EXPECT_EQ(nullptr, pc_->pending_local_description());
3168 EXPECT_EQ(local_offer, pc_->current_local_description());
3169 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3170
3171 // Set local pranswer.
3172 SessionDescriptionInterface* local_pranswer =
3173 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3174 sdp, nullptr);
3175 EXPECT_TRUE(DoSetLocalDescription(local_pranswer));
3176 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3177 EXPECT_EQ(local_pranswer, pc_->pending_local_description());
3178 EXPECT_EQ(local_offer, pc_->current_local_description());
3179 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3180
3181 // Set local answer.
3182 SessionDescriptionInterface* local_answer = webrtc::CreateSessionDescription(
3183 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3184 EXPECT_TRUE(DoSetLocalDescription(local_answer));
3185 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3186 EXPECT_EQ(nullptr, pc_->pending_local_description());
3187 EXPECT_EQ(remote_offer, pc_->current_remote_description());
3188 EXPECT_EQ(local_answer, pc_->current_local_description());
3189}
3190
zhihuang77985012017-02-07 15:45:16 -08003191// Tests that it won't crash when calling StartRtcEventLog or StopRtcEventLog
3192// after the PeerConnection is closed.
3193TEST_F(PeerConnectionInterfaceTest,
3194 StartAndStopLoggingAfterPeerConnectionClosed) {
3195 CreatePeerConnection();
3196 // The RtcEventLog will be reset when the PeerConnection is closed.
3197 pc_->Close();
3198
3199 rtc::PlatformFile file = 0;
3200 int64_t max_size_bytes = 1024;
3201 EXPECT_FALSE(pc_->StartRtcEventLog(file, max_size_bytes));
3202 pc_->StopRtcEventLog();
3203}
3204
deadbeef30952b42017-04-21 02:41:29 -07003205// Test that generated offers/answers include "ice-option:trickle".
3206TEST_F(PeerConnectionInterfaceTest, OffersAndAnswersHaveTrickleIceOption) {
3207 CreatePeerConnection();
3208
3209 // First, create an offer with audio/video.
3210 FakeConstraints constraints;
3211 constraints.SetMandatoryReceiveAudio(true);
3212 constraints.SetMandatoryReceiveVideo(true);
3213 std::unique_ptr<SessionDescriptionInterface> offer;
3214 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3215 cricket::SessionDescription* desc = offer->description();
3216 ASSERT_EQ(2u, desc->transport_infos().size());
3217 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3218 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3219
3220 // Apply the offer as a remote description, then create an answer.
3221 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3222 std::unique_ptr<SessionDescriptionInterface> answer;
3223 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3224 desc = answer->description();
3225 ASSERT_EQ(2u, desc->transport_infos().size());
3226 EXPECT_TRUE(desc->transport_infos()[0].description.HasOption("trickle"));
3227 EXPECT_TRUE(desc->transport_infos()[1].description.HasOption("trickle"));
3228}
3229
deadbeef1dcb1642017-03-29 21:08:16 -07003230// Test that ICE renomination isn't offered if it's not enabled in the PC's
3231// RTCConfiguration.
3232TEST_F(PeerConnectionInterfaceTest, IceRenominationNotOffered) {
3233 PeerConnectionInterface::RTCConfiguration config;
3234 config.enable_ice_renomination = false;
3235 CreatePeerConnection(config, nullptr);
3236 AddVoiceStream("foo");
3237
3238 std::unique_ptr<SessionDescriptionInterface> offer;
3239 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3240 cricket::SessionDescription* desc = offer->description();
3241 EXPECT_EQ(1u, desc->transport_infos().size());
3242 EXPECT_FALSE(
3243 desc->transport_infos()[0].description.GetIceParameters().renomination);
3244}
3245
3246// Test that the ICE renomination option is present in generated offers/answers
3247// if it's enabled in the PC's RTCConfiguration.
3248TEST_F(PeerConnectionInterfaceTest, IceRenominationOptionInOfferAndAnswer) {
3249 PeerConnectionInterface::RTCConfiguration config;
3250 config.enable_ice_renomination = true;
3251 CreatePeerConnection(config, nullptr);
3252 AddVoiceStream("foo");
3253
3254 std::unique_ptr<SessionDescriptionInterface> offer;
3255 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3256 cricket::SessionDescription* desc = offer->description();
3257 EXPECT_EQ(1u, desc->transport_infos().size());
3258 EXPECT_TRUE(
3259 desc->transport_infos()[0].description.GetIceParameters().renomination);
3260
3261 // Set the offer as a remote description, then create an answer and ensure it
3262 // has the renomination flag too.
3263 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3264 std::unique_ptr<SessionDescriptionInterface> answer;
3265 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3266 desc = answer->description();
3267 EXPECT_EQ(1u, desc->transport_infos().size());
3268 EXPECT_TRUE(
3269 desc->transport_infos()[0].description.GetIceParameters().renomination);
3270}
3271
3272// Test that if CreateOffer is called with the deprecated "offer to receive
3273// audio/video" constraints, they're processed and result in an offer with
3274// audio/video sections just as if RTCOfferAnswerOptions had been used.
3275TEST_F(PeerConnectionInterfaceTest, CreateOfferWithOfferToReceiveConstraints) {
3276 CreatePeerConnection();
3277
3278 FakeConstraints constraints;
3279 constraints.SetMandatoryReceiveAudio(true);
3280 constraints.SetMandatoryReceiveVideo(true);
3281 std::unique_ptr<SessionDescriptionInterface> offer;
3282 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3283
3284 cricket::SessionDescription* desc = offer->description();
3285 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3286 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3287 ASSERT_NE(nullptr, audio);
3288 ASSERT_NE(nullptr, video);
3289 EXPECT_FALSE(audio->rejected);
3290 EXPECT_FALSE(video->rejected);
3291}
3292
3293// Test that if CreateAnswer is called with the deprecated "offer to receive
3294// audio/video" constraints, they're processed and can be used to reject an
3295// offered m= section just as can be done with RTCOfferAnswerOptions;
3296TEST_F(PeerConnectionInterfaceTest, CreateAnswerWithOfferToReceiveConstraints) {
3297 CreatePeerConnection();
3298
3299 // First, create an offer with audio/video and apply it as a remote
3300 // description.
3301 FakeConstraints constraints;
3302 constraints.SetMandatoryReceiveAudio(true);
3303 constraints.SetMandatoryReceiveVideo(true);
3304 std::unique_ptr<SessionDescriptionInterface> offer;
3305 ASSERT_TRUE(DoCreateOffer(&offer, &constraints));
3306 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3307
3308 // Now create answer that rejects audio/video.
3309 constraints.SetMandatoryReceiveAudio(false);
3310 constraints.SetMandatoryReceiveVideo(false);
3311 std::unique_ptr<SessionDescriptionInterface> answer;
3312 ASSERT_TRUE(DoCreateAnswer(&answer, &constraints));
3313
3314 cricket::SessionDescription* desc = answer->description();
3315 const cricket::ContentInfo* audio = cricket::GetFirstAudioContent(desc);
3316 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
3317 ASSERT_NE(nullptr, audio);
3318 ASSERT_NE(nullptr, video);
3319 EXPECT_TRUE(audio->rejected);
3320 EXPECT_TRUE(video->rejected);
3321}
3322
3323#ifdef HAVE_SCTP
3324#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3325 DataChannelOnlyOfferWithMaxBundlePolicy
3326#else
3327#define MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy \
3328 DISABLED_DataChannelOnlyOfferWithMaxBundlePolicy
3329#endif
3330
3331// Test that negotiation can succeed with a data channel only, and with the max
3332// bundle policy. Previously there was a bug that prevented this.
3333TEST_F(PeerConnectionInterfaceTest,
3334 MAYBE_DataChannelOnlyOfferWithMaxBundlePolicy) {
3335 PeerConnectionInterface::RTCConfiguration config;
3336 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3337 CreatePeerConnection(config, nullptr);
3338
3339 // First, create an offer with only a data channel and apply it as a remote
3340 // description.
3341 pc_->CreateDataChannel("test", nullptr);
3342 std::unique_ptr<SessionDescriptionInterface> offer;
3343 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3344 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
3345
3346 // Create and set answer as well.
3347 std::unique_ptr<SessionDescriptionInterface> answer;
3348 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
3349 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
3350}
3351
zstein4b979802017-06-02 14:37:37 -07003352TEST_F(PeerConnectionInterfaceTest, SetBitrateWithoutMinSucceeds) {
3353 CreatePeerConnection();
3354 PeerConnectionInterface::BitrateParameters bitrate;
3355 bitrate.current_bitrate_bps = rtc::Optional<int>(100000);
3356 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3357}
3358
3359TEST_F(PeerConnectionInterfaceTest, SetBitrateNegativeMinFails) {
3360 CreatePeerConnection();
3361 PeerConnectionInterface::BitrateParameters bitrate;
3362 bitrate.min_bitrate_bps = rtc::Optional<int>(-1);
3363 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3364}
3365
3366TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanMinFails) {
3367 CreatePeerConnection();
3368 PeerConnectionInterface::BitrateParameters bitrate;
3369 bitrate.min_bitrate_bps = rtc::Optional<int>(5);
3370 bitrate.current_bitrate_bps = rtc::Optional<int>(3);
3371 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3372}
3373
3374TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentNegativeFails) {
3375 CreatePeerConnection();
3376 PeerConnectionInterface::BitrateParameters bitrate;
3377 bitrate.current_bitrate_bps = rtc::Optional<int>(-1);
3378 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3379}
3380
3381TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanCurrentFails) {
3382 CreatePeerConnection();
3383 PeerConnectionInterface::BitrateParameters bitrate;
3384 bitrate.current_bitrate_bps = rtc::Optional<int>(10);
3385 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3386 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3387}
3388
3389TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxLessThanMinFails) {
3390 CreatePeerConnection();
3391 PeerConnectionInterface::BitrateParameters bitrate;
3392 bitrate.min_bitrate_bps = rtc::Optional<int>(10);
3393 bitrate.max_bitrate_bps = rtc::Optional<int>(8);
3394 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3395}
3396
3397TEST_F(PeerConnectionInterfaceTest, SetBitrateMaxNegativeFails) {
3398 CreatePeerConnection();
3399 PeerConnectionInterface::BitrateParameters bitrate;
3400 bitrate.max_bitrate_bps = rtc::Optional<int>(-1);
3401 EXPECT_FALSE(pc_->SetBitrate(bitrate).ok());
3402}
3403
3404// The current bitrate from Call's BitrateConfigMask is currently clamped by
3405// Call's BitrateConfig, which comes from the SDP or a default value. This test
3406// checks that a call to SetBitrate with a current bitrate that will be clamped
3407// succeeds.
3408TEST_F(PeerConnectionInterfaceTest, SetBitrateCurrentLessThanImplicitMin) {
3409 CreatePeerConnection();
3410 PeerConnectionInterface::BitrateParameters bitrate;
3411 bitrate.current_bitrate_bps = rtc::Optional<int>(1);
3412 EXPECT_TRUE(pc_->SetBitrate(bitrate).ok());
3413}
3414
nisse51542be2016-02-12 02:27:06 -08003415class PeerConnectionMediaConfigTest : public testing::Test {
3416 protected:
3417 void SetUp() override {
zhihuang38ede132017-06-15 12:52:32 -07003418 pcf_ = PeerConnectionFactoryForTest::CreatePeerConnectionFactoryForTest();
nisse51542be2016-02-12 02:27:06 -08003419 pcf_->Initialize();
3420 }
nisseeaabdf62017-05-05 02:23:02 -07003421 const cricket::MediaConfig TestCreatePeerConnection(
nisse51542be2016-02-12 02:27:06 -08003422 const PeerConnectionInterface::RTCConfiguration& config,
3423 const MediaConstraintsInterface *constraints) {
nisse51542be2016-02-12 02:27:06 -08003424
zhihuang9763d562016-08-05 11:14:50 -07003425 rtc::scoped_refptr<PeerConnectionInterface> pc(pcf_->CreatePeerConnection(
3426 config, constraints, nullptr, nullptr, &observer_));
nisse51542be2016-02-12 02:27:06 -08003427 EXPECT_TRUE(pc.get());
nisseeaabdf62017-05-05 02:23:02 -07003428 return pc->GetConfiguration().media_config;
nisse51542be2016-02-12 02:27:06 -08003429 }
3430
zhihuang9763d562016-08-05 11:14:50 -07003431 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
nisse51542be2016-02-12 02:27:06 -08003432 MockPeerConnectionObserver observer_;
3433};
3434
3435// This test verifies the default behaviour with no constraints and a
3436// default RTCConfiguration.
3437TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3438 PeerConnectionInterface::RTCConfiguration config;
3439 FakeConstraints constraints;
3440
3441 const cricket::MediaConfig& media_config =
3442 TestCreatePeerConnection(config, &constraints);
3443
3444 EXPECT_FALSE(media_config.enable_dscp);
nisse0db023a2016-03-01 04:29:59 -08003445 EXPECT_TRUE(media_config.video.enable_cpu_overuse_detection);
3446 EXPECT_FALSE(media_config.video.disable_prerenderer_smoothing);
3447 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003448}
3449
3450// This test verifies the DSCP constraint is recognized and passed to
nisse528b7932017-05-08 03:21:43 -07003451// the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003452TEST_F(PeerConnectionMediaConfigTest, TestDscpConstraintTrue) {
3453 PeerConnectionInterface::RTCConfiguration config;
3454 FakeConstraints constraints;
3455
3456 constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDscp, true);
3457 const cricket::MediaConfig& media_config =
3458 TestCreatePeerConnection(config, &constraints);
3459
3460 EXPECT_TRUE(media_config.enable_dscp);
3461}
3462
3463// This test verifies the cpu overuse detection constraint is
nisse528b7932017-05-08 03:21:43 -07003464// recognized and passed to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003465TEST_F(PeerConnectionMediaConfigTest, TestCpuOveruseConstraintFalse) {
3466 PeerConnectionInterface::RTCConfiguration config;
3467 FakeConstraints constraints;
3468
3469 constraints.AddOptional(
3470 webrtc::MediaConstraintsInterface::kCpuOveruseDetection, false);
3471 const cricket::MediaConfig media_config =
3472 TestCreatePeerConnection(config, &constraints);
3473
nisse0db023a2016-03-01 04:29:59 -08003474 EXPECT_FALSE(media_config.video.enable_cpu_overuse_detection);
nisse51542be2016-02-12 02:27:06 -08003475}
3476
3477// This test verifies that the disable_prerenderer_smoothing flag is
nisse528b7932017-05-08 03:21:43 -07003478// propagated from RTCConfiguration to the PeerConnection.
nisse51542be2016-02-12 02:27:06 -08003479TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3480 PeerConnectionInterface::RTCConfiguration config;
3481 FakeConstraints constraints;
3482
Niels Möller71bdda02016-03-31 12:59:59 +02003483 config.set_prerenderer_smoothing(false);
nisse51542be2016-02-12 02:27:06 -08003484 const cricket::MediaConfig& media_config =
3485 TestCreatePeerConnection(config, &constraints);
3486
nisse0db023a2016-03-01 04:29:59 -08003487 EXPECT_TRUE(media_config.video.disable_prerenderer_smoothing);
3488}
3489
3490// This test verifies the suspend below min bitrate constraint is
nisse528b7932017-05-08 03:21:43 -07003491// recognized and passed to the PeerConnection.
nisse0db023a2016-03-01 04:29:59 -08003492TEST_F(PeerConnectionMediaConfigTest,
3493 TestSuspendBelowMinBitrateConstraintTrue) {
3494 PeerConnectionInterface::RTCConfiguration config;
3495 FakeConstraints constraints;
3496
3497 constraints.AddOptional(
3498 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3499 true);
3500 const cricket::MediaConfig media_config =
3501 TestCreatePeerConnection(config, &constraints);
3502
3503 EXPECT_TRUE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003504}
3505
deadbeefab9b2d12015-10-14 11:33:11 -07003506// The following tests verify that session options are created correctly.
deadbeefc80741f2015-10-22 13:14:45 -07003507// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of
3508// "verify options are converted correctly", should be "pass options into
3509// CreateOffer and verify the correct offer is produced."
deadbeefab9b2d12015-10-14 11:33:11 -07003510
3511TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) {
3512 RTCOfferAnswerOptions rtc_options;
3513 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3514
3515 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003516 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003517
3518 rtc_options.offer_to_receive_audio =
3519 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003520 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003521}
3522
3523TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) {
3524 RTCOfferAnswerOptions rtc_options;
3525 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3526
3527 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003528 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003529
3530 rtc_options.offer_to_receive_video =
3531 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003532 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003533}
3534
3535// Test that a MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003536// OfferToReceiveAudio and OfferToReceiveVideo options are set.
deadbeefab9b2d12015-10-14 11:33:11 -07003537TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) {
3538 RTCOfferAnswerOptions rtc_options;
3539 rtc_options.offer_to_receive_audio = 1;
3540 rtc_options.offer_to_receive_video = 1;
3541
3542 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003543 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003544 EXPECT_TRUE(options.has_audio());
3545 EXPECT_TRUE(options.has_video());
3546 EXPECT_TRUE(options.bundle_enabled);
3547}
3548
3549// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003550// OfferToReceiveAudio is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003551TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) {
3552 RTCOfferAnswerOptions rtc_options;
3553 rtc_options.offer_to_receive_audio = 1;
3554
3555 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003556 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003557 EXPECT_TRUE(options.has_audio());
3558 EXPECT_FALSE(options.has_video());
3559 EXPECT_TRUE(options.bundle_enabled);
3560}
3561
3562// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003563// the default OfferOptions are used.
deadbeefab9b2d12015-10-14 11:33:11 -07003564TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) {
3565 RTCOfferAnswerOptions rtc_options;
3566
3567 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003568 options.transport_options["audio"] = cricket::TransportOptions();
3569 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003570 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefc80741f2015-10-22 13:14:45 -07003571 EXPECT_TRUE(options.has_audio());
deadbeefab9b2d12015-10-14 11:33:11 -07003572 EXPECT_FALSE(options.has_video());
deadbeefc80741f2015-10-22 13:14:45 -07003573 EXPECT_TRUE(options.bundle_enabled);
deadbeefab9b2d12015-10-14 11:33:11 -07003574 EXPECT_TRUE(options.vad_enabled);
deadbeef0ed85b22016-02-23 17:24:52 -08003575 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3576 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003577}
3578
3579// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003580// OfferToReceiveVideo is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003581TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) {
3582 RTCOfferAnswerOptions rtc_options;
3583 rtc_options.offer_to_receive_audio = 0;
3584 rtc_options.offer_to_receive_video = 1;
3585
3586 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003587 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003588 EXPECT_FALSE(options.has_audio());
3589 EXPECT_TRUE(options.has_video());
3590 EXPECT_TRUE(options.bundle_enabled);
3591}
3592
3593// Test that a correct MediaSessionOptions is created for an offer if
3594// UseRtpMux is set to false.
3595TEST(CreateSessionOptionsTest,
3596 GetMediaSessionOptionsForOfferWithBundleDisabled) {
3597 RTCOfferAnswerOptions rtc_options;
3598 rtc_options.offer_to_receive_audio = 1;
3599 rtc_options.offer_to_receive_video = 1;
3600 rtc_options.use_rtp_mux = false;
3601
3602 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003603 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003604 EXPECT_TRUE(options.has_audio());
3605 EXPECT_TRUE(options.has_video());
3606 EXPECT_FALSE(options.bundle_enabled);
3607}
3608
3609// Test that a correct MediaSessionOptions is created to restart ice if
3610// IceRestart is set. It also tests that subsequent MediaSessionOptions don't
Taylor Brandstetterf475d362016-01-08 15:35:57 -08003611// have |audio_transport_options.ice_restart| etc. set.
deadbeefab9b2d12015-10-14 11:33:11 -07003612TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) {
3613 RTCOfferAnswerOptions rtc_options;
3614 rtc_options.ice_restart = true;
3615
3616 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003617 options.transport_options["audio"] = cricket::TransportOptions();
3618 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003619 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003620 EXPECT_TRUE(options.transport_options["audio"].ice_restart);
3621 EXPECT_TRUE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003622
3623 rtc_options = RTCOfferAnswerOptions();
htaaac2dea2016-03-10 13:35:55 -08003624 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003625 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3626 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003627}
3628
3629// Test that the MediaConstraints in an answer don't affect if audio and video
3630// is offered in an offer but that if kOfferToReceiveAudio or
3631// kOfferToReceiveVideo constraints are true in an offer, the media type will be
3632// included in subsequent answers.
3633TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) {
3634 FakeConstraints answer_c;
3635 answer_c.SetMandatoryReceiveAudio(true);
3636 answer_c.SetMandatoryReceiveVideo(true);
3637
3638 cricket::MediaSessionOptions answer_options;
3639 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options));
3640 EXPECT_TRUE(answer_options.has_audio());
3641 EXPECT_TRUE(answer_options.has_video());
3642
deadbeefc80741f2015-10-22 13:14:45 -07003643 RTCOfferAnswerOptions rtc_offer_options;
deadbeefab9b2d12015-10-14 11:33:11 -07003644
3645 cricket::MediaSessionOptions offer_options;
htaaac2dea2016-03-10 13:35:55 -08003646 EXPECT_TRUE(
3647 ExtractMediaSessionOptions(rtc_offer_options, false, &offer_options));
deadbeefc80741f2015-10-22 13:14:45 -07003648 EXPECT_TRUE(offer_options.has_audio());
htaaac2dea2016-03-10 13:35:55 -08003649 EXPECT_TRUE(offer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003650
deadbeefc80741f2015-10-22 13:14:45 -07003651 RTCOfferAnswerOptions updated_rtc_offer_options;
3652 updated_rtc_offer_options.offer_to_receive_audio = 1;
3653 updated_rtc_offer_options.offer_to_receive_video = 1;
deadbeefab9b2d12015-10-14 11:33:11 -07003654
3655 cricket::MediaSessionOptions updated_offer_options;
htaaac2dea2016-03-10 13:35:55 -08003656 EXPECT_TRUE(ExtractMediaSessionOptions(updated_rtc_offer_options, false,
htaa2a49d92016-03-04 02:51:39 -08003657 &updated_offer_options));
deadbeefab9b2d12015-10-14 11:33:11 -07003658 EXPECT_TRUE(updated_offer_options.has_audio());
3659 EXPECT_TRUE(updated_offer_options.has_video());
3660
3661 // Since an offer has been created with both audio and video, subsequent
3662 // offers and answers should contain both audio and video.
3663 // Answers will only contain the media types that exist in the offer
3664 // regardless of the value of |updated_answer_options.has_audio| and
3665 // |updated_answer_options.has_video|.
3666 FakeConstraints updated_answer_c;
3667 answer_c.SetMandatoryReceiveAudio(false);
3668 answer_c.SetMandatoryReceiveVideo(false);
3669
3670 cricket::MediaSessionOptions updated_answer_options;
3671 EXPECT_TRUE(
3672 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options));
3673 EXPECT_TRUE(updated_answer_options.has_audio());
3674 EXPECT_TRUE(updated_answer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003675}
deadbeef3edec7c2016-12-10 11:44:26 -08003676
deadbeef293e9262017-01-11 12:28:30 -08003677// Tests a few random fields being different.
3678TEST(RTCConfigurationTest, ComparisonOperators) {
3679 PeerConnectionInterface::RTCConfiguration a;
3680 PeerConnectionInterface::RTCConfiguration b;
3681 EXPECT_EQ(a, b);
3682
3683 PeerConnectionInterface::RTCConfiguration c;
3684 c.servers.push_back(PeerConnectionInterface::IceServer());
3685 EXPECT_NE(a, c);
3686
3687 PeerConnectionInterface::RTCConfiguration d;
3688 d.type = PeerConnectionInterface::kRelay;
3689 EXPECT_NE(a, d);
3690
3691 PeerConnectionInterface::RTCConfiguration e;
3692 e.audio_jitter_buffer_max_packets = 5;
3693 EXPECT_NE(a, e);
3694
3695 PeerConnectionInterface::RTCConfiguration f;
3696 f.ice_connection_receiving_timeout = 1337;
3697 EXPECT_NE(a, f);
3698
3699 PeerConnectionInterface::RTCConfiguration g;
3700 g.disable_ipv6 = true;
3701 EXPECT_NE(a, g);
3702
3703 PeerConnectionInterface::RTCConfiguration h(
3704 PeerConnectionInterface::RTCConfigurationType::kAggressive);
3705 EXPECT_NE(a, h);
3706}